Search code examples
androidlistviewandroid-listviewandroid-adapterbaseadapter

ListView with different layouts with two different objects


I want to populate a ListView with different layouts for odd and even rows. It should look like this:

enter image description here

I use two objects "OddListItem" and "EvenListItem" to store/access the data. I do not know how to pass both objects to my custom listview adapter and get the correct view.

My object classes:

public class OddListItem {

    private String time_start;
    private String time_end;
    private String location;

    public OddListItem(String time_start, String time_end, String location) {
        super();
        this.time_start = time_start;
        this.time_end = time_end;
        this.location = location;
    }

    // getters and setters
    void setTimeStart(String time_start) {
        this.time_start = time_start;
    }

    void setTimeEnd(String time_end) {
        this.time_end = time_end;
    }

    void setLocation(String location) {
        this.location = location;
    }

    public String getTimeStart() {
        return time_start;
    }

    public String getTimeEnd() {
        return time_end;
    }

    public String getLocation() {
        return location;
    }
}

public class EvenListItem {

    private String image;
    private String location;

    public EvenListItem (String image, String location) {
        super();
        this.image = image;
        this.location = location;
    }

    // getters and setters
    void setImage(String image) {
        this.image = image;
    }

    void setLocation(String location) {
        this.location = location;
    }

    public String getImage() {
        return image;
    }

    public String getLocation() {
        return location;
    }
}

MyCustomAdapter:

public class MyCustomAdapter extends BaseAdapter {

    // Tag for Logging
    private static final String TAG = "MyCustomAdapter";

    int type;
    private static final int TYPE_ITEM = 0;
    private static final int TYPE_SEPARATOR = 1;
    private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

    private ArrayList<OddListItem> mData = new ArrayList<OddListItem>();
    private LayoutInflater mInflater;
    //private TreeSet mSeparatorsSet = new TreeSet();

    private Context context;

    public MyCustomAdapter(Context context) {
        mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        this.context = context;
    }

    public void addItem(final OddListItem item) {
        mData.add(item);
        //The notification is not necessary since the items are not added dynamically
        //notifyDataSetChanged();
    }

    public void addSeparatorItem(final OddListItem item) {
        mData.add(item);
        //The notification is not necessary since the items are not added dynamically
        //notifyDataSetChanged();
    }

    @Override
    public int getItemViewType(int position) {
        /*if ((position%2) == 0){
            type = TYPE_ITEM;
        } else {
            type = TYPE_SEPARATOR;
        }
        return type;*/
        return position%2;
    }

    @Override
    public int getViewTypeCount() {
        return TYPE_MAX_COUNT;
    }

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

    @Override
    public OddListItem getItem(int position) {
        return mData.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        int type = getItemViewType(position);
        Log.d(TAG, "getView " + position + " " + convertView + " type = " + type);
        if (convertView == null) {
            holder = new ViewHolder();
            switch (type) {
                case TYPE_ITEM:
                    //inflate the new layout
                    convertView = mInflater.inflate(R.layout.detail_list_row_odd, parent, false);
                    holder.tv_time_from = (TextView) convertView.findViewById(R.id.tv_time_from);
                    holder.tv_time_to = (TextView) convertView.findViewById(R.id.tv_time_to);
                    holder.tv_current_location_odd = (TextView) convertView.findViewById(R.id.tv_current_location_odd);
                    //fill the layout with values
                    /*holder.tv_time_from.setText("12:34");
                    holder.tv_time_to.setText("12:37");
                    holder.tv_current_location_odd.setText("Aktueller Standort");*/
                    holder.tv_time_from.setText(mData.get(position).getTimeStart());
                    holder.tv_time_to.setText(mData.get(position).getTimeEnd());
                    holder.tv_current_location_odd.setText(mData.get(position).getLocation());
                    break;
                case TYPE_SEPARATOR:
                    //inflate the new layout
                    convertView = mInflater.inflate(R.layout.detail_list_row_even, parent, false);
                    holder.tv_current_location_even = (TextView) convertView.findViewById(R.id.tv_current_location_even);
                    holder.img_transport = (ImageView) convertView.findViewById(R.id.img_transport);
                    //fill the layout with values
                    holder.tv_current_location_even.setText("Hauptbahnhof");
                    holder.img_transport.setImageDrawable(context.getResources().getDrawable(R.drawable.rollator));
                    break;
                default:
                    break;
            }
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        return convertView;
    }

    private static class ViewHolder {
        public TextView tv_time_from;
        public TextView tv_time_to;
        public TextView tv_current_location_odd;
        public TextView tv_current_location_even;
        public ImageView img_transport;
    }
}

Here I generate the data and call the adapter:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detailed_connection);

    generateData();

    //fill ListView with custom content from MyCustomAdapter class
    mAdapter = new MyCustomAdapter(getApplicationContext());

    for (int i = 1; i < odd_items.size(); i++) {
        mAdapter.addItem(odd_items.get(i));
        if (i % 1 == 0) {
            mAdapter.addSeparatorItem(odd_items.get(i));
        }
    }
    setListAdapter(mAdapter);

    //set duration text
    tv_duration = (TextView)findViewById(R.id.tv_duration);
    tv_duration.setText("Dauer: 22 Minuten");
}

