Search code examples
javaandroidlistlistviewbaseadapter

My simple custom listview show wrong items, not working as intended. Can't see what is wrong


I am trying to create something like this: https://i.sstatic.net/l8ZOc.png

However, i ran into a problem. When i create the list with my adapter, it is supposed to be a list of 8 items. However, it just shows the first 4 of these items in a random order two times. Do you see what is wrong with my code?

public class MyActivity extends Activity{

    String headers[];
    String image_urls[];

    List<MyMenuItem> menuItems;
    ListView mylistview;

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

        menuItems = new ArrayList<MyMenuItem>();
        headers = getResources().getStringArray(R.array.header_names);
        image_urls = getResources().getStringArray(R.array.image_urls);


        for (int i = 0; i < headers.length; i++) {
            MyMenuItem item = new MyMenuItem(headers[i], image_urls[i]);
            menuItems.add(item);

        }

        mylistview = (ListView) findViewById(R.id.list);
        MenuAdapter adapter = new MenuAdapter(this, menuItems);
        mylistview.setAdapter(adapter);
        mylistview.setOnItemClickListener(this);
    }

public class MyMenuItem {

    private String item_header;
    private String item_image_url;

    public MyMenuItem(String item_header, String item_image_url){
        this.item_header=item_header;
        this.item_image_url=item_image_url;
    }

    public String getItem_header(){
        return item_header;
    }

    public void setItem_header(String item_header){
        this.item_header=item_header;
    }

    public String getItem_image_url(){
        return item_image_url;
    }

    public void setItem_image_url(String item_image_url){
        this.item_image_url=item_image_url;
    }


}

public class MenuAdapter extends BaseAdapter{

    Context context;
    List<MyMenuItem> menuItems;

    MenuAdapter(Context context, List<MyMenuItem> rowItems) {
        this.context = context;
        this.menuItems = rowItems;
    }

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

    @Override
    public Object getItem(int position) {
        return menuItems.get(position);
    }

    @Override
    public long getItemId(int position) {
        return menuItems.indexOf(getItem(position));
    }

    private class ViewHolder {
        ImageView ivMenu;
        TextView tvMenuHeader;
    }



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

        ViewHolder holder = null;

        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.menu_item, null);
            holder = new ViewHolder();

            holder.tvMenuHeader = (TextView) convertView.findViewById(R.id.tvMenuHeader);
            holder.ivMenu = (ImageView) convertView.findViewById(R.id.ivMenuItem);

            MyMenuItem row_pos = menuItems.get(position);

            Picasso.with(context)
                    .load(row_pos.getItem_image_url())
                    .placeholder(R.drawable.empty)
                    .error(R.drawable.error)
                    .into(holder.ivMenu);

            holder.tvMenuHeader.setText(row_pos.getItem_header());

            Log.e("Test", "headers:" + row_pos.getItem_header());

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        return convertView;
    }

}

Solution

  • You are setting the data only when the convertView is null.So when it is not null,list items are inflated with data of previous list items. getView should be something like this

        @Override
            public View getView(int position, View convertView, ViewGroup parent) {
    
                ViewHolder holder = null;
    
                LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
                if (convertView == null) {
                    convertView = mInflater.inflate(R.layout.menu_item, null);
                    holder = new ViewHolder();
    
                    holder.tvMenuHeader = (TextView) convertView.findViewById(R.id.tvMenuHeader);
                    holder.ivMenu = (ImageView) convertView.findViewById(R.id.ivMenuItem); 
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
    
                MyMenuItem row_pos = menuItems.get(position);
    
                    Picasso.with(context)
                            .load(row_pos.getItem_image_url())
                            .placeholder(R.drawable.empty)
                            .error(R.drawable.error)
                            .into(holder.ivMenu);
    
                    holder.tvMenuHeader.setText(row_pos.getItem_header());
    
                    Log.e("Test", "headers:" + row_pos.getItem_header());
                return convertView;
            }