简体   繁体   中英

child views losing layout_margin

I'm adding a LinearLayout as a child of a custom layout. The LinearLayout has margins, but the margins never get into the LayoutParams.

Here's the xml for the LinearLayout

<com.perinote.widgets.LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:orientation="vertical"
  android:layout_marginLeft="@dimen/popup_margin_LR"
  android:layout_marginRight="@dimen/popup_margin_LR"
  android:layout_marginTop="@dimen/popup_margin_TB"
  android:layout_marginBottom="@dimen/popup_margin_TB"
  >

Here's the code that inflates and adds the LinearLayout to the custom layout, where "this" is the custom layout, which is an extension of ViewGroup :

  public View setContentView (int layoutId)
  {
    LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
    ViewGroup v = (ViewGroup) inflater.inflate (layoutId, this, false);
    contentView = v;

    ViewGroup.LayoutParams params = v.getLayoutParams ();
    this.addView (contentView, params);

    return contentView;
  }

And, finally, here's a piece of onMeasure in the custom layout.

  @Override
  protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
  {
    ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) contentView.getLayoutParams();

    int contentWidth = MeasureSpec.getSize (widthMeasureSpec);
    int contentHeight = MeasureSpec.getSize (heightMeasureSpec);

    ... some other stuff ...

    // measure contentView.
    int contentWidthSpec = MeasureSpec.makeMeasureSpec (contentWidth, MeasureSpec.AT_MOST);
    int contentHeightSpec = MeasureSpec.makeMeasureSpec (contentHeight, MeasureSpec.AT_MOST);
    contentView.measure (contentWidthSpec, contentHeightSpec);

    setMeasuredDimension (MeasureSpec.getSize (widthMeasureSpec), MeasureSpec.getSize (heightMeasureSpec));
  }

The app crashes on the first line of onMeasure() -- params = . The error is:

java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.view.ViewGroup$MarginLayoutParams

which indicates that, during inflation, the inflator created LayoutParams instead of MarginLayoutParams.

What can I do to get MarginLayoutParms or some other variant that includes the layout_margin values?

The class extending ViewGroup must also override generateLayoutParams() . In my case:

@Override
public LayoutParams generateLayoutParams (AttributeSet attrs)
{
  return new ViewGroup.MarginLayoutParams (getContext(), attrs);
}

but you can extend LayoutParams to contain whatever you need instead of using MarginLayoutParams . During inflation of a child view, generateLayoutParams() gets called. This (aha) is why inflate needs to know the parent view group, even if you aren't adding the new child to the parent at this time.

Credit really goes to @Mike M. Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM