Android:在自定义视图中获取父级布局宽度以设置子级宽度

问题描述:

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

I have made class called ProgressButton that extended RelativeLayout.Now in main xml i added this class:

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

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

As you can see i added android:layout_width="200dp", now in ProgressButton class i want to get this size to create a button with this size:

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?

I want to create button exactly to size of relativeLayout, so how can i get layout_width in my custom view to set button_params width?

现在在ProgressButton类中,我想获得此大小以创建具有此大小的按钮

now in ProgressButton class i want to get this size to create a button with this size

@MikeM.在评论中建议.就像给子视图宽度MATCH_PARENT一样简单.见下文...

As @MikeM. suggested in a comment. It could be as easy as giving that child view a width of MATCH_PARENT. See below...

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

有了这个选项,您就不必担心实际的大小,因为MATCH_PARENT将使您的孩子的视线伸展到占据整个父对象的宽度...明显地忽略了边距和填充.

With that in place you don't need to worry about the actual size because MATCH_PARENT will stretch your child view to occupy the whole parent's width...obviosuly respecting margins and paddings.

但是,如果您确实需要知道父母的宽度,则应该在onMeasure中进行查询.我强烈建议您尽可能避免使用onMeasure,因为它有点复杂,并且可能会花费很多开发时间.

However, if you do need to know the parent's width, you should query that in onMeasure. I strongly suggest you to stay away from onMeasure whenever possible because it is a bit complex and it might take a lot of your development time.

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

Either way, in onMeasure you can know what measurements the parent view wants to give to its child views, this is based on the space available to render inside the parent and the layout params specified...

@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调用,以更好地了解正在发生的事情.请注意,此方法将被多次调用.

Add a few Log.d calls inside onMeasure for a better understanding of what's happening. Be aware that this method will be called multiple times.

同样,对于您的情况而言,这是不必要的过大杀伤力.将MATCH_PARENT设置为按钮应该会产生所需的结果

Again, this is an unnecessary overkill for your case scenario. Setting MATCH_PARENT to the button should produce the results you want