transferAvailPowered.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_margin="5dp"
android:padding="5dp"
android:gravity="left">
<TextView
android:id="#+id/availSerial"
android:layout_width="0dp"
android:layout_weight=".30"
android:layout_height="wrap_content"
android:layout_marginLeft="45dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:focusable="false"
android:padding="5dp"
android:gravity="left" />
<TextView
android:id="#+id/availModel"
android:layout_width="0dp"
android:layout_weight=".30"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:focusable="false"
android:padding="5dp"
android:gravity="left" />
<AutoCompleteTextView
android:id="#+id/availSite"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:padding="5dp"
android:hint="To Site"
android:background="#android:color/white"
android:textColor="#android:color/black"
android:textCursorDrawable="#null"
android:focusable="false"
android:layout_margin="5dp"
android:gravity="left" />
<ImageButton
android:id="#+id/addToTransfer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_margin="5dp"
android:background="#drawable/addsmall"
android:focusable="false"
android:gravity="left" />
transferAvailAttached.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_margin="5dp"
android:padding="5dp">
<TextView
android:id="#+id/availSerial"
android:layout_width="0dp"
android:layout_weight=".30"
android:focusable="false"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:padding="5dp"
android:gravity="right" />
<TextView
android:id="#+id/availModel"
android:layout_width="0dp"
android:layout_weight=".30"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_margin="5dp"
android:padding="5dp"
android:gravity="center" />
<CheckBox
android:id="#+id/include"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left|center_vertical"
android:focusable="false"
android:layout_marginRight="30dp"
android:background="#drawable/bg_checkbox" />
<ImageButton
android:id="#+id/removeAttachment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:padding="5dp"
android:layout_margin="5dp"
android:background="#drawable/deletesmall"
android:gravity="right" />
Adapter
class EquipAdapter : BaseExpandableListAdapter
{
private List<CPEquipment> Parent { get; set; }
private List<List<CPEquipment>> Child { get; set; }
private Context _context { get; set; }
private IListAdapter _adapter { get; set; }
private ExpandableListView _list { get; set; }
public EquipAdapter(Context context, List<CPEquipment> parent, List<List<CPEquipment>> child, IListAdapter adapter, ExpandableListView list)
{
_context = context;
Parent = parent;
Child = child;
_adapter = adapter;
_list = list;
}
public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
{
List<CPEquipment> level1 = Child.ElementAt(groupPosition);
CPEquipment level2 = level1.ElementAt(childPosition);
E e = new E() {Serial = level2.Serial, Model = level2.Model};
return e;
}
public override long GetChildId(int groupPosition, int childPosition)
{
return Convert.ToInt32(groupPosition.ToString(CultureInfo.InvariantCulture) + childPosition.ToString(CultureInfo.InvariantCulture));
}
public override int GetChildrenCount(int groupPosition)
{
return Child.ElementAt(groupPosition).Count;
}
public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
convertView = inflater.Inflate(Resource.Layout.transferAvailAttached, null);
}
E e = (E)GetChild(groupPosition, childPosition);
TextView serial = (TextView)convertView.FindViewById(Resource.Id.availSerial);
serial.Text = e.Serial;
TextView model = (TextView)convertView.FindViewById(Resource.Id.availModel);
model.Text = e.Model;
return convertView;
}
public override Object GetGroup(int groupPosition)
{
CPEquipment c = Parent.ElementAt(groupPosition);
E e = new E(){Serial = c.Serial, Model = c.Model, Type = c.Status};
return e;
}
public override long GetGroupId(int groupPosition)
{
return groupPosition;
}
public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
{
E e = (E)GetGroup(groupPosition);
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
convertView = inflater.Inflate(Resource.Layout.transferAvailPowered, null);
}
TextView serial = (TextView)convertView.FindViewById(Resource.Id.availSerial);
serial.Text = e.Serial;
TextView model = (TextView)convertView.FindViewById(Resource.Id.availModel);
model.Text = e.Model;
AutoCompleteTextView acText = (AutoCompleteTextView)convertView.FindViewById(Resource.Id.availSite);
acText.Adapter = _adapter;
_list.ExpandGroup(groupPosition);
return convertView;
}
public override bool IsChildSelectable(int groupPosition, int childPosition)
{
return true;
}
public override int GroupCount
{
get { return Parent.Count; }
}
public override bool HasStableIds
{
get { return true; }
}
}
Outcome:
In this scenario, the AutoCompleteTextView in the parent group and the green plus button should be "selectable" so that the user can input the info into the field and click that button without collapsing the group. And the CheckBox and the red x button in the child should also be "selectable" so the user can check the CheckBox and click the button. The only part of that that actually works is that the CheckBox is selectable and the group doesn't collapse because for lack of a better term, the group layout is "dead" and does nothing when pressed. And the seemingly "working" CheckBox isn't even so because it does this weird thing where checking or unchecking one will randomly check or uncheck others.
Below code is to resolve checkbox problem "CheckBox isn't even so because it does this weird thing where checking or unchecking one will randomly check or uncheck others." Along with ImageButton and CheckBox handling.
public override View GetChildView(final int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
convertView = inflater.Inflate(Resource.Layout.transferAvailAttached, null);
E e = (E)GetChild(groupPosition, childPosition);
TextView serial = (TextView)convertView.FindViewById(Resource.Id.availSerial);
serial.Text = e.Serial;
TextView model = (TextView)convertView.FindViewById(Resource.Id.availModel);
model.Text = e.Model;
CheckBox include = (CheckBox)convertView.FindViewById(Resource.Id.include);
include.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
//DO your checkbox handling here
}
});
ImageButton removeAttachment =(CheckBox)convertView.FindViewById(Resource.Id. removeAttachment);
removeAttachment.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
//DO your imageButton handling here
}
});
return convertView;
}
public override View GetGroupView(final int groupPosition, bool isExpanded, View convertview, ViewGroup parent)
{
View convertView = convertview;
if (convertView == null)
{
E e = (E)GetGroup(groupPosition);
LayoutInflater inflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService);
convertView = inflater.Inflate(Resource.Layout.transferAvailPowered, null);
}
TextView serial = (TextView)convertView.FindViewById(Resource.Id.availSerial);
serial.Text = e.Serial;
TextView model = (TextView)convertView.FindViewById(Resource.Id.availModel);
model.Text = e.Model;
AutoCompleteTextView acText = (AutoCompleteTextView)convertView.FindViewById(Resource.Id.availSite);
acText.Adapter = _adapter;
ImageButton addToTransfer =(CheckBox)convertView.FindViewById(Resource.Id. addToTransfer);
addToTransfer.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
//DO your addToTransfer imageButton handling here
}
});
_list.ExpandGroup(groupPosition);
return convertView;
}
Related
I am able to retrieve data from SQLite database(to be precise 3 columns) and display them in Expandable Listview as Child(s). But I want to display them as:
Due date: 10/23/2016
late sub: YES
Penalty: 10%
Above, Left side text, I am displaying from Textview text(Child xml) and right side text after the colon, I am retrieving from database.
How do I handle this in getChildView method in my Adapter?
Here is my Adapter class code:
public class AssignmentDisplayAdapter extends BaseExpandableListAdapter{
private Context mContext;
private List<String> expandableListTitle;
private HashMap<String, List<CourseDisplay>> expandableListDetail;
private LayoutInflater mInflater;
public AssignmentDisplayAdapter(Context context, List<String> expandableListTitle,
HashMap<String, List<CourseDisplay>> expandableListDetail) {
this.mContext = context;
this.expandableListTitle = expandableListTitle;
this.expandableListDetail = expandableListDetail;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public Object getChild(int listPosition, int expandedListPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.get(expandedListPosition);
}
#Override
public long getChildId(int listPosition, int expandedListPosition) {
return expandedListPosition;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.custom_listview_expandable_child, null);
}
TextView expandedListTextView = (TextView) convertView
.findViewById(R.id.assign_duedate_display);
expandedListTextView.setText(expandedListText);
return convertView;
}
#Override
public int getChildrenCount(int listPosition) {
return this.expandableListDetail.get(this.expandableListTitle.get(listPosition))
.size();
}
#Override
public Object getGroup(int listPosition) {
return this.expandableListTitle.get(listPosition);
}
#Override
public int getGroupCount() {
return this.expandableListTitle.size();
}
#Override
public long getGroupId(int listPosition) {
return listPosition;
}
#Override
public View getGroupView(int listPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String listTitle = (String) getGroup(listPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.custom_listview_expandable_parent, null);
}
TextView listTitleTextView = (TextView) convertView
.findViewById(R.id.parent_text);
listTitleTextView.setTypeface(null, Typeface.BOLD);
listTitleTextView.setText(listTitle);
return convertView;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
}//end class
Here is my parent xml code:
<?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="match_parent">
<TextView
android:id="#+id/parent_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
android:textColor="#color/primary"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
</LinearLayout>
Here is my child xml code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/assign_duedatetext_display"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Due Date: "
android:layout_weight="3"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
<TextView
android:id="#+id/assign_duedate_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_toRightOf="#id/assign_duedatetext_display"
android:layout_marginLeft="16dp"
android:textColor="#color/primary"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/assign_latesubtext_display"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Late Submission: "
android:layout_weight="3"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
<TextView
android:id="#+id/assign_latesub_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_toRightOf="#id/assign_latesubtext_display"
android:layout_marginLeft="16dp"
android:textColor="#color/primary"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/assign_penaltytext_display"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:text="Penalty: "
android:layout_weight="3"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp"/>
<TextView
android:id="#+id/assign_penalty_display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_toRightOf="#id/assign_penaltytext_display"
android:layout_marginLeft="16dp"
android:textColor="#color/primary"
android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
android:paddingTop="10dp"
android:paddingBottom="10dp" />
</RelativeLayout>
</LinearLayout>
I believe something needs to be done in getChildView method but not sure how to handle this. Please guide me through this.
I am able to achieve this dynamically as I know the data format in the database is going to be the same for each parent.
Here is updated getChildView() Method:
#Override
public View getChildView(int listPosition, final int expandedListPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
String expandedListText = (String) getChild(listPosition, expandedListPosition);
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.custom_listview_expandable_child, null);
}
TextView expandedListTextView1 = (TextView) convertView
.findViewById(R.id.assign_duedate_display);
TextView expandedListTextView2 = (TextView) convertView
.findViewById(R.id.assign_duedatetext_display);
if (expandedListPosition == 0){
expandedListTextView2.setText("Due date: ");
}else if(expandedListPosition == 1){
expandedListTextView2.setText("late submission: ");
}else {
expandedListTextView2.setText("Penalty: ");
}
expandedListTextView1.setText(expandedListText);
return convertView;
}
In My expandable list view first child item has two buttons.button1 and button2.in other child list item has check box and text.these check boxes are default disabled
in first time user expand the child list and after press button1 i want to enable all check boxes in particular group
As this point i can only enable first child list item checkbox.how can enable all check boxes by clicking button on the 1st child item.
Expandable list adapter
public class ExpandListAdapter extends BaseExpandableListAdapter {
private Context context;
private ArrayList<ExpandableListGroup> groups;
public ExpandListAdapter(Context context, ArrayList<ExpandableListGroup> groups) {
this.context = context;
this.groups = groups;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
ArrayList<ExpandableListChild> chList = groups.get(groupPosition).getItems();
return chList.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(final int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final ExpandableListChild child = (ExpandableListChild) getChild(groupPosition, childPosition);
final ViewHolder holder;
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.btn_start_inspection = (Button) convertView.findViewById(R.id.btn_start_inspection);
holder.btn_complete_inspection = (Button) convertView.findViewById(R.id.btn_complete_inspection);
holder.cbx_complete_inspection = (CheckBox) convertView.findViewById(R.id.check_sub_task);
holder.txt_activity_name = (TextView) convertView.findViewById(R.id.txt_sub_task_title);
holder.txt_activity_name.setText(child.getName().toString());
//button for enable checkboxes
holder.btn_start_inspection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.btn_complete_inspection.setBackgroundColor(Color.RED);
holder.itemEnabled = true;
notifyDataSetChanged();
}
});
//enable check boxes
if(holder.itemEnabled == true){
holder.cbx_complete_inspection.setEnabled(true);
}else{
holder.cbx_complete_inspection.setEnabled(false);
}
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
ArrayList<ExpandableListChild> chList = groups.get(groupPosition).getItems();
return chList.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) {
ExpandableListGroup group = (ExpandableListGroup) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater inf = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
convertView = inf.inflate(R.layout.list_group, null);
}
TextView tv = (TextView) convertView.findViewById(R.id.txt_company_name);
tv.setText(group.getName());
TextView tvAddress = (TextView) convertView.findViewById(R.id.txt_company_address);
tvAddress.setText(group.getAddressLevel());
iv = (ImageView) convertView.findViewById(R.id.img_expand);
return convertView;
}
#Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
iv.setImageDrawable(context.getResources().getDrawable(R.drawable.exp_fold));
}
#Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
iv.setImageDrawable(context.getResources().getDrawable(R.drawable.exp_min));
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
static class ViewHolder {
Button btn_complete_inspection;
Button btn_start_inspection;
CheckBox cbx_complete_inspection;
TextView txt_activity_name;
boolean itemEnabled = false;
}
}
listchildItem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lnrChild"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/lnr_task"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="10dp">
<Button
android:id="#+id/btn_start_inspection"
android:layout_width="100dp"
android:layout_height="30dp"
android:layout_gravity="left"
android:layout_marginLeft="10dp"
android:background="#drawable/rounded_cornerexpandable_list_child"
android:gravity="center"
android:text="Start Inspection"
android:textAllCaps="false"
android:textColor="#color/color_white"
android:textSize="12sp"
></Button>
<Button
android:id="#+id/btn_complete_inspection"
android:layout_width="150dp"
android:layout_height="35dp"
android:layout_marginLeft="150dp"
android:src="#drawable/rounded_cornerexpandable_list_child_gray"
android:text="Complete Inspection"
android:textAllCaps="false"
android:textColor="#color/color_white"
android:textSize="12sp"
></Button>
<LinearLayout
android:id="#+id/lnr_active_sub_task"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#+id/btn_complete_inspection">
<LinearLayout
android:id="#+id/lnr_sub_task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dp"
android:gravity="center"
android:orientation="horizontal">
<CheckBox
android:id="#+id/check_sub_task"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:checked="false"
android:gravity="center"></CheckBox>
</LinearLayout>
<LinearLayout
android:id="#+id/textHolder"
android:layout_width="0.0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="left"
android:orientation="horizontal">
<TextView
android:id="#+id/txt_sub_task_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="exx"
android:textSize="15sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0.0dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="0.5"
android:gravity="right"
android:orientation="horizontal">
<ImageView
android:id="#+id/txt_sub_task_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_keyboard_arrow_right_black_24dp"
android:gravity="center"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
What I see is that after click button on 1st list item only 1st check box in the 1st child item is enabled, the other list item check boxes are not. What I want is that checkboxes in the child item rows are enabled. (extra lines added from comments)
I have no idea what's wrong with this code my onChildClickListener() is not called I have seen some answers in which they said override isChildSelected and return true; i tried that too but still it's not getting called. Can anybody help me in this. Any help would be appreciated. Thanks.
public class Expand {
Context context;
private RelativeLayout relativeLayout;
private String[] headerText;
String[] secondHeaderTitle;
int[] secondHeaderVisibilty;
String[][] drdatewise;
String[][] spec;
ExpandableListView listView;
ExampleAdapter adapter;
public TextView secondHeader;
public Expand(Context context, String headerText[],
String[] secondHeaderTitle, int[] secondHeaderVisibilty,
String[][] drdatewise, String[][] spec) {
this.context = context;
this.headerText = headerText;
this.secondHeaderTitle = secondHeaderTitle;
this.secondHeaderVisibilty = secondHeaderVisibilty;
secondHeader = new TextView(context);
this.drdatewise = drdatewise;
this.spec = spec;
}
public View GetView() {
List<GroupItem> items = new ArrayList<GroupItem>();
// Populate our list with groups and it's children
for (int i = 0; i < headerText.length; i++) {
GroupItem item = new GroupItem();
item.title = headerText[i];
for (int j = 0; j < drdatewise[i].length; j++) {
ChildItem child = new ChildItem();
child.title1String = drdatewise[i][j];
child.title2String = spec[i][j];
child.title3String = "Class A";
child.title4String = "Mumbai";
item.items.add(child);
}
items.add(item);
}
adapter = new ExampleAdapter(context);
adapter.setData(items);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
relativeLayout = (RelativeLayout) inflater.inflate(
R.layout.activity_main_gb, null);
listView = (ExpandableListView) relativeLayout
.findViewById(R.id.listView);
listView.setAdapter(adapter);
listView.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Toast.makeText(context, "Mine mine minemie n", Toast.LENGTH_SHORT).show();
return true;
}
});
return relativeLayout;
}
private class ExampleAdapter extends BaseExpandableListAdapter {
private LayoutInflater inflater;
private List<GroupItem> items;
View convertView;
public ExampleAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
public void setData(List<GroupItem> items) {
this.items = items;
}
#Override
public ChildItem getChild(int groupPosition, int childPosition) {
return items.get(groupPosition).items.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) {
ChildHolder holder;
ChildItem item = getChild(groupPosition, childPosition);
this.convertView = convertView;
if (convertView == null) {
holder = new ChildHolder();
convertView = inflater.inflate(R.layout.child_view_cal, parent,
false);
holder.title1 = (TextView) convertView
.findViewById(R.id.childtextview1);
holder.title2 = (TextView) convertView
.findViewById(R.id.childtextview2);
holder.title3 = (TextView) convertView
.findViewById(R.id.childtextview3);
holder.title4 = (TextView) convertView
.findViewById(R.id.childtextview4);
convertView.setTag(holder);
} else {
holder = (ChildHolder) convertView.getTag();
}
holder.title1.setText(item.title1String);
holder.title2.setText(item.title2String);
holder.title3.setText(item.title3String);
holder.title4.setText(item.title4String);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return items.get(groupPosition).items.size();
}
#Override
public GroupItem getGroup(int groupPosition) {
return items.get(groupPosition);
}
#Override
public int getGroupCount() {
return items.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
GroupHolder holder;
GroupItem item = getGroup(groupPosition);
if (convertView == null) {
holder = new GroupHolder();
convertView = inflater.inflate(R.layout.parent_view_cal,
parent, false);
holder.title = (TextView) convertView
.findViewById(R.id.headertextview);
holder.patches = (TextView) convertView
.findViewById(R.id.headertextview2223);
holder.count = (TextView) convertView
.findViewById(R.id.headertextview223);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
holder.title.setText(item.title);
int countD = getChildrenCount(groupPosition);
holder.count.setText("" + countD);
holder.patches.setText("1");
return convertView;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}
}
private static class GroupHolder {
TextView title;
TextView patches;
TextView count;
}
private static class GroupItem {
String title;
String secondHeaderTitle;
List<ChildItem> items = new ArrayList<ChildItem>();
}
private static class ChildItem {
String title1String;
String title2String;
String title3String;
String title4String;
}
private static class ChildHolder {
TextView title1;
TextView title2;
TextView title3;
TextView title4;
}
}
child view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:id="#+id/upperlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E3ECF5"
android:gravity="center_vertical"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:paddingTop="13dp" >
<ImageView
android:id="#+id/childImage"
android:layout_width="58dp"
android:layout_height="58dp"
android:layout_gravity="left"
android:src="#drawable/ic_account_box_black_48dp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:gravity="left"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingTop="10dp" >
<TextView
android:id="#+id/childtextview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Data1"
android:textColor="#424242"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="#+id/childtextview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Data2"
android:textColor="#424242"
android:textSize="16sp"
android:textStyle="normal" />
<TextView
android:id="#+id/childtextview3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Data3"
android:textColor="#424242"
android:textSize="14sp"
android:textStyle="normal" />
<TextView
android:id="#+id/childtextview4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Data4"
android:textColor="#424242"
android:textSize="14sp"
android:textStyle="normal" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:paddingTop="13dp" >
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:text="11:00" />
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_below="#+id/upperlayout"
android:background="#FFFFFF" />
</RelativeLayout>
It is possible that your ImageView and possibly TextViews in the child layout are intercepting the click events. In your XML, try adding android:focusable="false" to all those elements.
I have a system of nested ExpandableListViews that continue on for a few generations (a tree-type layout) for comments. Each top-level comment can have comments with children on those comments. To do so, I have a main ExpandableListView to store all the top level comments, and each "comment" XML contains an ExpandableListView for any child comments. The adapter for my ExpandableListView is as follows
public class ExpandableCommentAdapter extends BaseExpandableListAdapter {
private static final class ViewHolder {
TextView textLabel;
}
private final List<CommentNode> itemList;
private final LayoutInflater inflater;
private Context main;
public ExpandableCommentAdapter(Context context, List<CommentNode> itemList) {
this.inflater = LayoutInflater.from(context);
this.itemList = itemList;
main = context;
}
#Override
public CommentNode getChild(int groupPosition, int childPosition) {
CommentNode n = itemList.get(groupPosition);
ArrayList<CommentNode> comments = new ArrayList<CommentNode>();
for (CommentNode node : n.walkTree(TraversalMethod.BREADTH_FIRST)) {
if (node.getParent().getComment().getId() == n.getComment().getId()) {
comments.add(node);
}
}
Log.v("RedditSlide", "COMMENT CHILD SIZE:" + comments.size());
return comments.get(childPosition);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public int getChildrenCount(int groupPosition) {
CommentNode n = itemList.get(groupPosition);
ArrayList<CommentNode> comments = new ArrayList<CommentNode>();
CommentNode comment = n;
for (CommentNode node : comment.walkTree(TraversalMethod.BREADTH_FIRST)) {
if (node.getParent().getComment().getId() == comment.getComment().getId()) {
comments.add(node);
}
}
return comments.size();
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView,
final ViewGroup parent) {
final CommentNode user = getChild(groupPosition, childPosition);
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment, parent, false);
}
TextView author = (TextView) convertView.findViewById(R.id.author);
TextView comm = (TextView) convertView.findViewById(R.id.commentLine);
TextView upvote = (TextView) convertView.findViewById(R.id.upvotePost);
author.setText(user.getComment().getAuthor());
comm.setText(user.getComment().getBody());
upvote.setText(user.getComment().getScore() + "");
ArrayList<CommentNode> comments = new ArrayList<CommentNode>();
CommentNode comment = user;
for (CommentNode node : comment.walkTree(TraversalMethod.BREADTH_FIRST)) {
if (node.getParent().getComment().getId() == comment.getComment().getId()) {
comments.add(node);
}
}
ExpandableCommentAdapter adapter = new ExpandableCommentAdapter(convertView.getContext(), comments);
ExpandableListView listView = (ExpandableListView) convertView.findViewById(R.id.commentsListUnder);
listView.setAdapter(adapter);
return convertView;
}
#Override
public CommentNode getGroup(int groupPosition) {
return itemList.get(groupPosition);
}
#Override
public int getGroupCount() {
return itemList.size();
}
#Override
public long getGroupId(final int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
final CommentNode user = itemList.get(groupPosition);
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment, parent, false);
}
TextView author = (TextView) convertView.findViewById(R.id.author);
TextView comm = (TextView) convertView.findViewById(R.id.commentLine);
TextView upvote = (TextView) convertView.findViewById(R.id.upvotePost);
author.setText(user.getComment().getAuthor());
comm.setText(user.getComment().getBody());
upvote.setText(user.getComment().getScore() + "");
return convertView;
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
My Comment XML is as follows
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-20dp"
android:layout_marginRight="-20dp"
android:background="#ff2b2b2b"
android:orientation="vertical"
android:padding="20dp"
android:paddingBottom="0dp"
android:paddingEnd="0dp"
android:scrollbars="none">
<TextView
android:id="#+id/author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ccrama"
android:textSize="12dp" />
<TextView
android:id="#+id/commentLine"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="COMMENT"
android:textSize="14dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="-10dp"
android:orientation="horizontal">
<ImageView
android:id="#+id/upvote"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_margin="10dp"
android:background="#drawable/roundbutton"
android:onClick="upvote"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="#drawable/iconupvote"
/>
<ImageView
android:id="#+id/downvote"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="-7dp"
android:background="#drawable/roundbutton"
android:onClick="downvote"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="#drawable/icondownvote"
/>
<TextView
android:id="#+id/upvotePost"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="7dp"
android:text="30"
android:textSize="14dp" />
</LinearLayout>
<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/commentsListUnder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-20dp"
android:layout_marginLeft="-5dp"
android:layout_marginRight="-20dp"
android:background="#ff2b2b2b"
android:orientation="vertical" />
</LinearLayout>
The issue I'm having is the "expandableness" of the child comments seems to skip a generation. Level 1, Level 3, etc all have expansion and their children are visible, but Level 2 can't expand, and only one child is visible. Further children (4, 5, 6...) aren't visible, and Level 3 has an expanding icon but when tapped shows no children.
What am I doing wrong with my layout/system?
Thanks!
Your issues are two things. One you are attempting to nest scrollable views that scroll in the same direction. Android can not handle this situation correctly and you will get all sorts of crazy behavior. Attempting to "hack" around the issues will just cause all sorts of headaches.
The second issues is that you are embedding adapters within adapters. While this "could" work, it is really not recommended. There is no guarantee to how many times a getChildView or getParentView will be called for the same position number. Sometimes it's once. Sometimes it's twice. Heck it could be 4 times. Each time you'd be recreating a new adapter that in-turn will invoke it's getChildView or getParentView methods multiple times per position. To put simply, it's a major performance concern.
Your best solution is to rework a UX design that does not entail embedding ExpandableListViews and adapters.
I have an expandable listview. I have put some dummy data and evrything seems ok but when I run the application all groups are in collapse mode and they don't take effect when I click on each of them. This is the screenshot:
XML of Group is:
<?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="wrap_content"
android:background="#color/bg_slider"
android:orientation="horizontal" >
<TextView
android:id="#+id/tvRecipeName"
style="#style/normal_text.bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:layout_marginRight="5dp"
android:focusable="false"
android:lines="1"
android:maxLines="1"
android:text="#string/dd_title" />
<ImageButton
android:id="#+id/ibDeleteRecipe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:background="#color/transparent"
android:contentDescription="#string/cd"
android:focusable="false"
android:src="#android:drawable/ic_menu_delete" />
<View
android:layout_width="1dp"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/tvRecipeName"
android:focusable="false" />
</RelativeLayout>
XML of child is:
<?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="wrap_content"
android:background="#color/White"
android:gravity="left|center_vertical" >
<View
android:layout_width="1dp"
android:layout_height="35dp"
android:layout_toLeftOf="#+id/tvIngredient"
android:focusable="false" />
<TextView
android:id="#+id/tvIngredient"
style="#style/normal_text_black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="5dp"
android:lines="1"
android:maxLines="1"
android:text="#string/dd_title"
android:focusable="false" />
<ImageButton
android:id="#+id/ibDeleteIngredient"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:background="#color/transparent"
android:contentDescription="#string/cd"
android:focusable="false"
android:src="#android:drawable/btn_dialog" />
</RelativeLayout>
and in main.xml, definition of expandable list is:
<ExpandableListView
android:id="#+id/elv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
I have an adapter that I have written this code for that:
public class ExpAdapter extends BaseExpandableListAdapter {
private final String TAG = "ExpAdapter";
private Context context;
static final String arrGroupelements[] = {"India", "Australia", "England", "South Africa"};
static final String arrChildelements[][] = { {"Sachin Tendulkar", "Raina", "Dhoni", "Yuvi" },
{"Ponting", "Adam Gilchrist", "Michael Clarke"},
{"Andrew Strauss", "kevin Peterson", "Nasser Hussain"},
{"Graeme Smith", "AB de villiers", "Jacques Kallis"} };
public ExpAdapter(Context context) {
this.context = context;
Log.i(TAG, "Adapter created.");
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
#Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.elv_child, null);
}
TextView tvItem = (TextView) convertView.findViewById(R.id.tvIngredient);
ImageButton ibDelete = (ImageButton) convertView.findViewById(R.id.ibDeleteIngredient);
ibDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "******");
}
});
tvItem.setText(arrChildelements[groupPosition][childPosition]);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return arrChildelements[groupPosition].length;
}
#Override
public Object getGroup(int groupPosition) {
return null;
}
#Override
public int getGroupCount() {
return arrGroupelements.length;
}
#Override
public long getGroupId(int groupPosition) {
return 0;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.elv_group, null);
}
TextView tvItem = (TextView) convertView.findViewById(R.id.tvRecipeName);
ImageButton ibDeleteRcipe = (ImageButton) convertView.findViewById(R.id.ibDeleteRecipe);
ibDeleteRcipe.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "%%%%%%");
}
});
tvItem.setText(arrGroupelements[groupPosition]);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
and finally, in code of fragment activity i have:
public class ShoppingList extends FragmentActivity {
ExpAdapter adapter = new ExpAdapter(this);
//Linking expnadable list view
expListView = (ExpandableListView) findViewById(R.id.elv);
expListView.setAdapter(adapter);
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Log.i(TAG, "Group " + groupPosition + " expanded.");
}
});
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Log.i(TAG, "Group " + groupPosition + " collapsed.");
}
});
expListView.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Log.i(TAG, "item " + childPosition + " of group " + groupPosition + " clicked.");
return false;
}
});
}
When I run the application and click on parents, nothing happens. I tried to add following lines of code at the end of shopping class:
int count = adapter.getGroupCount();
for (int position = 1; position <= count; position++)
expListView.expandGroup(position - 1);
Now when I run the application result is like this screenshot:
If I click on delete buttons (parent or child), I can see they take effect (as I check logcat), however when I click on child or parent nothing happens. So, I have no idea why callbacks doesn't work. Based on my research I found that I need to set Focussable of image buttons to false. As you can see in XML files I did it but still when I click on parent and child rows I can't see any response.
Finally I found the solution :)
I have no idea is it bug or disease or ...
As mentioned above based on my research I found that we need to set focus-ability of image view/box to "false". I did it in XML file and it didn't work. I set focus-ability to "true" in XML and in code set it to false. like this:
#Override
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.elv_group, null);
}
TextView tvItem = (TextView) convertView.findViewById(R.id.tvRecipeName);
ImageButton ibDeleteRcipe = (ImageButton) convertView.findViewById(R.id.ibDeleteRecipe);
ibDeleteRcipe.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
...
}
});
ibDeleteRcipe.setFocusable(false);
tvItem.setText(arrGroupElements[groupPosition]);
return convertView;
}
Therefore based of my achievement! it should be set to "false" in code not in XML! Now the question is What is difference? -I have no idea.
It is necessary to define android:focusable="false" in the layout xml for focusable views within the expandable list view item but not in the "ExpandableListView" attribute.
Eg: if a custom parent list item includes a checkbox (it will automatically get the focus) it should be like below.
<CheckBox
android:id="#+id/cbkSelectDownload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"/>