Reputation: 660
I have three sets of TextView as a heading and ExpandableListView as content inside a RelativeLayout, that is I have 3 TextViews and 3 ExpandableListViews alternating between each other. Now in devices with smaller screen size, my layouts go out of the view below the screen. So logically the user would try to scroll down. But its not scrolling the way it should
As shown in the picture above Men, Women, and Kids are TextViews and they have their respective ExpandableListViews each. I also have a list view above for Home and Settings. As seen in the picture most of Kids content is below the screen. But when I try to scroll its having none of it.
Here is my layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cccc">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Men"
android:textSize="30dp"
android:textAllCaps="true"
android:textAlignment="center"
android:layout_below="@id/listView"
android:id="@+id/menTextView"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/menExpandableListView"
android:layout_below="@id/menTextView" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="women"
android:textSize="30dp"
android:textAllCaps="true"
android:textAlignment="center"
android:layout_below="@id/menExpandableListView"
android:id="@+id/womenTextView"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/womenExpandableListView"
android:layout_below="@id/womenTextView" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="kids"
android:textSize="30dp"
android:textAllCaps="true"
android:textAlignment="center"
android:layout_below="@id/womenExpandableListView"
android:id="@+id/kidsTextView"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/kidsExpandableListView"
android:layout_below="@id/kidsTextView" />
</RelativeLayout>
This is how I solved it, I just had one Expandable List view and made the other TextViews are Group Headers inside Expandable List View without any children.
As suggested by one of the answers, I had a property that says if my Group is a header, so isHeader() gives if my group is a header or not.
Here is my layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="15"
android:background="#cccc">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"
android:fadeScrollbars="false"
/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/expandableListView"
android:fadeScrollbars="false"
android:layout_below="@id/listView"
/>
</RelativeLayout>
And my updated getGroupView in the Adapter for expandableListView that extends BaseExpandableListAdapter
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ProductHeadGroup headGroup = getGroup(groupPosition);
String header = headGroup.getGroupName();
if (headGroup.isHeader()) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.expandable_list_main_header, null);
TextView headerTextView = (TextView) convertView.findViewById(R.id.idExpandableHeaderItem);
headerTextView.setText(header);
} else {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.expandable_list_header, null);
ImageView imageView = (ImageView) convertView.findViewById(R.id.expandableHeaderIcon);
if (isExpanded){
imageView.setImageResource(R.drawable.ic_action_collapse_dark);
} else {
imageView.setImageResource(R.drawable.ic_action_expand_dark);
}
TextView headerTextView = (TextView) convertView.findViewById(R.id.idExpandableHeaderItem);
headerTextView.setText(header);
}
return convertView;
}
As shown above, I implemented my custom expand/collapse indicators having my own ImageView in the GroupLayout. and disabled it in my Activity using
expandableListView.setGroupIndicator(null)
Upvotes: 3
Views: 1188
Reputation: 44188
The whole problem is in your design. First of all RelativeLayout takes up the whole screen (or the free space that's left) thus, the last ExpandableListView becomes very small and practically unscrollable.
To do this right, you should:
getGroupTypeCount
return 2 (header and non-header)getGroupType
return 1 if a header, else return 0getGroupView
and inflate accordinglyexpListView.setIndicator(null);
)getGroupView
and elv.setOnGroupItemClick()
Looks like a lot of work but in the end it will be worth it.
The result: a dynamic ExpandableListview which scrolls properly no matter how many headers, groups and children you have.
Side note: I'd recommend a CursorTreeAdapter for applying, CursorLoader for fetching and SQLite for storing the data.
Upvotes: 1
Reputation: 17625
RelativeLayout
is not scrollable, hence cannot be larger than the physical display.
The first solution that comes to mind is placing RelativeLayout
in ScrollView
. There are couple of issues with that:
RelativeLayout
height to wrap_content
when placed inside ScrollView
. If ExpandableListView
height is set as wrap_content
then it's parent height cannot be wrap_content
. From docs:Note: You cannot use the value wrap_content for the android:layout_height attribute of a ExpandableListView in XML if the parent's size is also not strictly specified (for example, if the parent were ScrollView you could not specify wrap_content since it also can be any length. However, you can use wrap_content if the ExpandableListView parent has a specific size, such as 100 pixels.
ListView
should never be placed under ScrollView
. From docs:You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.
In this specific case, since the view hierarchy is flat (just one level), you should be using LinearLayout
instead of RelativeLayout
. RelativeLayout
will normally make 2 measure pass.
Solution:
Use LinearLayout
instead of RelativeLayout
and set layout_weight
for all the list views including expandable list view, so that left out space is equally divided by all the list views.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#cccc"
android:orientation="vertical"
android:weightSum="4">
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/listView"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Men"
android:textSize="30dp"
android:textAllCaps="true"
android:textAlignment="center"
android:id="@+id/menTextView" />
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/menExpandableListView"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="women"
android:textSize="30dp"
android:textAllCaps="true"
android:textAlignment="center"
android:id="@+id/womenTextView"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/womenExpandableListView"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="kids"
android:textSize="30dp"
android:textAllCaps="true"
android:textAlignment="center"
android:id="@+id/kidsTextView"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/kidsExpandableListView"/>
</LinearLayout>
Upvotes: 1