2

I need to call the BaseExpandableListAdapter method

        @Override
        public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent)

or something like that to get the view that the method returns. The problem is, if I call that method, I have to pass null to convertView, which will reinflate the view, which is the view I need.

I need the view because it contains a custom view with code I need to retrieve from it without resetting it to a new instance of itself. Take this method for example:

        public ArrayList<CustomViewData> getCustomViewData ()
        {
            ArrayList<CustomViewData> customViewDatas = new ArrayList<>();
            for(int i = 0; i < getGroupCount(); i++)
                if(listView.isGroupExpanded(i))
                {
                    View v = //getConvertView
                    customViewDatas.add((CustomViewData) v.findViewById(R.id.customView);
                }
            return customViewDatas;
         }

How can I get the actual view from the ExpandableListView (or its base adapter) without creating a new view?

Andrew No
  • 535
  • 6
  • 20

2 Answers2

0

Never store the Views generated by getView(). This is a very dangerous practice. You risk leaking Views. Additionally the adapter recycles Views as you scroll, so there's a chance what you are storing will not be representative of what you need.

You are thinking in the wrong direction. The adapter binds data to Views. Meaning, how a View is rendered is based upon the data itself. If you need to update one of the Views as a result of some event...then the data representative of that View must be updated. The adapter can then re-render it's View accordingly.

When solving such problems, just keep telling yourself "If I need to modify the View, then I need to modify it's data."

Ifrit
  • 6,791
  • 8
  • 50
  • 79
  • But the data is stored in a custom view. I can not have the view regenerated each time, and with out an onViewUnBound method or something on the lines, saving the views data is not possible. – Andrew No Jun 03 '15 at 19:40
  • Not sure I'm entirely following. You should not be storing data in Views. A View in position 1 could end up being in position 10 after scrolling around because they are recycled by the adapter. If you want the Views to render a particular way, your adapter needs to store that data/state so it can appropriately render the Views accordingly. Also, I just noticed you are storing Views in that ArrayList. Why are you doing that? That is very dangerous and mostly never recommended. – Ifrit Jun 03 '15 at 20:17
  • Its because they are custom views. For example, I extended ViewSlider to add a position text view. But in any case I actually got a perfect solution. Check the new answer! Thanks for the info. – Andrew No Jun 03 '15 at 20:40
  • You override the `getView()` method in the adapter if you need to use custom views. I'm sorry I wasn't helpful, but I feel you are still going down the wrong track. Please look to https://commonsware.com/ for help in how to use Adapters. He's very active on SO here too. – Ifrit Jun 03 '15 at 22:58
0

The solution to this problem is not an easily apparent one.

There is no way to replicate behaviors like ArrayAdapter's capabilities for RecyclerView Adapters.

Instead, if you need to get data from a custom view that is not automatically stored, override

@Override
public void onViewDetachedFromWindow (ViewHolder holder)
{
    //STORE VIEW DATA
    super.onViewDetachedFromWindow(holder);
}

@Override
public void onViewRecycled(ViewHolder holder)
{
    //STORE VIEW DATA
    super.onViewRecycled(holder);
}

Use those methods to get the data from the view stored in your ViewHolder.

You must get the data from the visible views after you are done with the recycler. Those visible views are not recycled automatically so you have to retreive the view data from the visible views still on the adapter.

To do this, see this post.

Community
  • 1
  • 1
Andrew No
  • 535
  • 6
  • 20