【问题标题】:Android: get parent layout width in custom view to set child widthAndroid:在自定义视图中获取父布局宽度以设置子宽度
【发布时间】:2019-08-05 05:31:30
【问题描述】:

我已经创建了一个名为 ProgressButton 的类,它扩展了 RelativeLayout。现在我在主 xml 中添加了这个类:

<com.tazik.progressbutton.ProgressButton
    android:id="@+id/pb_button"
    android:layout_width="200dp"
    android:layout_height="wrap_content"/>

如您所见,我添加了android:layout_width="200dp",现在在 ProgressButton 类中,我想获得这个大小来创建一个具有这个大小的按钮:

public class ProgressButton extends RelativeLayout {

    private AppCompatButton button;

    public ProgressButton(Context context) {
        super(context);
        initView();
    }
    private void initView() {

        initButton();
    }

    private void initButton() {
        button = new AppCompatButton(getContext());
        LayoutParams button_params = new LayoutParams(????, ViewGroup.LayoutParams.WRAP_CONTENT);
        button_params.addRule(RelativeLayout.CENTER_IN_PARENT,RelativeLayout.TRUE);
        button.setLayoutParams(button_params);
        button.setText("click");
        addView(button);
    }

我想根据 relativeLayout 的大小创建按钮,那么如何在我的自定义视图中获取 layout_width 来设置button_params width

【问题讨论】:

  • 使用MATCH_PARENT 作为宽度参数还不够吗?
  • 我没有使用MATCH_PARENT !!老兄@MikeM。
  • 我不确定你的意思。我只是问为什么在LayoutParams 构造函数调用中使用ViewGroup.LayoutParams.MATCH_PARENT 作为第一个参数不符合您的要求。
  • 你试过改变尺寸的方法吗?

标签: android android-custom-view


【解决方案1】:

现在在 ProgressButton 类中,我想获得这个大小来创建一个具有这个大小的按钮

作为@MikeM。在评论中建议。它可以像给子视图宽度为MATCH_PARENT 一样简单。见下文...

LayoutParams button_params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

有了它,您就不必担心实际大小,因为MATCH_PARENT 将拉伸您的子视图以占据整个父视图的宽度...显然要考虑边距和填充。

但是,如果您确实需要知道父项的宽度,则应在 onMeasure 中查询。我强烈建议您尽可能远离onMeasure,因为它有点复杂,并且可能会占用您大量的开发时间。

无论哪种方式,在onMeasure 中,您都可以知道父视图想要对其子视图进行哪些测量,这是基于父视图内部可用于渲染的空间和指定的布局参数...

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int childWidth = 0;

    if(widthSpecMode == MeasureSpec.AT_MOST){
        //The parent doesn't want the child to exceed "childWidth", it doesn't care if it smaller than that, just not bigger/wider
        childWidth = MeasureSpec.getSize(widthMeasureSpec);
    }
    else if(widthSpecMode == MeasureSpec.EXACTLY){
        //The parent wants the child to be exactly "childWidth"
        childWidth = MeasureSpec.getSize(widthMeasureSpec);
    }
    else {
        //The parent doesn't know yet what its children's width will be, probably
        //because it's still taking measurements
    }

    //IMPORTANT!!! set your desired measurements (width and height) or call the base class's onMeasure method. Do one or the other, NOT BOTH
    setMeasuredDimension(dimens, dimens);
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

onMeasure 中添加几个Log.d 调用,以便更好地了解正在发生的事情。请注意,此方法将被多次调用。

同样,这对于您的案例场景来说是不必要的矫枉过正。将MATCH_PARENT 设置为按钮应该会产生您想要的结果

【讨论】:

  • 是的,@MikeM 是对的。感谢 MikeM 和您以及其他朋友。
  • 老兄,我怎样才能在我的自定义视图中以编程方式获得 ViewGroup.LayoutParams.MATCH_PARENT 大小?@Leo