Android: get parent layout width in custom view to

2019-08-16 00:57发布

问题:

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"/>

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);
    }

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?

回答1:

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

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);

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.

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.

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);

}

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.

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