Different icon to items in expandiblelistview - android

Is it possible to assign different icon to each item in a group? Can anyone show me an example? I would like a result like this:
Thank you.

From the API reference of ExpandableListAdapter:
getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent):
Gets a View that displays the data for the given child within the given group.
This is the method that returns the View of the child, which means you could write something like this in your ExpandableListAdapter:
#Override
public View getChildView(int gPos, int cPos, bool isLast, View view, ViewGroup parent){
if (view == null){
view = inflater.inflate(R.layout.whatever, null);
}
ImageView image = (ImageView) view.findViewById(R.id.image);
// This next part depends on how you store the images.
// You could store the imageID in an int[][]:
int imageID = carImages[gPos][cPos];
image.setImageResource(imageID);
// or you could store the drawable in a List<List<Drawable>>
Drawable d = carimages.get(gPos).get(cPos);
iamge.setImageDrawable(d);
// etc.
return view;
}
The point is that you have to store the images in a way that you can retreive the right image by providing which index the view has, and in which group it is in.
You could also store the image in a CarObject, and have a List<CarObject> in your adapter. But you would have to find a way to distinguish between the different brands.

Related

"onChildChildClick" three level expandable list view

It got me wondering on how to implement an "onChildChildClickListener" into this three level expandable list view after answering the question of how to populate three level expandable list view (Populate different arrays in third layer of expandableListView).
How does one implement the third level being Clickable?
Example code by BKN is published on githube here:
https://github.com/ngocchung/ThreeLevelExpListView
Does anybody have an idea?
Help would be gladly appreciated as I would like to implement this into an showcase app as a part of my Masterthesis.
Found the solution after reading the comments in this How to add Three Level ListView in ExpandableListView in android
this needs to be implemented in the ParentLevelAdapter in the public View getChildView part.
#Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final CustomExpListView secondLevelExpListView = new CustomExpListView(this.mContext);
String parentNode = (String) getGroup(groupPosition);
secondLevelExpListView.setAdapter(new SecondLevelAdapter(this.mContext, mListData_SecondLevel_Map.get(parentNode), mListData_ThirdLevel_Map));
secondLevelExpListView.setGroupIndicator(null);
//newcode
secondLevelExpListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener(){
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition,long id)
{ String selectText = ((TextView) v).getText().toString();
switch (selectText){
case "ItemName you want to do something with":
//Actions you want to do when clicking this item
break;
case "ItemName2 you want to do something with":
//Actions you want to do when clicking this second item
break;
default:
//default actions on all other items
}
return false;}
});
return secondLevelExpListView;
}

button image drawn at random upon button click in the group in the expandlistview

I have an expandlistview in which I have included a button on the the group. When I click on the button, it is supposed to save the data associated with the button and also it has to redraw the button, based on the value of the button. The issue I am having is that it is not only redrawing itself but also it is redrawing some other buttons. It is quite difficult to understand and explain what is happening as it seems to redraw any button it at random. Please note that the save part is working correctly.
Can anyone tell me, what could be wrong with the piece of code below. The only thing I want to achieve is redraw the button that is being clicked only and not any other button in the expandlistview.
groupHolder.Favourite.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
String itemKey = Holder.Favourite.getTag().toString();
Boolean starred = Client.data.get(itemKey.toLowerCase());
Client.writeStarred(view.getContext(), itemKey.toLowerCase(), starred);
if (starred)
((ImageButton) view).setImageDrawable(view.getContext().getResources().getDrawable(R.drawable.ic_cat_star_yellow));
else
((ImageButton) view).setImageDrawable(view.getContext().getResources().getDrawable(R.drawable.ic_cat_star));
}
});
Part of the getGroupView
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupViewHolder Holder;
final GroupEvent group = (GroupEvent) getGroup(groupPosition);
if (group.Starred)
Holder.Favourite.setImageDrawable(convertView.getContext().getResources().getDrawable(R.drawable.ic_cat_star_yellow));
});
I have changed the code to the following to add notifyDataSetChanged(); , but this too does not seem to work.
groupHolder.ButtonFavourite.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
String itemKey = gpHolder.ButtonFavourite.getTag().toString();
Boolean starred = Client.data.get(itemKey.toLowerCase());
Client.writeStarred(view.getContext(), itemKey.toLowerCase(), starred);
notifyDataSetChanged();
}
});
The view is redrawing buttons at random due to view recycling.
For adapter views, the event handlers should be used to update model state and getView() [or for ExpandableListView, getGroupView() and getChildView()] should render the views based on that state.
In getGroupView(), check the starred flag for the item and set your image drawable accordingly.
Make sure you treat your view as "dirty" since it may be recycled and explicitly set the image drawable value every time:
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
GroupViewHolder Holder;
final GroupEvent group = (GroupEvent) getGroup(groupPosition);
...
Holder.Favourite.setImageDrawable(convertView.getContext().getResources().getDrawable(
group.Starred ? R.drawable.ic_cat_star_yellow : R.drawable.ic_cat_star));
}

