I am trying to implement an Expandable listView in a fragment. There are no errors coming and when I try to log the output from both the List<String>
and HashMap<String, List<String>>
, I get the actual data logged.
The issue I am getting is when I show the actual Expandable Listview in the fragment. Only the first item of the list is being shown and I cannot expand it (as per screenshot below):
.
This is the code I am using:
Fragment class
public static class LineupFragment extends Fragment {
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_lineup, null);
expListView = (ExpandableListView) rootView.findViewById(R.id.expListView);
prepareListData();
listAdapter = new ExpandableListAdapter(getActivity(), listDataHeader, listDataChild);
expListView.setAdapter(listAdapter);
Log.i("groups", listDataHeader.toString());
Log.i("details", listDataChild.toString());
// Listview Group click listener
expListView.setOnGroupClickListener(new OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,int groupPosition, long id) {
// Toast.makeText(getApplicationContext(),
// "Group Clicked " + listDataHeader.get(groupPosition),
// Toast.LENGTH_SHORT).show();
return false;
}
});
// Listview Group expanded listener
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getActivity().getApplicationContext(),listDataHeader.get(groupPosition) + " Expanded",Toast.LENGTH_SHORT).show();
}
});
// Listview Group collasped listener
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getActivity().getApplicationContext(),listDataHeader.get(groupPosition) + " Collapsed",Toast.LENGTH_SHORT).show();
}
});
// Listview on child click listener
expListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Toast.makeText(getActivity().getApplicationContext(),listDataHeader.get(groupPosition) + " : " + listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition), Toast.LENGTH_SHORT).show();
return false;
}
});
return rootView;
}
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("The Shawshank Redemption");
top250.add("The Godfather");
top250.add("The Godfather: Part II");
top250.add("Pulp Fiction");
top250.add("The Good, the Bad and the Ugly");
top250.add("The Dark Knight");
top250.add("12 Angry Men");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("The Conjuring Despicable Me TurboGrown Ups 2 Red 2 the Wolverine The Conjuring Despicable Me TurboGrown Ups 2 Red 2 the Wolverine");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
**Adapter class**
public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Activity _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Activity context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
@Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
}
TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);
txtListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_group, null);
}
TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
}
Edit: This is the code for the fragment_lineup.xml
file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/LinearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_black"
android:orientation="vertical" >
<ExpandableListView
android:id="@+id/expListView"
android:layout_width="match_parent"
android:layout_height="310dp"
android:layout_weight="0.14" >
</ExpandableListView>
</LinearLayout>
Then I have two other lavout files for a custom layout.
One for the **list_group.xml**
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_black"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="52dp"
android:layout_height="52dp"
android:orientation="vertical" >
<ImageView
android:id="@+id/photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/app_name"
android:fitsSystemWindows="true" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="52dp"
android:orientation="vertical" >
<TextView
android:id="@+id/lblListHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:paddingTop="6dip"
android:textColor="#CC0000"
android:textSize="20dp"
android:textStyle="bold"
tools:ignore="SpUsage" />
</LinearLayout>
</LinearLayout>
And the other for the **list_item.xml**
:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="120dp"
android:orientation="vertical" >
<TextView
android:id="@+id/lblListItem"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:paddingBottom="5dp"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="5dp"
android:textSize="13sp" />
</LinearLayout>
Kindly note that I need to use a fragment because this class is part of a larger app which I am developing, and uses tabs. The whole code works fine in an activity.
I am suspecting that my issue is in the adapter class.
I have finally found out how this can be made. I am pasting the code below for anyone who has been encountering the same problem. Feel free to use:
And this is how the new layout now looks:
Feel free to use this in your code and hope I have helped you somehow :)
Dev.mi's solution works fine. But I was stuck in similar problem bcoz of some stupid mistake. I was making bit sophisticated design and had used scrollView as root parent for ExpandableListView.
ExpandableListView with wrapcontent inside linear layout is enough to make it scrollable.
Adding Scrollable View outside caused Expandable ListView to shrink to show only one header.
Dont place ExpandableListView inside Scroll View