【问题标题】:Android: how to configure sizing of a custom layoutAndroid:如何配置自定义布局的大小
【发布时间】:2017-08-30 05:38:31
【问题描述】:

我一直在尝试创建一个自定义水平布局,目标是在 ImageView 的左侧有一个 TextView,其中包含一个描述特定状态的图标。 ImageView 保持一个正方形的尺寸,它的高度和宽度等于 TextView 中文本的高度。但是,问题仍然存在,例如未按照布局 xml 文件中的指定设置文本高度以及 ImageView 后存在未知的填充。这些问题可以在this image 中看到,红色表示未知填充,蓝色表示文本大小不一致,两者都设置为 12sp。需要修复字体大小和填充问题,以便可以将布局正确添加到网格布局中,该网格布局将包含这些自定义布局的网格。

StatusIcon.java

//This is part of the java class that extends ImageView to resize the Icon
@Override
protected void onMeasure(int width, int height) {
    super.onMeasure(width, height);

    int measuredHeight = getMeasuredHeight();
    setMeasuredDimension(measuredHeight, measuredHeight);
}

StatusIndicator.java

//This is the java class for the custom layout.
public class StatusIndicator extends LinearLayout {

    private TextView label;
    private StatusIcon statusLed;
    private CharSequence labelText;
    private float labelTextSize;

    public enum Status {
        GOOD,
        WARNING,
        CRITICAL
    }

    /*
     * Removed the basic required class constructors to save space.
     */

    private void getAttributes(Context context, AttributeSet attrs){
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StatusIndicator);
        labelText = typedArray.getString(R.styleable.StatusIndicator_label);
        labelTextSize = typedArray.getDimensionPixelSize(R.styleable.StatusIndicator_labelSize, 0);
        typedArray.recycle();
    }

    private void initializeViews(Context context){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.view_status_indicator, this);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        //Setup UI elements in layout
        label = (TextView) findViewById(R.id.textView_statusIndicatorLabel);
        statusLed = (StatusIcon) findViewById(R.id.imageView_statusIndicatorLed);
        label.setText(labelText);

        if(labelTextSize > 0){
            label.setTextSize(TypedValue.COMPLEX_UNIT_SP, labelTextSize);
        }
    }

    public void setStatus(StatusIndicator.Status status){
        switch (status){
            case GOOD:
                statusLed.setImageResource(R.mipmap.ic_status_panel_good);
                break;
            case WARNING:
                statusLed.setImageResource(R.mipmap.ic_status_panel_warning);
                break;
            case CRITICAL:
                statusLed.setImageResource(R.mipmap.ic_status_panel_critical);
                break;
        }
    }
}

view_status_indicator.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:parentTag="LinearLayout"
    tools:orientation="horizontal">

    <TextView
        android:id="@+id/textView_statusIndicatorLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_vertical|start"
        android:layout_marginEnd="2dp"
        android:text="@string/default_title"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:textSize="12sp"/>

    <com.css_design.android_quickbridge.ui.home.status_panel.StatusIcon
        android:id="@+id/imageView_statusIndicatorLed"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:gravity="center_vertical|end"

        app:srcCompat="@mipmap/ic_status_panel_critical"/>
    </merge>

【问题讨论】:

  • 如果它们可以为您提供相同的行为,您是否愿意使用 android 标准组件,或者您是否需要创建自己的自定义视图?
  • @BenP。我愿意使用标准组件。我刚接触 Android 并试图弄清楚。主要问题是一个网格中有 16 个这些状态指示器,一个活动中有 2 个网格,所以我想尽可能多地进行本地化。

标签: android android-layout


【解决方案1】:

我会通过使用ConstraintLayout 而不是创建自定义视图实现来解决这个问题。

ConstraintLayout 允许您为其子项指定纵横比,这可以确保您的ImageView 始终完全是正方形的。 ConstraintLayout 还允许您根据同级视图指定高度或宽度(通过将0dp 的维度与topbottom(或leftright)约束相结合)。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#ccf">

    <ImageView
        android:id="@+id/image"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:src="@drawable/circle"
        app:layout_constraintTop_toTopOf="@+id/text"
        app:layout_constraintLeft_toRightOf="@+id/text"
        app:layout_constraintBottom_toBottomOf="@+id/text"
        app:layout_constraintDimensionRatio="1"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40sp"
        android:text="hello world"/>

</android.support.constraint.ConstraintLayout>

(背景颜色添加到ConstraintLayout 以表明它不大于其内容)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    相关资源
    最近更新 更多