I am searching for a way to load data into an Expandale List View, the output I want to resemble the one of the picture attached here
In order this to be done dynamically, is it better to be read from a csv? Or to create a DB? Furthermore, on a sub-item press, I want a ScrollView to appear.
Here is the code so far:
The layout of the activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ExpandableListView
android:id= "#+id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="#+id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
The itemlayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/grp_child"
android:paddingLeft="50dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
And the subitem:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="#+id/row_name"
android:paddingLeft="50dp"
android:focusable="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
In the activity, I have hardcoded some values so far, using some tutorials I came across:
public void onCreate(Bundle savedInstanceState) {
try{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photographers);
SimpleExpandableListAdapter expListAdapter =
new SimpleExpandableListAdapter(
this,
createGroupList(),
R.layout.group_row,
new String[] { "Group Item" },
new int[] { R.id.row_name },
createChildList(),
R.layout.child_row,
new String[] {"Sub Item"},
new int[] { R.id.grp_child}
);
setListAdapter( expListAdapter );
}catch(Exception e){
System.out.println("Errrr +++ " + e.getMessage());
}
}
/* Creating the Hashmap for the row */
#SuppressWarnings("unchecked")
private List createGroupList() {
ArrayList result = new ArrayList();
for( int i = 0 ; i < 15 ; ++i ) { // 15 groups........
HashMap m = new HashMap();
m.put( "Group Item","Group Item " + i ); // the key and it's value.
result.add( m );
}
return (List)result;
}
#SuppressWarnings("unchecked")
private List createChildList() {
ArrayList result = new ArrayList();
for( int i = 0 ; i < 15 ; ++i ) { // this -15 is the number of groups(Here it's fifteen)
/* each group need each HashMap-Here for each group we have 3 subgroups */
ArrayList secList = new ArrayList();
for( int n = 0 ; n < 3 ; n++ ) {
HashMap child = new HashMap();
child.put( "Sub Item", "Sub Item " + n );
secList.add( child );
}
result.add( secList );
}
return result;
}
public void onContentChanged () {
System.out.println("onContentChanged");
super.onContentChanged();
}
/* This function is called on each child click */
public boolean onChildClick( ExpandableListView parent, View v, int groupPosition,int childPosition,long id) {
System.out.println("Inside onChildClick at groupPosition = " + groupPosition +" Child clicked at position " + childPosition);
return true;
}
/* This function is called on expansion of the group */
public void onGroupExpand (int groupPosition) {
try{
System.out.println("Group expanding Listener => groupPosition = " + groupPosition);
}catch(Exception e){
System.out.println(" groupPosition Errrr +++ " + e.getMessage());
}
}
I am wondering if it is a good idea to store the data I want to show in separate csv files (one storing the data for the items, one for the subitems. one for the extra information in the ScrollView), to have id-s for identification and to directly read from the CSVs with the OpenCSVReader?
I would appreciate any pieces of advice,
Thanks
create adapter for your expandable listView. like that
public class ExpandableAdapter extends BaseExpandableListAdapter {
private final Context context;
private final List<Menu> parentObjects;
public ExpandableAdapter(Context context, ArrayList<Menu> parentObjects) {
this.context = context;
this.parentObjects = parentObjects;
}
#Override
public int getGroupCount() {
return parentObjects.size();
}
#Override
public int getChildrenCount(int i) {
return parentObjects.get(i).childMenu.size();
}
#Override
public Menu getGroup(int i) {
return parentObjects.get(i);
}
#Override
public Menu.ChildMenu getChild(int i, int i2) {
return parentObjects.get(i).childMenu.get(i2);
}
#Override
public long getGroupId(int i) {
return i;
}
#Override
public long getChildId(int i, int i2) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
Menu currentParent = parentObjects.get(i);
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context
.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.navdrawer_parent_item, viewGroup,false);
}
ImageView imageViewIndicator = (ImageView) view.findViewById(R.id.imageViewNav);
if (getChildrenCount(i) == 0)
imageViewIndicator.setVisibility(View.GONE);
else
imageViewIndicator.setVisibility(View.VISIBLE);
TextView textViewNavMenuName = (TextView) view.findViewById(R.id.textViewNavParentMenuName);
ImageView imageViewIcon = (ImageView) view.findViewById(R.id.imageViewIcon);
String base64 = currentParent.getImage();
if (base64 != null && !base64.equals("")) {
byte[] imageAsBytes = Base64.decode(currentParent.getImage().getBytes(), Base64
.DEFAULT);
imageViewIcon.setImageBitmap(BitmapFactory.decodeByteArray(imageAsBytes, 0,
imageAsBytes.length));
} else
imageViewIcon.setImageResource(R.drawable.ic_action_android);
textViewNavMenuName.setText(currentParent.getMenuName());
return view;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean b, View view,
ViewGroup viewGroup) {
Menu currentChild = getGroup(groupPosition);
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context
.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.navdrawer_child_item, viewGroup,false);
}
View divider = view.findViewById(R.id.divider);
if (b)
divider.setVisibility(View.VISIBLE);
else
divider.setVisibility(View.GONE);
TextView textViewNavMenuName = (TextView) view.findViewById(R.id.textViewNavChildMenuName);
textViewNavMenuName.setText(currentChild.childMenu.get(childPosition).getMenuName());
return view;
}
#Override
public boolean isChildSelectable(int i, int i2) {
return true;
}
}
and the model for the expandable listView like
public class Menu {
private int AssociatedApp;
private String MenuName;
private String NavigateURL;
private String ActivityName;
private String Image;
private int MenuID;
public ArrayList<ChildMenu> childMenu;
public ArrayList<ChildMenu> getChildMenu() {
return childMenu;
}
public void setChildMenu(ArrayList<ChildMenu> childMenu) {
this.childMenu = childMenu;
}
public int getAssociatedApp() {
return AssociatedApp;
}
public void setAssociatedApp(int associatedApp) {
AssociatedApp = associatedApp;
}
public String getMenuName() {
return MenuName;
}
public void setMenuName(String menuName) {
MenuName = menuName;
}
public String getNavigateURL() {
return NavigateURL;
}
public void setNavigateURL(String navigateURL) {
NavigateURL = navigateURL;
}
public String getActivityName() {
return ActivityName;
}
public void setActivityName(String activityName) {
ActivityName = activityName;
}
public String getImage() {
return Image;
}
public void setImage(String image) {
Image = image;
}
public Menu() {
}
public int getMenuID() {
return MenuID;
}
public class ChildMenu {
private int AssociatedApp;
private String MenuName;
private String NavigateURL;
private String ActivityName;
private String Image;
private int MenuID;
public ChildMenu(String menuName, String activityName) {
this.MenuName = menuName;
this.ActivityName=activityName;
}
public ChildMenu() {
}
public int getAssociatedApp() {
return AssociatedApp;
}
public void setAssociatedApp(int associatedApp) {
AssociatedApp = associatedApp;
}
public String getMenuName() {
return MenuName;
}
public void setMenuName(String menuName) {
MenuName = menuName;
}
public String getNavigateURL() {
return NavigateURL;
}
public void setNavigateURL(String navigateURL) {
NavigateURL = navigateURL;
}
public String getActivityName() {
return ActivityName;
}
public void setActivityName(String activityName) {
ActivityName = activityName;
}
public String getImage() {
return Image;
}
public void setImage(String image) {
Image = image;
}
public int getMenuID() {
return MenuID;
}
}
}
ok now you can create your menu with data and bindwith expandable listview
elv = (ExpandableListView)findViewById(R.id.elv);
elv.setOnGroupExpandListener(onGroupExpandListenser);
MyExpandableAdapter adapter = new MyExpandableAdapter(this, getData());//where getData() will return list of data.
elv.setAdapter(adapter);
parent xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:paddingBottom="12dp"
android:paddingLeft="12dp"
android:paddingTop="12dp">
<ImageView
android:contentDescription="#string/app_name"
android:id="#+id/imageViewIcon"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignParentLeft="true"
android:layout_margin="4dp"
/>
<TextView
android:id="#+id/textViewNavParentMenuName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/imageViewNav"
android:layout_toRightOf="#+id/imageViewIcon"
android:padding="10dp"
android:textSize="15sp"/>
<ImageView
android:contentDescription="#string/app_name"
android:id="#+id/imageViewNav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_margin="4dp"
android:src="#drawable/ic_action_more_nav"
/>
</RelativeLayout>
<include
layout="#layout/divider"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
child 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:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:id="#+id/textViewNavChildMenuName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="45dp"
android:gravity="center_vertical"
android:text="TextView"
android:padding="16dp"/>
<include
layout="#layout/divider"
android:layout_width="match_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
adding listener for expandable listView like this. groupExpandlistener is used for collasping other groups while open one
private int lastExpandedPosition = -1;
for setting up listener
elv.setOnChildClickListener(new DrawerItemClickListener());
elv.setOnGroupClickListener(new DrawerItemClickListener());
elv.setOnGroupExpandListener(new DrawerItemClickListener());
private class DrawerItemClickListener implements ExpandableListView.OnChildClickListener,
ExpandableListView.OnGroupClickListener, ExpandableListView.OnGroupExpandListener {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int
childPosition, long id) {
selectItem(childPosition, navigationConfig.getBaseExpandableListAdapter
().getChild
(groupPosition, childPosition));
return true;
}
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
selectItem(groupPosition, navigationConfig.getBaseExpandableListAdapter
().getGroup
(groupPosition));
return false;
}
#Override
public void onGroupExpand(int groupPosition) {
if (lastExpandedPosition != -1
&& groupPosition != lastExpandedPosition) {
expandableListView.collapseGroup(lastExpandedPosition);
}
lastExpandedPosition = groupPosition;
}
}
for sample data use to bind with getData(). note create constructor in model class as given in getData()
//Sample data for expandable list view.
public List<Menu> getData()
{
List<Menu> parentObjects = new ArrayList<Menu>();
for (int i = 0; i<20; i++)
{
parentObjects.add(new Menu("Mother " +i, "Father " +i, "Header " + i, "Footer " +i, getChildren(i)));
}
return parentObjects;
}
private List<Menu.ChildMenu> getChildren(int childCount)
{
List<Menu.ChildMenu> childObjects = new ArrayList<Menu.ChildMenu>();
for (int i =0; i<childCount; i++)
{
childObjects.add(new Menu.ChildMenu("Child " + (i+1), 10 +i ));
}
return childObjects;
}
Related
My code java. I'm getting data from the intent as an array. I am using arraylist,listview and custom adapter. I can show the incoming data using listview. I want the item I clicked to be deleted. The name of my delete button "deleteshop" in customadapter. How can I do that ?
My code;
final ListView list = findViewById(R.id.list);
final ArrayList<SubjectData> arrayList = new ArrayList<SubjectData>();
final String[] cartList = getIntent().getStringArrayExtra("saleData");
arrayList.add(new SubjectData("", ""));
final int cartListLength = cartList.length;
int counter = 0;
String lastItem = "";
for (String e : cartList) {
counter += 1;
if (e == "" || e == null) {
lastItem = cartList[counter-3];
break;
}
String productPhoto = "";
switch (e) {
case "1 PC GREEN COLA x 10.00 TL":
productPhoto = "cc";
break;
default:
productPhoto = "";
break; }
arrayList.add(new SubjectData(e, productPhoto));;
}
arrayList.remove(arrayList.size()-1);
arrayList.remove(arrayList.size()-1);
arrayList.add(new SubjectData("*** GRAND TOTAL TL:" + lastItem + " ***", "arrowgreen"));
arrayList.add(new SubjectData("", ""));
arrayList.add(new SubjectData("", ""));
final CustomAdapter customAdapter = new CustomAdapter(this, arrayList);
list.setAdapter(customAdapter);
SubjectData model class:
String SubjectName;
String Image;
public SubjectData(String subjectName, String image) {
this.SubjectName = subjectName;
this.Image = image;
}
Customadapter;
class CustomAdapter implements ListAdapter {
ArrayList<SubjectData> arrayList;
Context context;
public CustomAdapter(Context context, ArrayList<SubjectData> arrayList) {
this.arrayList=arrayList;
this.context=context;
}
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return true;
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final SubjectData subjectData=arrayList.get(position);
if(convertView==null){
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView=layoutInflater.inflate(R.layout.list_row, null);
TextView tittle=convertView.findViewById(R.id.title);
ImageView imag=convertView.findViewById(R.id.list_image);
ImageView
deleteshop=convertView.findViewById(R.id.deleteshop);
deleteshop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Deneme",
Toast.LENGTH_SHORT).show();
}
});
tittle.setText(subjectData.SubjectName);
Resources resources = context.getResources();
final int resourceId = resources.getIdentifier(subjectData.Image, "drawable",
context.getPackageName());
imag.setImageResource(resourceId);
}
return convertView;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getViewTypeCount() {
return arrayList.size();
}
#Override
public boolean isEmpty() {
return false;
}
listview design;
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dip">
<LinearLayout
android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip"
android:padding="3dip">
<ImageView
android:id="#+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip" />
</LinearLayout>
<TextView
android:id="#+id/title"
android:layout_width="250dp"
android:layout_height="match_parent"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:gravity="center"
android:textColor="#040404"
android:textSize="15dip"
android:textStyle="bold"
android:typeface="sans" />
<ImageView
android:layout_gravity="center"
android:id="#+id/deleteshop"
android:src="#drawable/negative"
android:layout_width="25dp"
android:layout_height="25dp" ></ImageView>
</LinearLayout>
If you want to delete clicked item from your list view then you can use this code .I tested and its deleting smoothly , after deleting its updating list also.
CustomAdapter customAdapter = new CustomAdapter(this,R.layout.list_row, arrayList);
list.setAdapter(customAdapter);
// after setting adapter put this code
// and update your ui again using set adapter
Log.e("Custom",""+arrayList.size());
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
arrayList.remove(i);
list.setAdapter(customAdapter);
}
});
This is not a best solution but ulternative , suppose if you want to update your adapter on click of deletebutton first create one interface , here is sample
public interface MyInterface{
public void deleteItem(int pos);
}
Now in your main activity use like this MainActivity extends AppCompatActivity implements MyInterface and place your interface method public void deleteItem(int pos){ arrayList.remove(pos); list.setAdapter(customAdapter); }
After that call this method from your adapter like below
deleteshop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "Delete",
Toast.LENGTH_SHORT).show();
//Actually change your list of items here
if (context instanceof SampleList) {
((MainActivity)context).deleteItem(position);
}
}
});
I want my app to auto-scroll at particularGroup in ExpandableList when a user selects a particular group name from RecyclerView. I am using the Interface to handle the click from RecyclerView
here is my mainActivity code:
#Override
public void onItemClick(int position) {
menuListForRestaurant.setVisibility(View.GONE);
if (!menuOpenChecker){
menuOpenChecker=true;
}else{
menuOpenChecker=false;
}
//The above code gets execute except for the below one
listView.smoothScrollToPosition(position);// this line is not executing
}
#SuppressLint("ClickableViewAccessibility")
private void ListViewAdapter(final HashMap<String, ArrayList<ProductList>> objectMap, final ArrayList<String> headerList) {
listViewAdapter= new RestaurantItemListView(RestaurantDetail.this.getApplicationContext(), objectMap,headerList);
listView.setAdapter(listViewAdapter);
listViewAdapter.notifyDataSetChanged();
}
private void RecyclerMenuView(ArrayList<String> headerList){
menuItemRecyclerView.setLayoutManager(new LinearLayoutManager(this));
menuItemRecyclerView.getRecycledViewPool().clear();
menuAdapterRecyclerView= new RestaurantMenuRecyclerView(headerList, this.getApplicationContext());
menuItemRecyclerView.setItemAnimator(new DefaultItemAnimator());
menuItemRecyclerView.setAdapter(menuAdapterRecyclerView);
menuAdapterRecyclerView.notifyDataSetChanged();
menuAdapterRecyclerView.setOnClick(RestaurantDetail.this);
}
Its like the line which I have mentioned as not working because it doesn't get updated at the ExpandableListView
Thank you in Advance please anyone??
I have Finally resolved issue by using simeple code below:
//AutoScroll for menu
int t = 0,j, e=0, l=0;
for (int n=0; n<=position;n++){
e= e +objectMap.get(textHeaderlist.get(n)).size();
l= l+450;
}
t=position+1;
j= 200+e+t+l;
scrollView.scrollTo(5, j);
which finally resolve my issue.
Either way, thank you!
As you are using NonScrollExpandableListView, so the ExpandableListView does not scroll. Here I show 3 possible solutions:
NonScrollExpandableListView and ScrollView (your current approach): Instead of scroll the ExpandableListView, you have to scroll the ScrollView. It will be very difficult to calculate the scroll position if there is any group in the ExpandableListView expanded. Therefore it is much easier to collapse all groups and then expands only the desired group. Code is like this (I have not tested it):
for (int i = 0; i < listViewAdapter.getGroupCount(); i++) listView.collapseGroup(i);
int a = header.getHeight(); // header refers to all views above the ExpandableListView.
a += (listViewAdapter.getGroupView(0, false, null, null).getHeight() + listView.getDividerHeight())*
position;
scrollView.smoothScrollTo(0, a);
listView.expandGroup(position);
2.ExpandableListView with header (NoScrollView): Start a new project and try this sample, verify if it meets your requirements. Here I used Spinner instead of RecyclerView.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
LinkedHashMap<String, ArrayList<String>> dataList;
ExpandableListView expandableListView;
CustomBaseExpandableListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataList = createSampleList();
expandableListView = findViewById(R.id.expandable_list_view);
adapter = new CustomBaseExpandableListAdapter(getApplicationContext(), dataList);
expandableListView.setAdapter(adapter);
View header = getLayoutInflater().inflate(R.layout.header, null);
Button btExpand = header.findViewById(R.id.bt_expand);
btExpand.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
for (int i = 0; i < adapter.getGroupCount(); i++) expandableListView.expandGroup(i);
}
});
Spinner spinner = findViewById(R.id.selector);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplication(), android.R.layout.simple_list_item_1,
new ArrayList<>(dataList.keySet()));
spinner.setAdapter(arrayAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
int a = 1; // Without header a=0, with header a=1.
for (int j = 0; j < i; j++) {
a += (expandableListView.isGroupExpanded(j) ? adapter.getChildrenCount(j) : 0) + 1;
}
// expandableListView.smoothScrollToPosition(a);
expandableListView.smoothScrollToPositionFromTop(a, 0);
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
expandableListView.addHeaderView(header);
}
private LinkedHashMap<String, ArrayList<String>> createSampleList() {
LinkedHashMap<String, ArrayList<String>> dataList = new LinkedHashMap<>();
for (int i = 0; i < 10; i++) {
ArrayList<String> childList = new ArrayList<>();
for (int j = 0; j < 17; j++) {
childList.add("Item " + i + "-" + j);
}
dataList.put("Group " + i, childList);
}
return dataList;
}
}
CustomBaseExpandableListAdapter.java:
public class CustomBaseExpandableListAdapter extends BaseExpandableListAdapter {
ArrayList<String> groupList;
LinkedHashMap<String, ArrayList<String>> dataList;
Context context;
public CustomBaseExpandableListAdapter(Context context, LinkedHashMap<String, ArrayList<String>> dataList) {
this.context = context;
this.dataList = dataList;
groupList = new ArrayList(dataList.keySet());
}
#Override
public int getGroupCount() {
return groupList.size();
}
#Override
public int getChildrenCount(int i) {
return dataList.get(groupList.get(i)).size();
}
#Override
public String getGroup(int i) {
return groupList.get(i);
}
#Override
public String getChild(int i, int i1) {
return dataList.get(groupList.get(i)).get(i1);
}
#Override
public long getGroupId(int i) {
return 0;
}
#Override
public long getChildId(int i, int i1) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
TextView textView;
if (view == null) {
textView = new TextView((context));
textView.setTextSize(30);
textView.setPadding(80, 0, 0, 0);
} else {
textView = (TextView) view;
}
textView.setText(getGroup(i));
return textView;
}
#Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
TextView textView;
if (view == null) {
textView = new TextView((context));
textView.setTextSize(20);
textView.setPadding(120, 0, 0, 0);
} else {
textView = (TextView) view;
}
textView.setText(getChild(i, i1));
return textView;
}
#Override
public boolean isChildSelectable(int i, int i1) {
return true;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Spinner
android:id="#+id/selector"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<ExpandableListView
android:id="#+id/expandable_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
header.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
app:srcCompat="#drawable/ic_launcher_foreground" />
<Button
android:id="#+id/bt_expand"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="+"
android:textSize="30dp" />
</LinearLayout>
ExpandableListView using ViewPager as child view (ExpandableListView with ViewPager combination as its child), ExpandableListView using HorizontalRecyclerView as child view (Expandable list view with HorizontalScroll View for child view): With one of these approachs and set OnGroupExpandListener of the ExpandableListView to expand only one group, then I think that the current RecyclerView in not necessary.
expandableListView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
view.setOnScrollListener(null);
// Fix for scrolling bug
new Handler().post(new Runnable() {
#Override
public void run() {
view.setSelection(pos);
}
});
}
}
#Override
public void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount,
final int totalItemCount) { }
});
'pos' takes scroll to position value
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
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
I made a sample in 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;
}
}
Another sample adapter that has ViewPager child (Without fragment)
public class ExpandableListPagerAdapter2 extends BaseExpandableListAdapter {
private Context context;
private List<String> listGroup;
private Map<String, List<ChildItemSample>> listChild;
private int checkedBoxesCount;
private boolean[] checkedGroup;
private int child_items_per_page;
ExpandableListPagerAdapter2(Context context, List<String> listGroup, Map<String,
List<ChildItemSample>> listChild) {
this.context = context;
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();
}
// ******* Special *******
#Override
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(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(childItemSampleList);
childLayout.setAdapter(adapter);
return rowView;
}
public class ChildPagerAdapter extends PagerAdapter {
private List<ChildItemSample> pagerItemList;
ChildPagerAdapter(List<ChildItemSample> pagerItemList) {
this.pagerItemList = pagerItemList;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
int start_item = position*child_items_per_page;
int itemCount = pagerItemList.size() - start_item;
if(itemCount > child_items_per_page) itemCount = child_items_per_page;
itemCount += start_item;
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
GridLayout pageView = (GridLayout)inflater.inflate(R.layout.list_pager_item, container, false);
for(int i=start_item; i<itemCount; i++){
ChildItemSample expandedListText = pagerItemList.get(i);
CheckBox cbChild = new CheckBox(context);
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.width = (int)(80 * context.getResources().getDisplayMetrics().density);
cbChild.setLayoutParams(params);
cbChild.setChecked(expandedListText.isChecked());
cbChild.setText(expandedListText.getName() + "(" + expandedListText.getQty() + ")");
cbChild.setTag(i);
pageView.addView(cbChild);
cbChild.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int pos = (int) view.getTag();
final ChildItemSample selectedItem = pagerItemList.get(pos);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(selectedItem.getName());
final EditText editText = new EditText(context);
editText.setText("");
editText.append(String.valueOf(selectedItem.getQty()));
builder.setView(editText);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
selectedItem.setQty(Integer.parseInt(editText.getText().toString()));
ExpandableListPagerAdapter2.this.notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel", null);;
builder.show();
editText.requestFocus();
editText.postDelayed(new Runnable() {
#Override
public void run() {
InputMethodManager keyboard = (InputMethodManager)
context.getSystemService(Context.INPUT_METHOD_SERVICE);
keyboard.showSoftInput(editText, 0);
}
},200);
}
});
}
container.addView(pageView);
return pageView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
#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);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
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<ChildItemSample> getOrderList(){
ArrayList<ChildItemSample> overallOrder = new ArrayList<>();
for(int i=0; i<getGroupCount(); i++){
for(int j=0; j<listChild.get(getGroup(i)).size(); j++){
if(getChild(i,j).getQty() > 0){
ChildItemSample newOrder = new ChildItemSample(getGroup(i) + ">" +
getChild(i, j).getName(), getChild(i, j).getQty());
overallOrder.add(newOrder);
}
}
}
return overallOrder;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
private class GroupViewHolder {
CheckBox cbGroup;
TextView tvGroup;
}
}
I have a problem statement in my booking app such that user can delete all the booking of the particular date or all the dates, see this image:
I have tried to add data to the grid view using multiple adapters for listview and the inner gridview, but it's taking data replication. How can I solve this problem?
Each date represents the listview with checkbox,and the UH,U1 etc represents the item of gridview. I want to pass the selected venue id ie. UH,U! etc in a listview and its corresponding dates
Try the sample below :)
MainActivity.java:
public class MainActivity extends Activity {
Button clearChecks;
ExpandableListView expandableListView;
ExpandableListGridAdapter 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);
List<String> listTitle = genGroupList();
expandableListAdapter = new ExpandableListGridAdapter(this, 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();
}
});
}
private List<String> genGroupList(){
List<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() * 8);
for(int j=0; j<a; j++){
ChildItemSample testItem = new ChildItemSample("Child " + (j + 1));
testDataList.add(testItem);
}
listChild.put(header.get(i), testDataList);
}
return listChild;
}
}
ChildItemSample.java:
public class ChildItemSample {
private boolean checked;
private String name;
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ChildItemSample(){
checked = false;
name = "";
}
public ChildItemSample(String name){
checked = false;
this.name = name;
}
}
ExpandableListGridAdapter.java:
public class ExpandableListGridAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> listGroup;
private Map<String, List<ChildItemSample>> listChild;
private int checkedBoxesCount;
private boolean[] checkedGroup;
public ExpandableListGridAdapter(Context context, List<String> listGroup, Map<String,
List<ChildItemSample>> listChild) {
this.context = context;
this.listGroup = listGroup;
this.listChild = listChild;
checkedBoxesCount = 0;
checkedGroup = new boolean[listGroup.size()];
}
#Override
public int getGroupCount() {
return listGroup.size();
}
#Override
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 = inflater.inflate(R.layout.list_grid_item, null);
GridLayout childLayout = view.findViewById(R.id.layout_child);
for(int i = 0; i < listChild.get(listGroup.get(groupPosition)).size(); i++){
ChildItemSample expandedListText = getChild(groupPosition, i);
CheckBox cbChild = new CheckBox(context);
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
params.width = (int)(80 * context.getResources().getDisplayMetrics().density);
cbChild.setLayoutParams(params);
cbChild.setChecked(expandedListText.isChecked());
cbChild.setText(expandedListText.getName());
cbChild.setTag(i);
childLayout.addView(cbChild);
cbChild.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CheckBox cb = (CheckBox) view;
int pos = (int) view.getTag();;
ChildItemSample selectedItem = listChild.get(listGroup.get(groupPosition)).get(pos);
selectedItem.setChecked(cb.isChecked());
if(cb.isChecked()){
checkedBoxesCount++;
Toast.makeText(context,"Checked value is: " +
listChild.get(listGroup.get(groupPosition)).get(pos).getName(),
Toast.LENGTH_SHORT).show();
}else {
checkedBoxesCount--;
if(checkedBoxesCount == 0){
Toast.makeText(context,"nothing checked",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context,"unchecked",Toast.LENGTH_SHORT).show();
}
}
notifyDataSetChanged();
}
});
}
return view;
}
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();
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
private class GroupViewHolder {
CheckBox cbGroup;
TextView tvGroup;
}
}
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">
<Button
android:id="#+id/btnClearChecks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear Checks" />
<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_grid_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_child"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="60dp"
android:columnCount="3"
android:orientation="horizontal">
</GridLayout>
Hope that helps!
I have followed this example tutorial and developed a sample application http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
If i click on Core i want to load one more list in the same Screen under Core,How Could i do this?using my below code i am able to load the child list in another Screen,help?
My Code for ChildClickListener goes here:
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Log.d("onChildClick", "onChildClick");
String position = (String) parentItems.get(groupPosition);
Log.d("position", position);
String child = listDataChild.get(position).get(childPosition);
Log.d("child", child);
if (child.equalsIgnoreCase("Core")) {
ArrayList<String> parentItems = new ArrayList<String>();
HashMap<String, List<String>> listDataChild = new HashMap<String, List<String>>();
ArrayList<String> childItems = new ArrayList<String>();
childItems.add("corejava");
childItems.add("corejava");
childItems.add("corejava");
childItems.add("corejava");
parentItems.add(position);
listDataChild.put(parentItems.get(0), childItems);
expandableList = (ExpandableListView) findViewById(R.id.lvExp);
CoreAdapter adapter = new CoreAdapter(parentItems,
listDataChild);
CustExpListview SecondLevelexplv = new CustExpListview(
MainActivity.this);
adapter.setInflater(
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE),
MainActivity.this);
SecondLevelexplv.setAdapter(adapter);
SecondLevelexplv.setGroupIndicator(null);
expandableList.setAdapter(adapter);
}
i write one treeView adapter for you, you can use this and put many level as you want, for that you need just copy following code:
MainActivity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// add data for test on one list<AccountHierarchical>
AccountHierarchical obj = new AccountHierarchical();
obj.setLevelId(1);
obj.setTitle("level 1");
AccountHierarchical obj2 = new AccountHierarchical();
obj2.setLevelId(1);
obj2.setTitle("level 2");
AccountHierarchical obj3 = new AccountHierarchical();
obj3.setLevelId(1);
obj3.setTitle("level 3");
List<AccountHierarchical> emptyList = new ArrayList<AccountHierarchical>();
obj3.setList(emptyList);
List<AccountHierarchical> list2 = new ArrayList<AccountHierarchical>();
list2.add(obj3);list2.add(obj3);list2.add(obj3);list2.add(obj3);list2.add(obj3);
obj2.setList(list2);
List<AccountHierarchical> list = new ArrayList<AccountHierarchical>();
list.add(obj2);list.add(obj2);list.add(obj2);list.add(obj2);list.add(obj2);
obj.setList(list);
List<AccountHierarchical> result = new ArrayList<AccountHierarchical>();
result.add(obj);result.add(obj);result.add(obj);result.add(obj);
// create Adapter
TreeView adapter = new TreeView(result, this,
getLayoutInflater() , false, 0);
ExpandableListView expandList = (ExpandableListView)findViewById(R.id.expandableList_tree);
expandList.setGroupIndicator(null);
expandList.setAdapter(adapter);
}
CustExpListview:
public class CustExpListview extends ExpandableListView {
int intGroupPosition, intChildPosition, intGroupid;
public CustExpListview(Context context) {
super(context);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// widthMeasureSpec = MeasureSpec.makeMeasureSpec(400,
// MeasureSpec.AT_MOST);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(600,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
AccountHierarchical:
public class AccountHierarchical {
List<AccountHierarchical> list;
private String Title;
private int Id;
public int getId() {
return Id;
}
public void setLevelId(int Id) {
this.Id = Id;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public List<AccountHierarchical> getList() {
return list;
}
public void setList(List<AccountHierarchical> list) {
this.list = list;
}
}
TreeView:
public class TreeView extends BaseExpandableListAdapter implements
OnClickListener {
List<AccountHierarchical> list;
LayoutInflater inflatter;
static Context context;
boolean checkGroup;
int position;
static ProgressDialog ProgressDialog;
public TreeView( List<AccountHierarchical> list, Context context,
LayoutInflater inflatter, boolean checkGroup, int position
) {
this.list = list;
TreeView.context = context;
this.inflatter = inflatter;
this.checkGroup = checkGroup; // this is true when you call from inner.
this.position = position;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return list.get(groupPosition).getList().get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return list.get(groupPosition).getList().get(childPosition).getId();
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if (checkGroup)
groupPosition = position;
List<AccountHierarchical> childtemp = list.get(groupPosition)
.getList();
// call this adapter again for creating another level
if (childtemp.get(childPosition).getList().size() > 0) {
CustExpListview SecondLevelexplv = new CustExpListview(context);
TreeView adapter = null;
adapter = new TreeView(childtemp, context,
inflatter, true, childPosition);
SecondLevelexplv.setGroupIndicator(null);
SecondLevelexplv.setAdapter(adapter);
return SecondLevelexplv;
}
// call one layout, this is last child
else {
convertView = inflatter.inflate(R.layout.grouprow, null);
TextView tv = (TextView) convertView.findViewById(R.id.grouprow);
tv.setText(list.get(groupPosition).getList().get(childPosition)
.getTitle());
tv.setPadding(0, 0, 20, 0);
convertView.setTag(list.get(groupPosition).getList()
.get(childPosition) );
convertView.setId(position);
convertView.setOnClickListener(this);
return convertView;
}
}
#Override
public int getChildrenCount(int groupPosition) {
return list.get(groupPosition).getList().size();
}
#Override
public Object getGroup(int groupPosition) {
return list.get(groupPosition);
}
#Override
public int getGroupCount() {
if (checkGroup)
return 1;
return list.size();
}
#Override
public long getGroupId(int groupPosition) {
return list.get(groupPosition).getId();
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null)
convertView = inflatter.inflate(R.layout.grouprow, null);
TextView tv = (TextView) convertView.findViewById(R.id.grouprow);
if (checkGroup)
tv.setText(list.get(position).getTitle());
else
tv.setText(list.get(groupPosition).getTitle());
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
#Override
public void onClick(View v) {
// your onClick method
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ExpandableListView
android:id="#+id/expandableList_tree"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ExpandableListView>
</RelativeLayout>
grouprow.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/grouprow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:text=""/>
</RelativeLayout>
snap:
You have to create a layout in the xml file (from where your core textview comes from) and display an image view below
onClick of that imageView you will just have to make your layout Gone and Visible
I have just given you direction rest relies on your skill :)
<RelativeLayout
android:id="#+id/option"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:gravity="center"
android:orientation="horizontal" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/linear"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal" >
<ImageView
android:id="#+id/navigationIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/nn" />
<ImageView
android:id="#+id/callOption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/phonee" />
<ImageView
android:id="#+id/imageViewfeedback"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="#drawable/editer" />
</RelativeLayout>
In Jave File
linear.setVisibility(View.GONE);
option.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
if(count==0)
{
linear.setVisibility(View.VISIBLE);
count=1;
}
else
{
linear.setVisibility(View.GONE);
count=0;
}
}
});
You need to switch to Three-Level of Expandable ListView which contains the subchild inside child.
Also check out ExpandableListView with 3 Childs