Adapter getView() method getting called when I set the adapter of my GridView in one my place but not when I set it in another

Basically I have 2 Views that both use an Adapter to populate.
An ExpandableListView. ExpandableListView gridHostList;
A custom View that works very similarly to GridView (it's called StaggeredGridView) StaggeredGridView grid;
Their Adapters in order:
HostListAdapter which inherits from BaseExpandableListAdapter.
GridAdapter which inherits from BaseAdapter.
The reason for this is I need an expandable list with varying numbers of parents or groups where each group contains a grid that also has a varying number of children. I looked into many ways of achieving this and I think this is the best but I am open to alternatives.
In the getChildView() method of HostListAdapter I make my grid and this works fine.
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.layout_containing_grid, null);
StaggeredGridView gridView = (StaggeredGridView) convertView.findViewById(R.id.grid_view);
}
Now when I set the adapter of my StaggeredGridView here as shown below everything works as expected.
#Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.layout_containing_grid, null);
StaggeredGridView gridView = (StaggeredGridView) convertView.findViewById(R.id.grid_view);
gridView.setAdapter(mGridAdapter);
}
That works fine. However I want to set the adapter from the Fragment which contains all of this (it's in a ViewPager). To do this I store the view returned by the hostListAdapter in a Hashmap with the Hashmap key being a Class I made that contains an ArrayList.
gridHostList = (GridHostList) V.findViewById(R.id.gridHostList);
if (!gridsHashMap.containsKey(dataForThisGrid)) {
gridsHashMap.put(dataForThisGrid, getGrid(0, gridsHashMap.get(dataForThisGrid)));
StaggeredGridView gridView = (StaggeredGridView) gridsHashMap.get(dataForThisGrid).findViewById(R.id.grid_view);
if (gridView.getAdapter() == null) {
gridView.setAdapter(new GridAdapter(context);
}
private View getGrid(int groupPosition, View convertView) {
View v;
v = gridHostList.getExpandableListAdapter().getChildView(groupPosition, 0, true, convertView, gridHostList);
return v;
}
}
I've tried this without any of the fancy HashMap stuff or logic of any kind to check if that was the problem and found nothing. I know I am actually getting a View from the parent adapter. gridAdapter.getCount() is being called by the system and returning a positive int as it should. However the problem seems to come because for some reason gridAdapter.getView is never called.
So what I am trying to figure out is why gridAdapter.getView is called when I set it in the hostListAdapter, but not when I set it in the Fragment which contains this all.
Please forgive minor errors in the code here, I made many changes in the StackOverflow editor (mostly removing logs and changing names for clarity). Thanks for your time.
In your getGrid method you are getting the StaggeredGridView and you are adding it to the gridsHashMap with the key dataForThisGrid . But when you are retrieving it from the gridsHashMap you are doing it as (StaggeredGridView) gridsHashMap.get(dataForThisGrid).findViewById(R.id.grid_view);.
I think you have to retrieve it using just
(StaggeredGridView) gridsHashMap.get(dataForThisGrid);
Note: I have seen people advising not to call the getView or getChildView method directly as calling them will result in inflating the respective view.

how to get view of group in expandablelistview in android?

im blazilian so, my english is not good.
So.. i need get view of group in expandablelistview for get your object tag throught view.getTag() method.
follow me in this example:
ExpandableListView
--> group (i need this view)
----> child
----> child
----> child
--> group (i need this view)
----> child
----> child
My code:
#Override
public boolean onChildClick(final ExpandableListView parent, final View v,
final int groupPosition, final int childPosition, final long id) {
/* I NEED GET VIEW OF GROUP FOR GET YOUR TAG*/
View vParent = parent.getChildAt(groupPosition); // dont work after first group
Programa v2 = (Programa) parent.getTag(); // return null
// v parameter is a child of group
return true;
}
in my adapter:
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TwoLineListItem view = (TwoLineListItem) LayoutInflater.from(contexto)
.inflate(android.R.layout.simple_expandable_list_item_2,
parent, false);
String programa = map.keySet().toArray(new String[map.keySet().size()])[groupPosition];
view.getText1().setText(programa);
view.getText2().setText("PROGRAMA LOCAL");
view.setTag(programas.get(groupPosition)); // i need get this in child click listener
return convertView = view;
}
any idea? thanks
To get the group view from an ExpandableListView, you do something as follows:
public View getGroupView(ExpandableListView listView, int groupPosition) {
long packedPosition = ExpandableListView.getPackedPositionForGroup(groupPosition);
int flatPosition = listView.getFlatListPosition(packedPosition);
int first = listView.getFirstVisiblePosition();
return listView.getChildAt(flatPosition - first);
}
If your code is correct, you want to get the group view for the child so that you can call getTag() on it, correct?
If so, why not just skip that step and access the value of the tag, set by programas.get(groupPosition) manually?
You can do this by calling:
programas.get(groupPosition) right on the top of your onChildClick method since you get the group position value there too.
Edit in response to your comment:
The issue here is that you're not going to be able to get the view of the group through the adapter since it might involve recreating the view due to recycling of views in lists. If this method doesn't work, I strongly suggest modifying your code to make it work.
If programas is one of the inputs to your adapter, then call getGroup(groupPosition) on your adapter to access it. Else, make a public method in your adapter class to allow retrieval of that value.
I tried AedonEtLIRA answer but it only obtained the first item in the list.
My solution was to set a tag in my adapter's getGroupView method.
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater layoutInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = layoutInflater.inflate(R.layout.listitem_group, null);
}
//This is your data object that you might be using for storage that can be returned by your getGroup(groupPosition) function
GroupDataDto groupDataDto = (GroupDataDto) getGroup(groupPosition);
String name = groupDataDto.getName();
convertView.setTag(name);
...
Now in your Fragment / Activity, in your onGroupExpand and onGroupCollapse:
GroupDataDto groupDataDto = (GroupDataDto) listAdapter.getGroup(groupPosition);
ImageView arrow = (ImageView) getView().findViewWithTag(groupDataDto.getName()).findViewById(R.id.expandable_arrow_down);
Then I can do my animation on the arrow, which is why I wanted to get that group view.
Well I used the following code to access a TextView in a group:
#Override
public boolean onChildClick(final ExpandableListView parent, final View v,
final int groupPosition, final int childPosition, final long id) {
View vParent = mAdapter.getGroupView(groupPosition, true, null, null);
Programa v2 = (Programa) vParent.getTag();
return true;
}
I hope it helps

