4

I have a Fragment. This fragment on his onCreateView method the view loaded has a ListView(A) (which is filled in the Adapter(A)). However, this ListView(A) has another ListView(B) inside of it. So now, I have to call an adapter(B) to fill this listview(B). if I call it from the fragment i get a null pointer, if i call it from the Adapter(A) it doesn't crash but it doesn't work.

How do you call an adapter inside another one.

This is the Fragment's code:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mContentView = inflater.inflate(R.layout.fragment_kidscontacts, container, false);
    mAdapter = new KidsContactsAdapter(getActivity());
    final ListView list = (ListView) mContentView.findViewById(R.id.listViewKidsContacts);
    list.setAdapter(mAdapter); 
    return mContentView;
}

where the mAdapter is a call for the Adapter(A) I made. And the mContentView is a simple View. Now, the code of the Adapter(A), I have a Holder object created named holder (which holds the elements in the xml).

public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder; //this is the holder object I created

    if (convertView == null) { //View received from parameter.
        convertView = LayoutInflater.from(mContext).inflate(R.layout.kids_contacts_list_item, parent, false);
        holder = new ViewHolder(); 
        holder.listViewKidsContacts = (ListView) convertView.findViewById(R.id.insidelistViewKidsContacts); //ListView(B)
        holder.kidImage = (ImageView) convertView.findViewById(R.id.kid_image);
        holder.statusImageView = (ImageView) convertView.findViewById(R.id.status_image_view);
        holder.nameTxtView = (TextView) convertView.findViewById(R.id.kid_friend_txtview);
        holder.statusTextView = (TextView) convertView.findViewById(R.id.kid_status_txtview);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    //Some work I do with the holder items assigning them 

    //Trying to fill the ListView(B)
        KidsInsideContactsAdapter mAdapter = new KidsInsideContactsAdapter(((Activity)mContext)); //This is the adapter(B)
        holder.listViewKidsContacts.setAdapter(mAdapter); //Assign the adapter(B) to the ListView(B)

    return convertView;
}

I have some logs inside the adapter(B), but they are not shown in LogCat. And neither is the listview filled. It shows like if there was no listview. However in the xml there it is.

Diego Rivera
  • 403
  • 1
  • 5
  • 19

2 Answers2

5

One thing that might be happening is the second list view's height is not being set correctly since it's inside another list view. I might have had to deal with that once.

Try using this method in your first adapter to set the list view's height - (AFTER YOU'VE SET THE ADAPTER) Something like setListViewHeightBasedOnChildren(holder.listViewKidsContacts);

// Method for Setting the Height of the ListView dynamically

public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null)
        return;

    int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.UNSPECIFIED);
    int totalHeight = 0;
    View view = null;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        view = listAdapter.getView(i, view, listView);
        if (i == 0)
            view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT));
        view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
        totalHeight += view.getMeasuredHeight();
    }
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
    listView.requestLayout();
}

If that doesn't work, I would try breakpointing on lines: KidsInsideContactsAdapter mAdapter = new KidsInsideContactsAdapter(((Activity)mContext)); //This is the adapter(B) holder.listViewKidsContacts.setAdapter(mAdapter); //Assign the adapter(B) to the ListView(B)

When debugging check to see if mAdapter is null. Also put breakpoints in constructors for KidsInsideContactsAdapter to see if everything is happening okay.

Also check to make sure holder.listViewKidsContacts is the list view you are looking for while debugging.

sb6847
  • 92
  • 4
  • This fixed it. The getCount was returning 0, because of a mistake I had, so if someone is having a similar problem, check that out. – Diego Rivera Aug 31 '15 at 16:04
  • Thanks mate for your answer... I was calling adapter inside of adapter and listviews height attribute was dynamicly is changed...Initial was 0... and I have noticed that when I was changed targetsdk higher I saw listview item was not visibled.. After I see your answer I have figured out the problem... But then why with targetted low api items visible but not in higher targetted api?? – Ucdemir Jan 21 '16 at 05:17
1

You are right. To populate the second list view, in your first list view's adapter in your

@Override public View getView(final int position, View convertView, ViewGroup parent) {

method (where you get each item in your first list view), you'd have to get the (second) list view from the view (convertView or inflating the layout for your first list view's item). once you grab the (second) list view you're trying to populate, in this method, you'd set the adapter for that doing something like : ListView listView = (ListView) view.findViewById(R.id.___); //Get the second list view that's inside your first list view listView.setAdapter(Your adapter for your second list view)

This should work. Put your code in here and I can take a look at it and tell you why it might not be working.

Also check out these : (in case you're trying to do something like this)

https://github.com/emilsjolander/StickyListHeaders

Or How to make sticky section headers (like iOS) in Android?

Community
  • 1
  • 1
sb6847
  • 92
  • 4