There is an activity in which I use the custom FullDrawerLayout with Gravity=start , inside this activity there is a ViewPager within which fragments, and here in one of these fragments I want to add NavigationDrawer with Gravity=end and use already android.support.v4.widget.DrawerLayout and here I want to change the width, I do it like this:

  drawerRecycler = (RecyclerView) rootView.findViewById(R.id.recyclerView); RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity()); drawerRecycler.setLayoutManager(mLayoutManager); drawerRecycler.setItemAnimator(new DefaultItemAnimator()); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) drawerLayout.getLayoutParams(); params.width = 100; drawerLayout.setLayoutParams(params); 

but it falls with this error:

java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.

but this error leads to NavigationDrawer which, in activation, I can’t understand what it’s about. Here is the code NavigationDrawer that I use in activit:

 public class FullDrawerLayout extends DrawerLayout { private static final int MIN_DRAWER_MARGIN = 0; // dp public FullDrawerLayout(Context context) { super(context); } public FullDrawerLayout(Context context, AttributeSet attrs) { super(context, attrs); } public FullDrawerLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int widthMode = MeasureSpec.getMode(widthMeasureSpec); final int heightMode = MeasureSpec.getMode(heightMeasureSpec); final int widthSize = MeasureSpec.getSize(widthMeasureSpec); final int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.EXACTLY) { throw new IllegalArgumentException( "DrawerLayout must be measured with MeasureSpec.EXACTLY."); } setMeasuredDimension(widthSize, heightSize); // Gravity value for each drawer we've seen. Only one of each permitted. int foundDrawers = 0; final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (child.getVisibility() == GONE) { continue; } final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (isContentView(child)) { // Content views get measured at exactly the layout's size. final int contentWidthSpec = MeasureSpec.makeMeasureSpec( widthSize - lp.leftMargin - lp.rightMargin, MeasureSpec.EXACTLY); final int contentHeightSpec = MeasureSpec.makeMeasureSpec( heightSize - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY); child.measure(contentWidthSpec, contentHeightSpec); } else if (isDrawerView(child)) { final int childGravity = getDrawerViewGravity(child) & Gravity.HORIZONTAL_GRAVITY_MASK; if ((foundDrawers & childGravity) != 0) { throw new IllegalStateException("Child drawer has absolute gravity " + gravityToString(childGravity) + " but this already has a " + "drawer view along that edge"); } final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec, MIN_DRAWER_MARGIN + lp.leftMargin + lp.rightMargin, lp.width); final int drawerHeightSpec = getChildMeasureSpec(heightMeasureSpec, lp.topMargin + lp.bottomMargin, lp.height); child.measure(drawerWidthSpec, drawerHeightSpec); } else { throw new IllegalStateException("Child " + child + " at index " + i + " does not have a valid layout_gravity - must be Gravity.LEFT, " + "Gravity.RIGHT or Gravity.NO_GRAVITY"); } } } boolean isContentView(View child) { return ((DrawerLayout.LayoutParams) child.getLayoutParams()).gravity == Gravity.NO_GRAVITY; } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) boolean isDrawerView(View child) { final int gravity = ((DrawerLayout.LayoutParams) child.getLayoutParams()).gravity; final int absGravity = Gravity.getAbsoluteGravity(gravity, child.getLayoutDirection()); return (absGravity & (Gravity.LEFT | Gravity.RIGHT)) != 0; } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) int getDrawerViewGravity(View drawerView) { final int gravity = ((DrawerLayout.LayoutParams) drawerView.getLayoutParams()).gravity; return Gravity.getAbsoluteGravity(gravity, drawerView.getLayoutDirection()); } static String gravityToString(int gravity) { if ((gravity & Gravity.LEFT) == Gravity.LEFT) { return "LEFT"; } if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) { return "RIGHT"; } return Integer.toHexString(gravity); } } 

Here falls in the line

 сhild.measure(contentWidthSpec, contentHeightSpec); 

    1 answer 1

    Solved the problem, made it through the layout, simply setting the width for RecyclerView and set it to bind to the right edge of the parent:

     <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- CONTENT --> <RelativeLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> <!-- MENU LIST --> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="end" > <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="250dp" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_height="match_parent" android:choiceMode="singleChoice" android:divider="@android:color/transparent" android:dividerHeight="0dp" android:background="@color/white"/> </RelativeLayout> </android.support.v4.widget.DrawerLayout> </LinearLayout>