UPDATE - Added experimentation result
Is it possible to implement an ExpandableListView to have a viewpager child?
I tried to put viewpager as a child in ExpandableListView but it is not showing :( I also tried to add it under ScrollView but same result so I think it is a problem being under a scrollable view? But when I removed ScrollView it showed up. What can I do so they can go together?
This is what I am aiming for to do
And this is what happen when I tried to implement on my own code.
P.S. This is just a sampler and not yet finished. I have 3 children and my layout displayed thrice also with each item inside
2 Answers
Answers 1
I made a sample with Java. Hope that helps!
activity_main.xml:
<?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:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/btnClearChecks" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Clear Checks" /> <Button android:id="@+id/btnPutOrder" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Put Order" /> </LinearLayout> <ExpandableListView android:id="@+id/expandedListView" android:layout_width="match_parent" android:layout_height="match_parent"> </ExpandableListView> </LinearLayout>
expanded_list_group.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:descendantFocusability="blocksDescendants" > <CheckBox android:id="@+id/cb_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="40dp" android:layout_gravity="center_vertical" /> <TextView android:id="@+id/tv_group" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Text" android:textSize="30sp" /> </LinearLayout>
list_child_pager.xml:
<?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="wrap_content" android:orientation="vertical" android:paddingStart="60dp"> <android.support.v4.view.ViewPager android:id="@+id/layout_child" android:layout_width="match_parent" android:layout_height="200dp" /> </LinearLayout>
list_pager_item.xml:
<?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:columnCount="@integer/pager_col_count" android:rowCount="@integer/pager_row_count"> </GridLayout>
integers.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="pager_col_count">3</integer> <integer name="pager_row_count">3</integer> </resources>
ChildItemSample.java
public class ChildItemSample { private boolean checked = false; private String name; private int qty; public int getQty() { return qty; } public void setQty(int qty) { this.qty = qty; } public boolean isChecked() { return checked; } public void setChecked(boolean checked) { this.checked = checked; } public String getName() { return name; } public ChildItemSample(String name, int qty){ this.name = name; this.qty = qty; } }
MainActivity.java:
public class MainActivity extends AppCompatActivity { Button clearChecks, putOrder; ExpandableListView expandableListView; ExpandableListPagerAdapter expandableListAdapter; int lastExpandedPosition = -1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); expandableListView = findViewById(R.id.expandedListView); clearChecks = findViewById(R.id.btnClearChecks); putOrder = findViewById(R.id.btnPutOrder); List<String> listTitle = genGroupList(); expandableListAdapter = new ExpandableListPagerAdapter(this, getSupportFragmentManager(), listTitle, genChildList(listTitle)); expandableListView.setAdapter(expandableListAdapter); expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { if(lastExpandedPosition != -1 && (lastExpandedPosition != groupPosition)){ expandableListView.collapseGroup(lastExpandedPosition); } lastExpandedPosition = groupPosition; } }); clearChecks.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { expandableListAdapter.clearChecks(); } }); putOrder.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ArrayList<String> putOrder = expandableListAdapter.getOrderList(); StringBuilder msg = new StringBuilder(); for(int i=0; i<putOrder.size(); i++){ msg.append(putOrder.get(i)); msg.append("\n"); } Toast.makeText(getBaseContext(), msg, Toast.LENGTH_LONG).show(); } }); } private ArrayList<String> genGroupList(){ ArrayList<String> listGroup = new ArrayList<>(); for(int i=1; i<10; i++){ listGroup.add("Group: " + i); } return listGroup; } private Map<String, List<ChildItemSample>> genChildList(List<String> header){ Map<String, List<ChildItemSample>> listChild = new HashMap<>(); for(int i=0; i<header.size(); i++){ List<ChildItemSample> testDataList = new ArrayList<>(); int a = (int)(Math.random()*28); for(int j=0; j<a; j++){ ChildItemSample testItem = new ChildItemSample("Child " + (j + 1), 0); testDataList.add(testItem); } listChild.put(header.get(i), testDataList); } return listChild; } }
ExpandableListPagerAdapter.java:
public class ExpandableListPagerAdapter extends BaseExpandableListAdapter { private int child_items_per_page; private Context context; private FragmentManager fm; private List<String> listGroup; private Map<String, List<ChildItemSample>> listChild; private static int checkedBoxesCount; private boolean[] checkedGroup; ExpandableListPagerAdapter(Context context, FragmentManager manager, List<String> listGroup, Map<String, List<ChildItemSample>> listChild) { this.context = context; fm = manager; this.listGroup = listGroup; this.listChild = listChild; checkedBoxesCount = 0; checkedGroup = new boolean[listGroup.size()]; child_items_per_page = context.getResources().getInteger(R.integer.pager_col_count) * context.getResources().getInteger(R.integer.pager_row_count); } @Override public int getGroupCount() { return listGroup.size(); } @Override //******* Special ******* public int getChildrenCount(int groupPosition) { return 1; } @Override public String getGroup(int groupPosition) { return listGroup.get(groupPosition); } @Override public ChildItemSample getChild(int groupPosition, int childPosition) { return listChild.get(listGroup.get(groupPosition)).get(childPosition); } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } @Override public boolean hasStableIds() { return false; } @Override public View getGroupView(int groupPosition, boolean b, View view, ViewGroup viewGroup) { String itemGroup = getGroup(groupPosition); GroupViewHolder groupViewHolder; if(view == null){ LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.expanded_list_group, null); groupViewHolder = new GroupViewHolder(); groupViewHolder.tvGroup = view.findViewById(R.id.tv_group); groupViewHolder.cbGroup = view.findViewById(R.id.cb_group); groupViewHolder.cbGroup.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int pos = (int)view.getTag(); checkedGroup[pos] = !checkedGroup[pos]; for(ChildItemSample item : listChild.get(listGroup.get(pos))){ item.setChecked(checkedGroup[pos]); } notifyDataSetChanged(); } }); view.setTag(groupViewHolder); }else { groupViewHolder = (GroupViewHolder)view.getTag(); } groupViewHolder.tvGroup.setText(String.format("%s (%d)", itemGroup, listChild.get(listGroup.get(groupPosition)).size())); if(checkedGroup[groupPosition]) groupViewHolder.cbGroup.setChecked(true); else groupViewHolder.cbGroup.setChecked(false); groupViewHolder.cbGroup.setTag(groupPosition); return view; } @Override public View getChildView(final int groupPosition, int childPosition, boolean b, View view, ViewGroup viewGroup) { LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View rowView = inflater.inflate(R.layout.list_child_pager, null); ViewPager childLayout = rowView.findViewById(R.id.layout_child); List<ChildItemSample> childItemSampleList = listChild.get(listGroup.get(groupPosition)); ChildPagerAdapter adapter = new ChildPagerAdapter(fm, childItemSampleList, child_items_per_page); childLayout.setAdapter(adapter); return rowView; } public class ChildPagerAdapter extends FragmentStatePagerAdapter { private List<ChildItemSample> pagerItemList; private int items_per_page; ChildPagerAdapter(FragmentManager fm, List<ChildItemSample> pagerItemList, int items_per_page) { super(fm); this.pagerItemList = pagerItemList; this.items_per_page = items_per_page; } @Override public Fragment getItem(int position) { return ChildFragment.newInstance(position, pagerItemList, items_per_page); } @Override public int getCount() { int remainedItemCount = pagerItemList.size()%child_items_per_page; if(remainedItemCount == 0) return (pagerItemList.size()/child_items_per_page); else return (pagerItemList.size()/child_items_per_page + 1); } } public static class ChildFragment extends Fragment { private static final String SECTION_NUMBER = "section_number"; private static final String ITEMS_PER_PAGE = "items/page"; private static List<ChildItemSample> itemList; public ChildFragment() {} public static ChildFragment newInstance(int sectionNumber, List<ChildItemSample> pagerItemList, int itemPerPage) { ChildFragment fragment = new ChildFragment(); Bundle args = new Bundle(); args.putInt(SECTION_NUMBER, sectionNumber); args.putInt(ITEMS_PER_PAGE, itemPerPage); fragment.setArguments(args); itemList = pagerItemList; return fragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { int child_items_per_page = getArguments().getInt(ITEMS_PER_PAGE); int start_item = getArguments().getInt(SECTION_NUMBER)*child_items_per_page; int itemCount = itemList.size() - getArguments().getInt(SECTION_NUMBER)*child_items_per_page; if(itemCount > child_items_per_page) itemCount = child_items_per_page; itemCount += getArguments().getInt(SECTION_NUMBER)*child_items_per_page; GridLayout pageView = (GridLayout)inflater.inflate(R.layout.list_pager_item, container, false); for(int i=start_item; i<itemCount; i++){ ChildItemSample expandedListText = itemList.get(i); CheckBox cbChild = new CheckBox(getContext()); GridLayout.LayoutParams params = new GridLayout.LayoutParams(); params.width = (int)(80 * getContext().getResources().getDisplayMetrics().density); cbChild.setLayoutParams(params); cbChild.setChecked(expandedListText.isChecked()); cbChild.setText(expandedListText.getName()); cbChild.setTag(i); pageView.addView(cbChild); cbChild.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { CheckBox cb = (CheckBox) view; int pos = (int) view.getTag(); ChildItemSample selectedItem = itemList.get(pos); selectedItem.setChecked(cb.isChecked()); if(cb.isChecked()){ checkedBoxesCount++; Toast.makeText(getContext(),"Checked value is: " + itemList.get(pos).getName(), Toast.LENGTH_SHORT).show(); }else { checkedBoxesCount--; if(checkedBoxesCount == 0){ Toast.makeText(getContext(),"nothing checked",Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getContext(),"unchecked",Toast.LENGTH_SHORT).show(); } } } }); } return pageView; } } public void clearChecks() { for(int i=0; i<checkedGroup.length; i++) checkedGroup[i] = false; for(List<ChildItemSample> value : listChild.values()) { for (ChildItemSample sample : value) { sample.setChecked(false); } } checkedBoxesCount = 0; notifyDataSetChanged(); } public ArrayList<String> getOrderList(){ ArrayList<String> overallOrder = new ArrayList<>(); for(int i=0; i<getGroupCount(); i++){ //for(int j=0; j<getChildrenCount(i); j++){ for(int j=0; j<listChild.get(getGroup(i)).size(); j++){ if(getChild(i,j).isChecked()){ String newOrder = getGroup(i) + ">" + getChild(i, j).getName(); overallOrder.add(newOrder); } } } return overallOrder; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } private class GroupViewHolder { CheckBox cbGroup; TextView tvGroup; } }
Answers 2
can you check this API https://developer.android.com/reference/android/widget/ExpandableListView
A view that shows items in a vertically scrolling two-level list
0 comments:
Post a Comment