I’ll describe my solution on how to resize a view under a SlidingDrawer. When the drawer is collapsed, the view (a map in my app) scales to take the additional place.
I ended up having two layers (two LinearLayouts in a FrameView), each containing its actual contents and a dummy padding view.
<FrameLayout android:id="@+id/det_frame" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <fragment android:id="@+id/det_map" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" /> <View android:id="@+id/det_map_padding" android:layout_width="match_parent" android:layout_height="0dp" /> </LinearLayout> <LinearLayout android:id="@+id/det_drawer_layer" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <View android:id="@+id/det_drawer_padding" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <SlidingDrawer android:id="@+id/drawer" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:allowSingleTap="true" android:content="@+id/details_tab_content" android:handle="@+id/drawer_handle" > <ImageView android:id="@+id/drawer_handle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/handle_top" /> <LinearLayout android:id="@+id/details_tab_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:orientation="vertical" > <!-- drawer contents--> </LinearLayout> </SlidingDrawer> </LinearLayout> </FrameLayout>
During runtime, two important things are done. First, the map padding size is adjusted so that it matches the drawer size in the other layer. Then, the padding visibility is changed when the drawer is expanded or collapsed. It would be best to animate the content resizing in sync with the drawer – I will look into it.
import android.app.Fragment; import android.os.Bundle; import android.os.Handler; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.LinearLayout; import android.widget.SlidingDrawer; import android.widget.SlidingDrawer.OnDrawerCloseListener; import android.widget.SlidingDrawer.OnDrawerOpenListener; @SuppressWarnings("deprecation") public class MyFragment extends Fragment { private int mDrawerOrientation; private View mTabContentView; private View mMapPaddingView; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment final View v = inflater.inflate(R.layout.my_layout, container, false); LinearLayout layout = (LinearLayout) (v.findViewById(R.id.det_drawer_layer)); mDrawerOrientation = layout.getOrientation(); mTabContentView = v.findViewById(R.id.details_tab_content); mMapPaddingView = v.findViewById(R.id.det_map_padding); final SlidingDrawer slidingDrawer = (SlidingDrawer) v.findViewById(R.id.drawer); slidingDrawer.setOnDrawerOpenListener(new OnDrawerOpenListener() { @Override public void onDrawerOpened() { v.findViewById(R.id.det_map_padding).setVisibility(View.VISIBLE); } }); slidingDrawer.setOnDrawerCloseListener(new OnDrawerCloseListener() { @Override public void onDrawerClosed() { v.findViewById(R.id.det_map_padding).setVisibility(View.GONE); } }); // TODO: this smells. Should open the drawer when the view is laid out new Handler().postDelayed(new Runnable() { @Override public void run() { slidingDrawer.open(); } }, 100); mTabContentView.addOnLayoutChangeListener(new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { LayoutParams layoutParams = mMapPaddingView.getLayoutParams(); if (mDrawerOrientation == LinearLayout.HORIZONTAL) { int width = right - left; if (width > 0 && layoutParams.width != width) { layoutParams.width = width; mMapPaddingView.setLayoutParams(layoutParams); } } else { int height = bottom - top; if (height > 0 && layoutParams.height != height) { layoutParams.height = height; mMapPaddingView.setLayoutParams(layoutParams); } } } }); return v; } }