private void generateData() {

    odd_items = new ArrayList<OddListItem>();
    odd_items.add(new OddListItem("12:34", "", "Aktueller Standort"));
    odd_items.add(new OddListItem("12:37", "12:37", "TUM"));
    odd_items.add(new OddListItem("12:42", "12:42", "Hauptbahnhof Nord"));
    odd_items.add(new OddListItem("12:48", "12:48", "Hauptbahnhof"));

    even_items = new ArrayList<EvenListItem>();
    even_items.add(new EvenListItem("R.drawable.rollator", "3 Minuten Fußweg"));
    even_items.add(new EvenListItem("R.drawable.bus", "Richtung Hauptbahnhof Nord"));
    even_items.add(new EvenListItem("R.drawable.rollator", "6 Minuten Fußweg"));

    mData = new Data(odd_items, even_items);
}

Any help would be great. Maybe there is also a better approach then please let me know.


Solution

  • I would create a Single list of Items

    public class Items {
    
    
        private String time_start;
        private String time_end;
        private String location;
        private int image;
        private String locationeven;
        private int oddoreven;
    
        public String getTime_start() {
            return time_start;
        }
        public void setTime_start(String time_start) {
            this.time_start = time_start;
        }
        public String getTime_end() {
            return time_end;
        }
        public void setTime_end(String time_end) {
            this.time_end = time_end;
        }
        public String getLocation() {
            return location;
        }
        public void setLocation(String location) {
            this.location = location;
        }
        public int getImage() {
            return image;
        }
        public void setImage(int image) {
            this.image = image;
        }
        public String getLocationeven() {
            return locationeven;
        }
        public void setLocationeven(String locationeven) {
            this.locationeven = locationeven;
        }
        public int getOddoreven() {
            return oddoreven;
        }
        public void setOddoreven(int oddoreven) {
            this.oddoreven = oddoreven;
        }
    
    }
    

    In onCreate of Activity call

     generateData() ;
    

    Then

     ArrayList<Items>  oddorevenlist = new ArrayList<Items>();
     private void generateData() {
    
               Items item1 = new Items();
               item1.setTime_start("12:34");
               item1.setTime_end("");
               item1.setLocation("Aktueller Standort");
               item1.setOddoreven(0);
               oddorevenlist.add(item1);
    
               Items item2 = new Items();
               item2.setImage(R.drawable.ic_launcher);
               item2.setLocationeven("3 Minuten Fußweg");
               item2.setOddoreven(1);
               oddorevenlist.add(item2);
    
               Items item3 = new Items();
               item3.setTime_start("12:37");
               item3.setTime_end("12:37");
               item3.setLocation("Tum");
               item3.setOddoreven(0);
               oddorevenlist.add(item3);
    
               Items item4 = new Items();
               item4.setImage(R.drawable.ic_launcher);
               item4.setLocationeven("Richtung Hauptbahnhof Nord");
               item4.setOddoreven(1);
               oddorevenlist.add(item4);
    
               Items item5 = new Items();
               item5.setTime_start("12:42");
               item5.setTime_end("12:42");
               item5.setLocation("Hauptbahnhof Nord");
               item5.setOddoreven(0);
               oddorevenlist.add(item5);
    
               Items item6 = new Items();
               item6.setImage(R.drawable.ic_launcher);
               item6.setLocationeven("R6 Minuten Fußweg");
               item6.setOddoreven(1);
               oddorevenlist.add(item6);
    
               Items item7 = new Items();
               item7.setTime_start("12:48");
               item7.setTime_end("12:48");
               item7.setLocation("HHauptbahnhof");
               item7.setOddoreven(0);
               oddorevenlist.add(item7);
    
               MyCustomAdapter mAdapter = new MyCustomAdapter(this,oddorevenlist);
               setListAdapter(mAdapter);
    
           }
    

    Adapter code

    public class MyCustomAdapter extends BaseAdapter {
    
        // Tag for Logging
        private static final String TAG = "MyCustomAdapter";
    
        int type;
        private static final int TYPE_ITEM = 0;
        private static final int TYPE_SEPARATOR = 1;
    
    
    
        private ArrayList<Items>  oddorevenlist ;
        private LayoutInflater mInflater;
    
    
        private Context context;
    
        public MyCustomAdapter(Context context, ArrayList<Items> oddorevenlist) {
            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            this.context = context;
    
            this.oddorevenlist = oddorevenlist;
        }
    
    
        @Override
        public int getItemViewType(int position) {
            if (oddorevenlist.get(position).getOddoreven()==0){
                type = TYPE_ITEM;
            } else if (oddorevenlist.get(position).getOddoreven()==1) {
                type = TYPE_SEPARATOR;
            }
            return type;
    
        }
    
        @Override
        public int getViewTypeCount() {
            return 2;
        }
    
        @Override
        public int getCount() {
            return oddorevenlist.size();
        }
    
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            int type = getItemViewType(position);
            Log.d(TAG, "getView " + position + " " + convertView + " type = " + type);
            if (convertView == null) {
                holder = new ViewHolder();
                switch (type) {
                    case TYPE_ITEM:
                        //inflate the new layout
                        convertView = mInflater.inflate(R.layout.row_odd, parent, false);
                        holder.tv_time_from = (TextView) convertView.findViewById(R.id.tv_time_from);
                        holder.tv_time_to = (TextView) convertView.findViewById(R.id.tv_time_to);
                        holder.tv_current_location_odd = (TextView) convertView.findViewById(R.id.tv_current_location_odd);
    
                        holder.tv_time_from.setText(oddorevenlist.get(position).getTime_start());
                        holder.tv_time_to.setText(oddorevenlist.get(position).getTime_end());
                        holder.tv_current_location_odd.setText(oddorevenlist.get(position).getLocation());
                        break;
                    case TYPE_SEPARATOR:
                        //inflate the new layout
                        convertView = mInflater.inflate(R.layout.row_even, parent, false);
                        holder.tv_current_location_even = (TextView) convertView.findViewById(R.id.tv_current_location_even);
                        holder.img_transport = (ImageView) convertView.findViewById(R.id.img_transport);
                        //fill the layout with values
                        holder.tv_current_location_even.setText(oddorevenlist.get(position).getLocationeven());
                        holder.img_transport.setImageResource(R.drawable.ic_launcher);
                        break;
                    default:
                        break;
                }
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
    
            return convertView;
        }
    
        private static class ViewHolder {
            public TextView tv_time_from;
            public TextView tv_time_to;
            public TextView tv_current_location_odd;
            public TextView tv_current_location_even;
            public ImageView img_transport;
        }
    
        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return position;
        }
    
    
    }
    

    Snap

    enter image description here