Showing posts with label expandablelistview. Show all posts
Showing posts with label expandablelistview. Show all posts

Tuesday, May 22, 2018

ExpandableListView with ViewPager combination as its child

Leave a Comment

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

Original Pic

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

enter image description here

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

Read More

Wednesday, June 22, 2016

Populating ExpandableListView from database - not working

Leave a Comment

I have tables Receipt and Logs and table receipt has_many logs. So on my LogsRecapitulation.class I have grouping logs by sort and grade(those two columns are from table logs).

I have trying to made this via ExpandableListView. Each group of logs parent elements will consists of Sort and Grade for each group from database.

Children elements will have textViews for logs count in child element, mass, price and some calculated price. And it should look something like this:

enter image description here

I have created expandableListView layouts and adapter. But now I have trouble with populating parent and child elements from database.

Here is my code so you can see what I have done so far.

This is expandableListAadapter class:

public class ExpandableListAdapter extends BaseExpandableListAdapter {      private Context _context;     private List<String> _listDataHeader;     private HashMap<String, List<String>> _listDataChild;      public ExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listDataChild) {         this._context = context;         this._listDataHeader = listDataHeader;         this._listDataChild = listDataChild;     }      @Override     public Object getChild(int groupPosition, int childPosition) {         return this._listDataChild.get(this._listDataHeader.get(groupPosition)).get(childPosition);     }      @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 inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);             convertView = inflater.inflate(R.layout.expendable_items, null);         }          TextView logsMass = (TextView) convertView.findViewById(R.id.exp_lis_mass);         TextView logsPrice = (TextView) convertView.findViewById(R.id.exp_lis_price);         TextView logsMassPrice = (TextView) convertView.findViewById(R.id.ext_lis_sum_price);         logsMass.setText(childText);         logsPrice.setText(childText);         logsMassPrice.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 inflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);             convertView = inflater.inflate(R.layout.expandable_group, null);         }          TextView logsSort = (TextView) convertView.findViewById(R.id.exp_gr_sort);         TextView logsGrade = (TextView) convertView.findViewById(R.id.exp_gr_grade);         TextView logsCount = (TextView) convertView.findViewById(R.id.exp_gr_logs_count);         logsSort.setText(headerTitle);         logsGrade.setText(headerTitle);         logsCount.setText(headerTitle);          return convertView;     }      @Override     public boolean hasStableIds() {         return false;     }      @Override     public boolean isChildSelectable(int groupPosition, int childPosition) {         return true;     } } 

And this is my logsRecapitulation class:

public class LogsRecapitulation extends AppCompatActivity {      ExpandableListAdapter listAdapter;     ExpandableListView expListView;     List<String> listDataHeader;     HashMap<String, List<String>> listDataChild;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.expandable_layout);         //recieve RecepitID and query to group_by logs         final long forwardedId = (long) getIntent().getExtras().get(String.valueOf("recepitID"));         List<Logs> logsList = new Select().from(Logs.class).where("Receipt = " + forwardedId).groupBy("SortID, Grade").execute();         //get the listview         expListView = (ExpandableListView) findViewById(R.id.lvExp);         prepareListData();         listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);         expListView.setAdapter(listAdapter);     }      private void prepareListData() {      } } 

My problem now is to populate ExpendableListView with data from database. Here are my table classes:

