I have a ExpandableListView in my xml and i'm setting its adapter with a custom BaseExpandableListAdapter.
XML:
<ExpandableListView
android:id="#+id/expanlist_EstatisticaArsenal"
android:divider="#null"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:transcriptMode="alwaysScroll"
android:cacheColorHint="#000000"
android:listSelector="#android:color/transparent"
android:visibility="gone">
</ExpandableListView>
android:visibility="gone" because i make it visible after some stuff
Adapter custom class:
public class Adapter_expanEstatistica extends BaseExpandableListAdapter {
private Context c;
private List<BlocoArsenal> listblocos;
public Adapter_expanEstatistica(Context ctx, List<BlocoArsenal> listBlocos)
{
c = ctx;
listblocos = listBlocos;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View expdanableView = inflater.inflate(R.layout.estatistica_expanlist_child, null);
/* Here i populate a tableLayout that exists in expdanableView with some info */
return expdanableView;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return 1;
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return listblocos.size();
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View expdanableView = inflater.inflate(R.layout.estatistica_expanlist_parent, null);
TextView txt = (TextView) expdanableView.findViewById(R.id.txtNomeBloco);
txt.setText(listblocos.get(groupPosition).getNome());
return expdanableView;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return false;
}
XML ChildView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/tblEstasticaArsenal" >
</TableLayout>
</LinearLayout>
XML ParentView:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/txtNomeBloco"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:layout_marginTop="3dp"
android:textColor="#5E302A"
android:text="Nome Bloco"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
When i set the adapter of the expanListView and change its visibility to visible, everything goes ok, but it doesn't show the groupIndicator icon. Anyone can help me?
in method getGroupView try use this layout - android.R.layout.simple_expandable_list_item_2
as a result, your code will look like this:
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View theConvertView, ViewGroup parent)
{
View row = theConvertView;
TextView textView;
if(theConvertView == null) {
row = inflater.inflate(android.R.layout.simple_expandable_list_item_2, null);
textView = (TextView)row.findViewById(android.R.id.text2);
row.setTag(textView);
} else {
textView = (TextView)theConvertView.getTag();
}
//textView.setText(); //TODO set group
return row;
}
If you can see this method is diferrent from your. I used ViewHolderPatter, read about it (this code work better).
I checked it, in my group mas indicator.
Hope, I help you.
Related
I am trying to implement expandable list view. When the list is expanded, it is not scrollable anymore. The header got misplaced.
Here is the layout for the lisltview in my main activity:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="#+id/dashboard_scrollview">
<ExpandableListView
android:id="#+id/leaderboard_list_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:transcriptMode="alwaysScroll" />
</RelativeLayout>
and after the list view is tapped, it expanded but is unable to scroll:
I'm wondering why the header and the first element are not showing up in the list view.
MainActivity:
public void setupLeaderboardListView(){
leaderboardDetail = ExpandableLeaderboardData.getData();
leaderboardListView.setStackFromBottom(true);
leaderboardtitle = new ArrayList<String>(leaderboardDetail.keySet());
leaderboardAdapter = new LeaderboardAdapter(this, leaderboardtitle, leaderboardDetail);
leaderboardListView.setAdapter(leaderboardAdapter);
leaderboardListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Toast.makeText(getApplicationContext(),
leaderboardtitle.get(groupPosition) + " List Expanded.",
Toast.LENGTH_SHORT).show();
}
});
leaderboardListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
leaderboardtitle.get(groupPosition) + " List Collapsed.",
Toast.LENGTH_SHORT).show();
}
});
leaderboardListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
Toast.makeText(
getApplicationContext(),
leaderboardtitle.get(groupPosition)
+ " -> "
+ leaderboardDetail.get(
leaderboardtitle.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT
).show();
return false;
}
});
}
List datasource:
List<String> cricket = new ArrayList<String>();
cricket.add("India");
cricket.add("Pakistan");
cricket.add("Australia");
cricket.add("England");
cricket.add("South Africa");
cricket.add("India");
cricket.add("Pakistan");
cricket.add("Australia");
cricket.add("England");
cricket.add("South Africa");
I tried setting layout_height=match_parent for the expandable list, but it did not work
This can happen when your ExpandableListView has wrap_content for a width and height. To fix, make it the same as the parent RelativeLayout
<ExpandableListView
android:id="#+id/leaderboard_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:transcriptMode="alwaysScroll" />
First of all: ListView is depricated, It should have been dead long ago and yet, i keep seeing post on it!!!
Second:
Move to recyclerView, here are some resources that will help ya:
1. Nice introduction to it: https://developer.android.com/training/material/lists-cards.html
2. My dialog cheetSheet app (something like demo app), one of the dialogs uses expandable recyclverview library, give it a try https://github.com/WithoutCaps/DialogsCheatSheet
Use this code, it's working fine.
This is main activity layout:
<?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" >
<ExpandableListView
android:id="#+id/expandable_listview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ExpandableListView>
</LinearLayout>
Your Parent Item Layout:
<?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" >
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tv_parent_item"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:textSize="20sp"
/>
</LinearLayout>
Your child item layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/iv_child_item"
android:background="#drawable/ic_launcher"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="100dp"
android:layout_marginTop="5dp" >
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tv_child_item1"
android:layout_marginLeft="10dp"
android:textSize="15sp"
android:text="Test"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/tv_child_item2"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:textSize="15sp"
android:text="Test"
/>
</LinearLayout>
Custom Adapter class:
import java.util.HashMap;
import java.util.List;
import com.example.expandablelistview.R;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
public class ExpandableAdapter extends BaseExpandableListAdapter{
private Context context;
private List<String> parentList;
private HashMap<String , List<Songs>> childList;
ImageLoader imageLoader = ImageLoader.getInstance();
DisplayImageOptions options;
public ExpandableAdapter(){
}
public ExpandableAdapter(Context context,List<String> parentList,
HashMap<String,List<Songs>> childList)
{
this.context=context;
this.parentList=parentList;
this.childList=childList;
options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher)
.showImageOnFail(R.drawable.ic_launcher)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
.defaultDisplayImageOptions(options)
.build();
imageLoader.getInstance().init(config);
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return this.parentList.size();
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return this.childList.get(this.parentList.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return this.parentList.get(groupPosition);
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return this.childList.get(this.parentList.get(groupPosition)).get(childPosition);
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.parent_item, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.tv_parent_item);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
ExpandableListView eLV = (ExpandableListView) parent;
eLV.expandGroup(groupPosition);
return convertView;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Songs childText = (Songs) getChild(groupPosition, childPosition);
if(convertView==null)
{
LayoutInflater infalInflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.child_item , null);
}
TextView artist = (TextView) convertView.findViewById(R.id.tv_child_item1);
TextView song = (TextView) convertView.findViewById(R.id.tv_child_item2);
ImageView image = (ImageView) convertView.findViewById(R.id.iv_child_item);
artist.setText(childText.getArtist());
song.setText(childText.getSong());
String imgUrl=childText.getArtwork();
imageLoader.displayImage(imgUrl, image);
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
For Main Activity OnCreate() method:
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expListView = (ExpandableListView) findViewById(R.id.expandable_listview);
listParent = new ArrayList<String>();
listChild = new HashMap<String, List<Songs>>();
new GetData().execute();
listAdapter = new ExpandableAdapter(this, listParent, listChild);
expListView.setAdapter(listAdapter);
expListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
Toast.makeText(getApplicationContext(),
"Group Clicked " + listParent.get(groupPosition),
Toast.LENGTH_SHORT).show();
return false;
}
});
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
}
});
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
}
});
expListView.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Toast.makeText(
getApplicationContext(),
listParent.get(groupPosition)
+ " : "
+ listChild.get(
listParent.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT)
.show();
return false;
}
});
}
In Expandable List view xml used android:nestedScrollingEnabled="true"
I have a image button and a image view. I am trying to get a hover theme,like when the user clicks an item there will be a hover image over the item which means he checked the item. My xml:
layout1:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/fetchedImageObj"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:scaleType="centerInside"
android:src="#drawable/test"
android:background="#drawable/image_selector"
android:clickable="true"
android:padding="0dp"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/hoverImage"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:scaleType="centerInside"
android:src="#drawable/correct"
android:visibility="gone"/>
</RelativeLayout>
And this is my adapter where i am trying to do the task. But the problem whenerver i select a item and scrolls down it disappears or switch to other object
Adapter:
public class FetchItemAdapter extends BaseAdapter {
private Activity myContext;
private LayoutInflater inflater;
public FetchModel fetchModel;
private boolean check_click=false;
public FetchItemAdapter(Activity context,FetchModel fetchModel)
{
this.myContext=context;
inflater = context.getLayoutInflater();
this.fetchModel = fetchModel;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return this.fetchModel.images.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
private static class ViewHolder {
ImageButton fetchedImageObj;
ImageView selection;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
System.out.println("get View");
final ViewHolder viewHolder = new ViewHolder();
convertView = inflater.inflate(com.yolove.R.layout.fetched_images_row,null);
//viewHolder = new ViewHolder();
viewHolder.fetchedImageObj = (ImageButton) convertView.findViewById(com.yolove.R.id.fetchedImageObj);
viewHolder.selection=(ImageView)convertView.findViewById(com.yolove.R.id.hoverImage);
convertView.setTag(viewHolder);
ImageLoader.getInstance().displayImage(fetchModel.images.get(position).imageurl,viewHolder.fetchedImageObj);
viewHolder.fetchedImageObj.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(check_click==false)
{
viewHolder.selection.setVisibility(View.VISIBLE);
check_click=true;
}
else
{
viewHolder.selection.setVisibility(View.GONE);
check_click=false;
}
}
});
return convertView;
}
}
I have made my holder final to get the viewholder.selection object.
On my opinion you need to make a selector xml for your image background and set the image view visible in xml file.
I have an ExpandableListView with a checkbox next to group name and when expanded, child items with checkbox as well.
Let's suppose I have 4 groups with 50 childs. When a group is expanded, and I click on select all checkbox, everything works fine, all checkbox are selected and keep their state if I scroll.
But if I scroll untill the last child of the list, scrolling gets buggy after that ( scrolling to the top and then touching the screen to stop the scrolling doesn't work anymore), clicking on group doesn't work anymore too, untill I click on selectall checkbox again.
Clicking on a child checkbox does nothing, I must click on selectall checkbox for everything to work.
I changed Focusable state of the child checkbox, group checkbox and tried many ways, but I can not find a solution to this. Do you have an idea of where it is coming from?
public class ExpandableListAdapter extends BaseExpandableListAdapter {
LayoutInflater cinflater;
LayoutInflater ginflater;
ArrayList<Group> array;
Context context;
public ExpandableListAdapter(Context context, ArrayList<Group> array) {
super();
cinflater = LayoutInflater.from(context);
ginflater = LayoutInflater.from(context);
this.array = array;
this.context = context;
}
public class ChildViewHolder {
CheckBox contactcheckbox;
TextView name;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return array.get(groupPosition).getContacts().size();
}
private OnCheckedChangeListener contactchecklistener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton checkboxView, boolean isChecked) {
Contact contact = (Contact) checkboxView.getTag();
contact.setCheck(isChecked);
}
};
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
ChildViewHolder cholder;
if(convertView == null){
cholder = new ChildViewHolder();
convertView = cinflater.inflate(R.layout.childsitems, null);
cholder.name = (TextView) convertView.findViewById(R.id.childnametextview);
cholder.contactcheckbox = (CheckBox) convertView.findViewById(R.id.childcheckbox);
cholder.contactcheckbox.setOnCheckedChangeListener(contactchecklistener);
convertView.setTag(cholder);
}else{
cholder = (ChildViewHolder) convertView.getTag();
}
cholder.contactcheckbox.setTag(array.get(groupPosition).getContacts().get(childPosition));
cholder.contactcheckbox.setChecked(array.get(groupPosition).getContacts().get(childPosition).isCheck());
cholder.name.setText(array.get(groupPosition).getContacts().get(childPosition).getName());
return convertView;
}
public class GroupViewHolder {
TextView groupname;
CheckBox groupcheck;
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return array.size();
}
private OnCheckedChangeListener groupchecklistener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int index = (Integer) buttonView.getTag();
for(int i = 0;i<array.get(index).getContacts().size();i++){
array.get(index).getContacts().get(i).setCheck(isChecked);
}
array.get(index).setCheck(isChecked);
notifyDataSetChanged();
}
};
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
GroupViewHolder gholder;
if(convertView==null){
gholder = new GroupViewHolder();
convertView = ginflater.inflate(R.layout.groupsitems,null);
gholder.groupname = (TextView)convertView.findViewById(R.id.groupnametextview);
gholder.groupcheckbox = (CheckBox)convertView.findViewById(R.id.groupcheckbox);
gholder.groupcheckbox.setOnCheckedChangeListener(groupchecklistener);
convertView.setTag(gholder);
}else{
gholder = (GroupViewHolder)convertView.getTag();
}
gholder.groupname.setText(array.get(groupPosition).getGroupname());
gholder.groupname.setTextSize(24);
gholder.groupname.setTextColor(Color.parseColor("#FF858585"));
gholder.groupname.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
int paddingleft = 48; // 38 dps
final float scale = getResources().getDisplayMetrics().density;
int dpvalue = (int) (paddingleft * scale + 0.5f);
gholder.groupname.setPadding(dpvalue, 16, 0, 16);
gholder.groupcheckbox.setTag(groupPosition);
gholder.groupcheckbox.setChecked(array.get(groupPosition).isCheck());
if(isExpanded == true){
convertView.setBackgroundDrawable(getResources().getDrawable(R.drawable.expandedbackground));
}else{
convertView.setBackgroundColor(Color.TRANSPARENT);
}
return convertView;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return 0;
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return null;
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return false;
}
}
groupsitems.xml :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<CheckBox
android:id="#+id/groupcheckbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="12dp"
android:focusable="false"
android:gravity="right|center"
android:paddingRight="10dp" />
<TextView
android:id="#+id/groupnametextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/groupcheckbox"
android:focusableInTouchMode="false"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#FF858585"
android:textStyle="bold" />
</RelativeLayout>
childitems.xml :
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:paddingLeft="8dp" >
<TextView
android:id="#+id/childnametextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/childcheckbox"
android:gravity="right|center"
android:paddingLeft="16dp"
android:textColor="#FFAFAFAF"
android:textSize="16sp"
android:textStyle="bold" />
<CheckBox
android:id="#+id/childcheckbox"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" />
</RelativeLayout>
I've found the solution. Instead of using OnCheckedChangeListener on the groupcheckbox, I used OnClickListener and it solved everything like this :
gholder.groupcheckbox.setChecked(array.get(groupPosition).isCheck());
gholder.groupcheckbox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0;i<array.get(groupPosition).getContacts().size();i++){
array.get(groupPosition).getContacts().get(i).setCheck(gholder.groupcheckbox.isChecked());
}
array.get(groupPosition).setCheck(gholder.groupcheck.isChecked());
notifyDataSetChanged();
}
});
I can't for the life of me figure out why my ExpandableListView doesn't expand... I have used log statements in just about every click listener I can find for the ExpandableListView and it doesnt look like any of them get called.
I know there are many posts on this topic but I have read through them all and tried many things and am having no luck, hopefully I'm missing some tiny error that will be easy to spot for someone else.
Main Activity:
public class ForumListActivity extends Activity {
private static ArrayList<Forum> forumList;
private static ArrayList<ArrayList<SubForum>> subForumList;
private ExpandableListView forumListView;
private ForumListAdapter forumListAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main_page);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
forumListView = (ExpandableListView) this.findViewById(R.id.main_page_forum_list);
forumList = new ArrayList<Forum>();
subForumList = new ArrayList<ArrayList<SubForum>>();
setUpForums(this);
forumListAdapter = new ForumListAdapter(this, forumList, subForumList);
forumListView.setAdapter(forumListAdapter);
forumListView.setOnGroupExpandListener(new OnGroupExpandListener(){
#Override
public void onGroupExpand(int groupPosition) {
Log.d("onGroupExpand", "this works?");
for(int i=0; i<forumListAdapter.getGroupCount(); i++) {
if(i != groupPosition)
forumListView.collapseGroup(groupPosition);
}
}
});
forumListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Log.d("onGroupClick:", "worked");
parent.expandGroup(groupPosition);
return true;
}
});
}
Note: the method setUpForums() just takes system arrays and puts them into forumList and subForumList
ListViewAdapter:
public class ForumListAdapter extends BaseExpandableListAdapter {
private ArrayList<Forum> groups;
private ArrayList<ArrayList<SubForum>> children;
private Context ctx;
public ForumListAdapter(Context ctx, ArrayList<Forum> groups, ArrayList<ArrayList<SubForum>> children) {
this.ctx = ctx;
this.groups = groups;
this.children = children;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return children.get(groupPosition).get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(ctx);
convertView = inflater.inflate(R.layout.forum_list_child_item_row, null);
}
SubForum currentSubForum = children.get(groupPosition).get(childPosition);
TextView name = (TextView)convertView.findViewById(R.id.child_row_forum_title);
TextView desc = (TextView)convertView.findViewById(R.id.child_row_forum_description);
if (name != null)
name.setText(currentSubForum.getName());
if (desc != null)
desc.setText(currentSubForum.getDescription());
convertView.setFocusableInTouchMode(true);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return children.get(groupPosition).size();
}
#Override
public Object getGroup(int groupPosition) {
return groups.get(groupPosition);
}
#Override
public int getGroupCount() {
return groups.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null)
{
LayoutInflater inflater = LayoutInflater.from(ctx);
convertView = inflater.inflate(R.layout.forum_list_group_item_row, null);
}
Forum currentForum = (Forum) groups.get(groupPosition);
TextView name = (TextView) convertView.findViewById(R.id.group_item_forum_title);
//ImageView image = (ImageView) convertView.findViewById(R.id.group_item_expander_image);
if(name != null)
name.setText(currentForum.getName());
/*
if(image != null) {
int[][] group_state_sets = {{}, {android.R.attr.state_expanded}};
image.setVisibility(View.VISIBLE);
int stateSetIndex = (isExpanded ? 1 : 0) ;
Drawable drawable = image.getDrawable();
drawable.setState(group_state_sets[stateSetIndex]);
}
*/
return convertView;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
Group Layout:
<?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="fill_parent"
android:background="#drawable/turquoise_gradient"
android:orientation="horizontal"
android:paddingTop="6dip"
android:paddingBottom="6dip"
android:paddingLeft="6dip" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/turquoise_gradient"
android:orientation="vertical"
android:padding="2dip" >
<TextView
android:id="#+id/group_item_forum_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:gravity="left"
android:paddingLeft="5dip"
android:textColor="#color/white"
android:textSize="16dip" />
</LinearLayout>
<!--
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center|right">
<ImageView
android:id="#+id/group_item_expander_image"
android:focusable="false"
android:focusableInTouchMode="false"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="#drawable/collapse_down" />
</LinearLayout> -->
</LinearLayout>
child layout:
<?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="fill_parent"
android:background="#drawable/turquoise_gradient"
android:orientation="horizontal"
android:paddingTop="6dip"
android:paddingBottom="6dip"
android:paddingLeft="6dip" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="2dip"
android:background="#drawable/turquoise_gradient" >
<TextView
android:id="#+id/child_row_forum_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_gravity="center_vertical"
android:paddingLeft="5dip"
android:textColor="#color/white"
android:maxLines="1"
android:textSize="11dip" />
<TextView
android:id="#+id/child_row_forum_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_gravity="center_vertical"
android:paddingLeft="15dip"
android:textColor="#color/white"
android:maxLines="2"
android:textSize="11dip" />
</LinearLayout>
</LinearLayout>
main page layout:
<?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="fill_parent"
android:background="#color/black"
android:orientation="vertical" >
<ExpandableListView
android:id="#+id/main_page_forum_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/black"
android:divider="#color/black"
android:dividerHeight="1dip"
android:clickable="true" />
</LinearLayout>
Any help you can provide is greatly appreciated!
I've also encountered similar problem like you. After a couple of days of investigation, I found that I did something wrong. So I fixed it to work correctly by making small change.
Let's look at the body of boolean onGroupClick(...) in setOnGroupClickListener. You've returned true that means "the click was handled"
You should return false if you want to expand. So I suggest you to do like this :
forumListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Log.d("onGroupClick:", "worked");
parent.expandGroup(groupPosition);
return false;
}
});
in android.widget.ExpandableListView class, there is a method named boolean handleItemClick(View v, int position, long id) which is responsible for expanding/collapsing groups or passing on the click to the proper child.
/* It's a group click, so pass on event */
if (mOnGroupClickListener != null) {
if (mOnGroupClickListener.onGroupClick(this, v,
posMetadata.position.groupPos, id)) {
posMetadata.recycle();
return true;
}
}
/* expanding/collapsing/other tasks... */
if you implement onGroupClick to return true, the the code below 8th line will never be executed. (that means, groups will never be collapsed, expanded)
Hope my answer helped you :-) good luck!
In case you have a widget on your list item, such as a Button, you may have to add android:focusable="false" to it. The Button was not allowing my list item to be clicked. That was the issue in my case.
There are probably three things u need to check,
check if u have any data available for the chid, cos if u dont have any data the child will not appear at all.
2.try removing if condition check while you using layout inflaters
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(ctx);
convertView = inflater.inflate(R.layout.forum_list_child_item_row, null);
}
you need to also pass Viewgroup here
convertView = inflater.inflate(R.layout.forum_list_child_item_row,parent, false);
I know this was already answered, but try setting the base layout of whatever you're inflating to have the attribute:
android:descendantFocusability="blocksDescendants"
If your expandable listview parent has button or switch it doesn't get called i wasted whole day in this.
So just use below code
android:focusable="false"
android:focusableInTouchMode="false"
Add this code inside toggle button,switch button or any which is on expandable listview
Make sure your custom group layout does not have android:textIsSelectable="false" as "true", if the text in textview is set to selectable, the expandable listview would expand in gingerbread but not in jellybean and might not work in ICS too.
I had a similar problem and it was solved by removing the android:clickable="true" property from ExpandableListView on xml.
When you are working with expandable lists then group expand is default functionality in it . means that group will expand itself only when you click on it you donot need to overrirde onGroupExpand(int groupPosition) or any other method just simply populate your data into your list somthing like this:
public class MyActivity extends Activity {
private ExpandableListView forumListView;
private ForumListAdapter forumListAdapter;
String[] forumList={"group 1","group 2","group 3"};
String[][] subForumList={{"group 1 child1","group 1 child1","group 1 child3"},
{"group 2 child1","group 2 child2","group 2 child3"},
{"group 3 child1","group 3 child2","group 3 child3"},
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.main);
forumListView = (ExpandableListView) this.findViewById(R.id.main_page_forum_list);
forumListAdapter = new ForumListAdapter(this, forumList, subForumList);
forumListView.setAdapter(forumListAdapter);
/* forumListView.setOnGroupExpandListener(new OnGroupExpandListener(){
public void onGroupExpand(int groupPosition) {
Log.d("onGroupExpand", "this shit works?");
for(int i=0; i<forumListAdapter.getGroupCount(); i++) {
if(i != groupPosition)
forumListView.collapseGroup(groupPosition);
}
}
});
forumListView.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
Log.d("onGroupClick:", "worked");
parent.expandGroup(groupPosition);
return true;
}
});*/
}
public class ForumListAdapter extends BaseExpandableListAdapter {
String[] groups;
String[][] children;
private Context ctx;
public ForumListAdapter(Context ctx, String[] groups, String[][] children) {
this.ctx = ctx;
this.groups = groups;
this.children = children;
}
public Object getChild(int arg0, int arg1) {
// TODO Auto-generated method stub
return children[arg0][arg1];
}
public long getChildId(int arg0, int arg1) {
// TODO Auto-generated method stub
return arg1;
}
public View getChildView(int arg0, int arg1, boolean arg2, View arg3,
ViewGroup arg4) {
if (arg3 == null) {
LayoutInflater inflater = LayoutInflater.from(ctx);
arg3 = inflater.inflate(R.layout.child, null);
}
String childData = children[arg0][arg1];
TextView name = (TextView)arg3.findViewById(R.id.child_row_forum_title);
TextView desc = (TextView)arg3.findViewById(R.id.child_row_forum_description);
if (name != null)
name.setText(childData);
if (desc != null)
// desc.setText(currentSubForum.getDescription());
arg3.setFocusableInTouchMode(true);
return arg3;}
public int getChildrenCount(int arg0) {
// TODO Auto-generated method stub
return children[arg0].length;
}
public Object getGroup(int arg0) {
// TODO Auto-generated method stub
return groups[arg0];
}
public int getGroupCount() {
// TODO Auto-generated method stub
return groups.length;
}
public long getGroupId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
public View getGroupView(int arg0, boolean arg1, View arg2, ViewGroup arg3) {
if (arg2 == null)
{
LayoutInflater inflater = LayoutInflater.from(ctx);
arg2 = inflater.inflate(R.layout.group, null);
}
TextView name = (TextView) arg2.findViewById(R.id.group_item_forum_title);
//ImageView image = (ImageView) arg2.findViewById(R.id.group_item_expander_image);
if(name != null)
name.setText(groups[arg0]);
/*
if(image != null) {
int[][] group_state_sets = {{}, {android.R.attr.state_expanded}};
image.setVisibility(View.VISIBLE);
int stateSetIndex = (isExpanded ? 1 : 0) ;
Drawable drawable = image.getDrawable();
drawable.setState(group_state_sets[stateSetIndex]);
}
*/
return arg2;}
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
public boolean isChildSelectable(int arg0, int arg1) {
// TODO Auto-generated method stub
return false;
}
}
}
forumListView.collapseGroup(groupPosition);
should be
forumListView.collapseGroup(i);
Add implements OnGroupExpandListener to your Activity. Then It will works. I am Using same it works fine.
In my case I had buttons in group and child views and even setting android:focusable="false"
android:focusableInTouchMode="false" on both it didn't work.
So I had to change them from ImageButton to ImageView. The listeners for the clicks are the same. You might need to create a custom background to give the touch animation for the ImageView.
I am implementing Expandable List view in android and i am getting the above titled error. Please help me.
Main activity is -
package com.expand;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;
public class MyExpandableListViewActivity extends Activity {
/** Called when the activity is first created. */
static final String groupElements[]= {
"India",
"Australia",
"England",
"South Africa"
};
static final String[][] childElements=
{
{
"Sachin Tendulkar",
"Raina",
"Dhoni",
"Yuvi"
},
{
"Ponting",
"Adam Gilchrist",
"Michael Clarke"
},
{
"Andrew Strauss",
"kevin Peterson",
"Nasser Hussain"
},
{
"Graeme Smith",
"AB de villiers",
"Jacques Kallis"
}
};
DisplayMetrics metrics;
int width;
ExpandableListView expandList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
expandList = (ExpandableListView)findViewById(R.id.expandList1);
metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
width = metrics.widthPixels;
//ExpAdapter adapter = new ExpAdapter(MyExpandableListViewActivity.this, groupElements, childElements);
expandList.setAdapter(new ExpAdapter(MyExpandableListViewActivity.this, groupElements, childElements));
expandList.setIndicatorBounds(width - GetDipsFromPixel(50), width - GetDipsFromPixel(10));
expandList.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
// TODO Auto-generated method stub
Log.e("onGroupExpand", "OK");
}
});
expandList.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
// TODO Auto-generated method stub
Log.e("onGroupCollapse", "OK");
}
});
expandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
//getting the item that is selected
//String s = (String) expandList.getItemAtPosition((int) id);
Toast.makeText(MyExpandableListViewActivity.this, "You have selected :" , Toast.LENGTH_SHORT).show();
return false;
}
});
}
public int GetDipsFromPixel(float pixels)
{
// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
return (int) (pixels * scale + 0.5f);
}
}
ExpAdapter class is -
I have implemented the adapter in other class and have called it in mt main activity
package com.expand;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;
public class ExpAdapter extends BaseExpandableListAdapter {
public Context myContext;
public String[][] childElements;
TextView childValues;
public String[] groupElements;
public ExpAdapter(Context context, String[] group, String[][] childs)
{
this.myContext=context;
this.groupElements = group;
this.childElements = childs;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childElements[groupPosition][childPosition];
}
#Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
LayoutInflater inflator = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflator.inflate(R.layout.child_rows, parent);
}
childValues = (TextView)convertView.findViewById(R.id.rowValues);
childValues.setText(childElements[groupPosition][childPosition]);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return groupElements[groupPosition].length();
}
#Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groupElements[groupPosition];
}
#Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groupElements.length;
}
#Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if(convertView==null){
LayoutInflater inflator = (LayoutInflater)myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflator.inflate(R.layout.group_rows, null);
}
TextView group = (TextView)convertView.findViewById(R.id.groupId);
group.setText(groupElements[groupPosition]);
return convertView;
}
#Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
main.xml-
this is the xnl that is displayed at the first by the main activity
<?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="fill_parent"
android:orientation="vertical" >
<ExpandableListView
android:id="#+id/expandList1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</TextView>
</ExpandableListView>
</LinearLayout>
group_row.xml
this is the xml for the group elements
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gropu_name"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:orientation="vertical" >
<TextView
android:id="#+id/groupId"
android:layout_height="40dp"
android:layout_width="wrap_content"
android:paddingLeft="30dp"
android:gravity="center_vertical"
android:textSize="16dp"
android:textStyle="bold"
/>
</LinearLayout>
child_row.xml
this is the xml for the child elements
<?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="40dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/rowValues"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:gravity="center_vertical"
android:paddingLeft="50dp"
android:textSize="12dp" />
</LinearLayout>
Seems like Adapterview does not allow adding new view,
I encountered same problem
Solve it by replacing following line
convertView = inflator.inflate(R.layout.child_rows, parent);
to
convertView = inflator.inflate(R.layout.child_rows, null);
UPDATE
Instead of not using a parent at all, you should simply tell the Inflater not to attach the inflated view to the parent with
convertView = inflator.inflate(R.layout.child_rows, parent, false);
See also this answer.
The reason is that adapter takes care of attaching views to parent itself.
Note that you can also get this error when your layout xml is invalid.
As were noted above,
Instead of not using a parent at all, you should simply tell the
Inflater not to attach the inflated view to the parent with
convertView = inflator.inflate(R.layout.child_rows, parent, false);
See also this answer.
The reason is that adapter takes care of attaching views to parent itself.
According to Android Lint your child view should always provide a reference to its parent view when inflated. I had the exact same error in my code. Is was occurring because the TextView was placed inside the ExpandableListView. When I rearranged my xml layout the error stopped appearing.
This error can also be caused because of instant run feature. I was working on listview and because of this error app kept crashing. Uninstalling the app and running again resolved the error.