how to get view of group in expandablelistview in android? - 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

Related

How to toggle between two different layouts for an ExpandableListView childView?

I finally have my ExpandableListView working (thanks to SO), but now I want to be able to toggle between two different childViews whenever I (short) click on a child item.
I have this snippet for the setOnChildClickListener, which currently resides in the onCreate section. I assume I have to move this to within the BaseExpandableListAdapter in order to be able to toggle the layout of the childView (or can I do this from within onCreate?)
maybe a picture can illustrate it best: If I click on the 'PPLT' child, I want it to expand to approx. double height and and more info (according to a different child xml layout file)
expListView = (ExpandableListView) findViewById(R.id.StockExpandList);
expListAdapter = new ExpandableListAdapter(PortfolioView.this, SubcategoryList, subgroupCollection);
expListView.setAdapter(expListAdapter);
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
public boolean onChildClick(ExpandableListView parent,
View v,int groupPosition, int childPosition, long id) {
final String selected = (String) expListAdapter.getChild(groupPosition, childPosition);
Toast.makeText(getBaseContext(), selected, Toast.LENGTH_SHORT).show();
return true;
}
});
I'm probably showing my ignorance on how a basic listview adapter works, but I assume this is where I add a condition that decides whether to use the default child_item layout or the other one I want to show up when I click on it (e.g. called child_expanded_item since it's supposed to be larger with more info in it)
public View getChildView(final int groupPosition, final int
childPosition,boolean isLastChild,View childView, ViewGroup parent)
{
LayoutInflater inflater = context.getLayoutInflater();
if (childView == null) {
childView = inflater.inflate(R.layout.child_item, null);
}
}
Or do I go crazy and do a nested ExpandableListView?

"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;
}

ExpandableListView getGroupView friom child control

In an Expandablelistview, I want to update the one of the groupview image based on the selected control in the childview, how to accomplish this ??
basically
i want like this
public View getChildview(int groupPosition,final int childPosition, boolean isLastChild, View convertView,ViewGroup parent)
{
View Groupview=parent.getChildAt(groupPosition); ///but gives null when if scrolling the expandablelist
}
EDIT
Below Code works me
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);
}
I suggest using OnChildClickListener and override onChildClick() and use this code in getting the parent view.
getGroupView() – Returns view for the list group header
getChildView() – Returns view for list child item
So u must create/inflate view in getChildView method
For more details:
http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/

is it possible to impliment expandablelistview in which each child has different item/layouts

First of all, I'm new to programming. Is it possible to create custom expandable list in each child that has a different layout? If yes, please help me out!
There are three parents, each having a textview and a switch.
The child of first parent has:
textview
Seekbar
edittext
The child of second parent has:
textview
timepicker
textview
edittext
The child of third parent has:
textview
edittext
Please check this photoshop mockup, which is want I'd like to impliment:
Should I create three different XML for each child, or is it the adapter who plays a role here?
If not possible with expandable list, HOW can I implement this ?
Any suggestion to guide, tutorial is appreciated. :)
You can in a custom adapter but you have to create the respective layouts. Use something like the following in your getView() method.
switch (groupPosition) {
case 0:
convertView = inflater.inflate(R.layout.group1, null);
break;
case 1:
convertView = inflater.inflate(R.layout.group2, null);
break;
}
As you are using two types of views of children items of the group. So you have to override the following two methods
final int CHILDVIEW_ONE = 0;
final int CHILDVIEW_TWO = 1;
final int CHILDVIEW_TYPE_COUNT = CHILDVIEW_TWO + 1;
#Override
public int getChildTypeCount() {
return CHILDVIEW_TYPE_COUNT;
}
#Override
public int getChildType(int groupPosition, int childPosition)
{
if(childObject instanceOf item1)
return CHILDVIEW_ONE;
else if (childObject instance item2)
return CHILDVIEW_TWO;
return super.getChildType(int groupPosition, int childPosition);
}
Then in your getChildView() Do the following:
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
....
if(childObject instanceOf item1){
//handle the first child view
}else if (childObject instanceOf item2){
//handle the second child view
}
....
}
You have to override both getChildType and getChildTypeCount in order to use the concept of viewholders which optimizes the Memory peroformance drawing a scrollview

custom views not updating with OnGroupClickListener on ExpandableListView

I have custom groupViews that need to change state when they are expanded and collapsed.
If the same group view is expanded it toggles between two states.
The problem i'm having is that the expand method seems to be pulling up some cached version of the views because my updates aren't visible after calling expandGroup.
If my listener returns true (handles the whole event itself) without calling expandGroup the update does happen. So something is happening with expandGroup that only allows cached view to be drawn.
I have tried invalidating() just about everything. I've tried firing off data update events on the List View. i've tried all this other stuff as well:
expandableList.setGroupIndicator(null);
expandableList.setAlwaysDrawnWithCacheEnabled(false);
expandableList.setWillNotCacheDrawing(true);
expandableList.setItemsCanFocus(false);
no luck on any of those :(
Here's my onClick code:
expandableList.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
MusicTrackRow mt = (MusicTrackRow) v;
if (mt.isPlaying == true) {
mt.setPaused();
} else {
mt.setPlaying();
}
mt.invalidate();
parent.invalidate();
trackAdapter.notifyDataSetInvalidated();
//need to call expandGroup if the listener returns true.. if returning false expandGroup is //returned automatically
expandableList.expandGroup(groupPosition); //no view refresh
return true;
Found a solution finally!
When the expandable list is expanded a call to getGroupview in the adapter is made for every group on the list.
That is the place where you want to effect changes.
the isExpanded argument lets you determine which group view is expanded.
Then you can do stuff that looks like this:
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View v;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getBaseContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.expandablelistitem, null);
} else {
v = convertView;
}
int id = (!isExpanded) ? R.drawable.list_plus_selector
: R.drawable.list_minus_selector;
TextView textView = (TextView) v.findViewById(R.id.list_item_text);
textView.setText(getGroup(groupPosition).toString());
ImageView icon = (ImageView) v.findViewById(R.id.list_item_icon);
icon.setImageResource(id);
return v;
}

Categories

Resources