ExpandableListView with button inside childs

I'm writing an ExpandableListActivity with a SimpleCursorTreeAdapter that queries a DB. I added a button inside very child, and now i'm having bad time getting info on the item from the list that its button is clicked. I think that my problem is that i don't well understand how to handle data within the adapter. Most of the examples are about listadapter like this one.
My adapter got getChildView implementation and what i cannot achieve is to retrieve the _id of the clicked group from the original cursor. Because i didn't know how, i tried in the following code to get the name from the group textview but in every child that i click i get the name of the first item in the list.
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);
v.inflate(getApplicationContext(),R.layout.productsexpchilditem, null);
Button button = (Button)v.findViewById(R.id.button1);
String name=((TextView)parent.findViewById(R.id.txt_exp_products_name_item)).getText().toString();
button.setTag(name);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(ProductsActivityExp.this, "TOAST "+v.getTag(), Toast.LENGTH_SHORT).show();
}
});
return v;
}
BTY I didn't implemented the getGroupView method, cause when I did it I lost all the displayed text in the groups (but not in the child). I really think the work with cursorTreeAdapter got specific implementation different then listadapter.
I didn't used ExpandableListView, but it seems strange that you get name value via parent. Its not surprising that you get same name for all buttons.
Can you explain in details, what you want to do?

Categories

Resources