Using ScrollView in Navigation Drawer
-
21-12-2019 - |
Question
I have one ListView and two ImageButtons in my Nav Drawer. My problem is, if my Listview expands beyond screen, it scrolls to show all the listview items only, not the two imagebuttons below.
To solve this, I tried adding ScrollView to wrap the LinearLayout (@+id/drawer), but it gives me below error.
Is it possible to have a NavDrawer with extra items (other than listview) and have an overall scroller?
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ScrollView
android:layout_width="240dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/texturebg2"
android:layout_gravity="start">
<LinearLayout
android:id="@+id/drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/texturebg2"
android:layout_gravity="start">
<ListView
android:id="@+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@color/col3"
android:dividerHeight="1dp"
android:listSelector="@drawable/menu_selector" />
<LinearLayout
android:id="@+id/extrabuttons"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center_horizontal|bottom"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp" >
<ImageButton
android:id="@+id/credit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription = "@string/credit"
android:onClick="openCredit"
android:src="@drawable/information"
android:background="@drawable/mybutton2"
android:padding="8dip"
android:text="@string/credit" />
<ImageButton
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription = "@string/exit"
android:onClick="closeApp"
android:src="@drawable/ic_exit"
android:background="@drawable/mybutton2"
android:padding="8dip"
android:layout_marginLeft="10dp"
android:text="@string/exit" />
</LinearLayout>
</LinearLayout>
</ScrollView>
LogCat
01-09 14:04:02.446: E/AndroidRuntime(1072): FATAL EXCEPTION: main
01-09 14:04:02.446: E/AndroidRuntime(1072): Process: com.migrationdesk.mylibman, PID: 1072
01-09 14:04:02.446: E/AndroidRuntime(1072): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.migrationdesk.mylibman/com.migrationdesk.mylibman.NavContainer}: java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.support.v4.widget.DrawerLayout$LayoutParams
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2176)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2226)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.ActivityThread.access$700(ActivityThread.java:135)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1397)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.os.Handler.dispatchMessage(Handler.java:102)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.os.Looper.loop(Looper.java:137)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.ActivityThread.main(ActivityThread.java:4998)
01-09 14:04:02.446: E/AndroidRuntime(1072): at java.lang.reflect.Method.invokeNative(Native Method)
01-09 14:04:02.446: E/AndroidRuntime(1072): at java.lang.reflect.Method.invoke(Method.java:515)
01-09 14:04:02.446: E/AndroidRuntime(1072): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
01-09 14:04:02.446: E/AndroidRuntime(1072): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
01-09 14:04:02.446: E/AndroidRuntime(1072): at dalvik.system.NativeStart.main(Native Method)
01-09 14:04:02.446: E/AndroidRuntime(1072): Caused by: java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.support.v4.widget.DrawerLayout$LayoutParams
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.support.v4.widget.DrawerLayout.isDrawerView(DrawerLayout.java:857)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.support.v4.widget.DrawerLayout.closeDrawer(DrawerLayout.java:1058)
01-09 14:04:02.446: E/AndroidRuntime(1072): at com.migrationdesk.mylibman.NavContainer.displayView(NavContainer.java:202)
01-09 14:04:02.446: E/AndroidRuntime(1072): at com.migrationdesk.mylibman.NavContainer.onCreate(NavContainer.java:116)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.Activity.performCreate(Activity.java:5243)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-09 14:04:02.446: E/AndroidRuntime(1072): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2140)
01-09 14:04:02.446: E/AndroidRuntime(1072): ... 11 more
Solution
<LinearLayout
android:id="@+id/extrabuttons"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:gravity="center_horizontal|bottom"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp" >
<ImageButton
android:id="@+id/credit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription = "@string/credit"
android:onClick="openCredit"
android:src="@drawable/information"
android:background="@drawable/mybutton2"
android:padding="8dip"
android:text="@string/credit" />
<ImageButton
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription = "@string/exit"
android:onClick="closeApp"
android:src="@drawable/ic_exit"
android:background="@drawable/mybutton2"
android:padding="8dip"
android:layout_marginLeft="10dp"
android:text="@string/exit" />
</LinearLayout>
Put above layout inside different xml file and call it footer.xml
now in java code where you set the adapter:
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.footer, null, true);
listView.addFooterView(View);
And just keep ListView in drawer like:
<ListView
android:id="@+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@color/col3"
android:dividerHeight="1dp"
android:listSelector="@drawable/menu_selector" />
And now your list view will scroll to this view.
OTHER TIPS
This seems pretty familiar to me as I faced the same problem a short time ago. Firstly, wrapping a ListView
into a ScrollView
is generally not a good idea (and probably, if you use the Android SDK integrated version of Eclipse, you received a warning), because ListView
has an scroller itself.
Secondly, the problem is that due to your layout definition, the ListView
is expanding to the bottom of your screen, which makes your two images unreachable.
I solved this issue wrapping the content I wanted to show within a LinearLayout
with vertical
orientation, something like this:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="20dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textStyle="italic"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ListView
android:id="@+id/chanlist_list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="vertical" >
</ListView>
<Button
android:id="@+id/btn_chanlist_close"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:onClick="btn_close"
android:background="@drawable/botones"
android:textColor="#FFFFFF"
android:text="@string/btn_close" />
</LinearLayout>
The "problem" is that the layout will try to fit the screen to the whole layout definition, i.e. if you have too much elements in your layout, your ListView
will be compressed in a short amount of space and it will make it hard to scroll. Try to simplify your layout as much as you can.
you can use a background
image as it will extend the wrap_content
or you can use empty image and extend it's size in code using ImageView.getLayoutParams().width = width;
or ImageView.getLayoutParams().height = height;