//receipt table @Table(name = "Receipt") public class Receipt extends Model {     @Column(name="Place")     String place;     @Column(name="ShippingNumber")     String shippingNumber;     @Column(name="Warehouse")     String warehouse;     @Column(name="Carrier")     String carrier;     @Column(name="LicencePlate")     String licencePlate;     @Column(name = "Driver")     String driver;     @Column(name = "Customer")     String customer;     @Column(name= "DestWarehouse")     String destWarehouse;     @Column(name = "Employee")     String employee;     @Column(name = "PriceType")     String priceType;     @Column(name = "PriceCorrection")     Double priceCorrection;     @Column(name = "PriceCorrection2")     Double priceCorrection2;     @Column(name = "Supplier")     String supplier;     @Column(name = "CreatedAt")     Date createdAt; } //logs table @Table(name = "Logs") public class Logs extends Model {     @Column(name="PlateNumber")     String plate_number;     @Column(name="SortID")     String sort_id;     @Column(name="Grade")     String grade;     @Column(name = "Diametar")     double diameter;     @Column(name="Length")     double length;     @Column(name="CreatedAt")     Date createdAt;     @Column(name="Receipt")     Receipt receipt;     @Column(name = "Price")     Price price; } //price table @Table(name = "Price") public class Price extends Model {     @Column(name = "Sort")     String sort;     @Column(name = "Grade")     String grade;     @Column(name = "Diameter")     double diameter;     @Column(name = "LengthDG")     double lengthDG;     @Column(name = "LengthGG")     double lengthGG;     @Column(name = "StumpPriceKn")     double stumpPrice_kn;     @Column(name = "RoadPriceKn")     double roadPrice_kn; } 

Note: I'm using ActiveAndroid.

Please if anyone knows how to populate expandable listView from database please help.

Question: What should I do to successfully populate ExpandableListView from database?

1 Answers

Answers 1

I am not an expert on ActiveAndroid.But here are the steps to create an expandablelistview using cursor.

You need two methods in your db helper class to gather the rows that you'll need.

public Cursor fetchGroup() {     String query = "SELECT * FROM rooms"     return mDb.rawQuery(query, null); }  public Cursor fetchChildren(String room) {     String query = "SELECT * FROM devices WHERE id_room = '" + room + "'";     return mDb.rawQuery(query, null); } 

Then you need to configure the adapter (in your activity):

  public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {     public MyExpandableListAdapter(Cursor cursor, Context context,int groupLayout,          int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom,          int[] childrenTo) {             super(context, cursor, groupLayout, groupFrom, groupTo,                   childLayout, childrenFrom, childrenTo);         }     }      @Override     protected Cursor getChildrenCursor(Cursor groupCursor) {         Cursor childCursor = mDbHelper.fetchChildren(groupCursor.getString(groupCursor.getColumnIndex("id_room"));                     getActivity().startManagingCursor(childCursor);         childCursor.moveToFirst();         return childCursor;     } } 

And finally, call the adapter and configure it to your list (in your activity):

private void fillData() {     mGroupsCursor = mDbHelper.fetchGroup();     getActivity().startManagingCursor(mGroupsCursor);     mGroupsCursor.moveToFirst();      ExpandableListView elv = (ExpandableListView) getActivity().findViewById(android.R.id.list);      mAdapter = new MyExpandableListAdapter(mGroupsCursor, getActivity(),         R.layout.rowlayout_expgroup,                     // Your row layout for a group         R.layout.rowlayout_itemlist_exp,                 // Your row layout for a child         new String[] { "id_room" },                      // Field(s) to use from group cursor         new int[] { android.R.id.room },                 // Widget ids to put group data into         new String[] { "name_device", "state_device" },  // Field(s) to use from child cursors         new int[] { R.id.device, R.id.state });          // Widget ids to put child data into          lv.setAdapter(mAdapter);                         // set the list adapter.     } } 

So All together code

public class List_Exp extends Activity {     @Override     public void onActivityCreated(Bundle savedInstanceState) {         super.onActivityCreated(savedInstanceState);         mDbHelper = new YourDB(getActivity());         mDbHelper.open();         fillData();     }      private void fillData() {          // set list adapter here     }      public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {         // Your adapter     } } 

If you want to capture click event on group/child then handle events:

lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {     @Override     public boolean onChildClick(ExpandableListView parent, View v,         int groupPosition, int childPosition, long id) {         // Your child click code here         return true;     } });  lv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {     @Override     public boolean onGroupClick(ExpandableListView parent, View v,         int groupPosition, int groupPosition, long id) {         // Your group click code here         return true;     } }); 
Read More