1

I would like to display different types of objects in the same ListView, but I don't know how to differentiate these Objects via getItem(position)

The ListView displays a list of Messages which can be either a Chat, either a Notification, and the items Chat and Notification have different layout.

This is the adapter :

public class MailboxAdapter extends BaseAdapter {

    private ArrayList<Messages> m_alMessages = null;

    private Messages getItem(int position) {

        return m_alMessages.get(position)
    }

   @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        if (m_alMessages != null) {
            if (getItem(position).isChat()) {
                final Chat cChatItem = getItem(position);
                if (convertView == null) {
                    //Cat logic
                    // ...
                }
            } else {
                final Notification nNotifItem = getItem(position);

                 if (convertView == null) {
                    //Notification logic
                    // ...
                }

            }
        }
    }

the Message Class (minimal)

public class Message {
        private long m_lId = 0L;
        private boolean m_bIsChat = false;

        public boolean isChat() { return m_bIsChat; }

}

the Notification and Chat classes :

public class Notification extends Message { ... }

public class Cat extends Message { ... }

I am retrieving a list of Chats and a List of Notifications from web-services when starting the activity, so I would have to add them to a new list of Messages in their respective order (date), and then instantiate m adapter with this list of Message

Is it a good practice ?

Jerec TheSith
  • 1,932
  • 4
  • 32
  • 41

3 Answers3

4

Just add a boolean flag to the class object and in the adapter, check the flag and use one layout if its a chat, another if it is flagged as a notification. No problem with that

There is a tutorial here which actually covers more or less what you are trying to do with different view layouts within a listView

Within your adapter create two viewholders, one for chat, one for notification. Then, in getView(), get the object which you are creating the view for, check the boolean flag, instantiate the correct holder and inflate the view based upon the flag and then set the view elements as you would if there was just that one class and the ListView will show the view you set up that element in place.

rcbevans
  • 7,101
  • 4
  • 30
  • 46
  • If there is a boolean in the object class (isChat), what would be the boolean in the adapter ? – Jerec TheSith May 14 '13 at 10:39
  • If you already have that flag then yes, you can check that in the getElement method you can get the object for the view placeholder being populated, check the flag and inflate the view accordingly. – rcbevans May 14 '13 at 10:42
1

As o0rebelious0o said, use a flag or an id in your object. Then, use getItemViewType and getViewTypeCount in the adapter to differentiate your item type. So, in getView, you will only receive a compatible convertView.

1

I have done this

enter image description here

I have a single list, in that 3 different types of Object list(like Tour/Hotel/Visa)

So three different type of object list each list contain a different type of Objects, but there is a twist which I have used for the identification I have three types of objects list, so I have passed the Map> to the adapter, check the below example

        BookingDetails details = gson.fromJson(result, BookingDetails.class);
        Map<String, List<Object>> serviceListMap = new HashMap<>();
        if (details.getHotelList() != null) {
            List<Object> list = new ArrayList<>();
            list.addAll(details.getHotelList());
            serviceListMap.put("Hotel", list);
        }
        if (details.getTourList() != null) {
            List<Object> list = new ArrayList<>();
            list.addAll(details.getTourList());
            serviceListMap.put("Tour", list);
        }
        if (details.getVisaList() != null) {
            List<Object> list = new ArrayList<>();
            list.addAll(details.getVisaList());
            serviceListMap.put("Visa", list);
        }
        if (serviceListMap.size() > 0){
            HomeListAdapter adapter = new HomeListAdapter(HomeActivity.this, serviceListMap);
            listView.setAdapter(adapter);
        }

and in the HomeListAdapter

public class HomeListAdapter extends BaseAdapter {

private List<String> mDataList;
private Map<String, List<Object>> detailMap;
private Context mContext;

public HomeListAdapter(Context context, Map<String, List<Object>> dataList) {
    mContext = context;
    mDataList = new ArrayList<>(dataList.keySet());
    detailMap = dataList;
}


@Override
public int getCount() {
    return mDataList.size();
}

@Override
public String getItem(int position) {
    return mDataList.get(position);
}

@Override
public long getItemId(int position) {
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    String key = mDataList.get(position);
    final HolderVoucher holderVoucher;
    if (convertView == null) {
        convertView = View.inflate(mContext, R.layout.item_row, null);
        holderVoucher = new HolderVoucher();
        convertView.setTag(holderVoucher);
        holderVoucher.title = convertView.findViewById(R.id.title);
        holderVoucher.checkin = convertView.findViewById(R.id.checkin);
        holderVoucher.checkout = convertView.findViewById(R.id.checkout);
    } else {
        holderVoucher = (HolderVoucher) convertView.getTag();
    }
    StringBuilder desc = null;
    holderVoucher.title.setText(key);
    List<Object> services = detailMap.get(key);
    desc = new StringBuilder();

    if (services.size() > 0) {
        for (int i = 0; i < services.size(); i++) {
            desc.append("\n");
            if (services.size() > 1) {
                desc.append((i + 1) + ". ");
            }
            if (key.equalsIgnoreCase("Visa")) {
             VisaDetails detail = (VisaDetails) services.get(i);
                desc.append(detail.getVisaName());
                desc.append("\nTravel Date : " +  detail.getTravelDate()));
            } else if (key.equalsIgnoreCase("Hotel")) {
                HotelDetails detail = (HotelDetails) services.get(i);
                desc.append(detail.getHotelName() + "\n" + detail.getRoomType());
                desc.append("\nCheck in : " + detail.getCheckInDate()) +
                        " Check out : " + detail.getCheckOutDate()));
            } else if (key.equalsIgnoreCase("Tour")) {
                TourDetails detail = (TourDetails) services.get(i);
                desc.append("Tour - " + detail.getTourName());
                desc.append("\nTravel Date : " +detail.getTravelDate()));
            }
    holderVoucher.checkin.setText(desc.toString());

    return convertView;
  }
  private class HolderVoucher {
    private TextView title, checkin, checkout;
  }
}

if you have any query in above details let me know.

Vivek Hande
  • 929
  • 9
  • 11