简体   繁体   中英

How to fix repeating items when scrolling in android listview?

I have a custom adapter class which extended by ArrayAdapter . I set the adapter to a listview in my activity. In my objects list I have 8 objects. In the listview shows 5 objects when it's loading(when i'm scrolling the listview it has 3 more data to show). After I scroll the listview last 3 objects are showing same as 1st 3 objects. Here's the code what I tried.

Adapter

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        final MenuItem listItem = objects.get(position);
        holder = new Holder();
        LayoutInflater inflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.menu_list_item, parent);

        holder.textViewItemName = (TextView) convertView.findViewById(R.id.textViewItemName);
        holder.textViewItemName.setText(listItem.getItemName());

        holder.textViewPrice = (TextView) convertView.findViewById(R.id.textViewPrice);
        holder.textViewPrice.setText("$ ".concat(String.valueOf(listItem.getItemPrice())));

        holder.imageView = (ImageView) convertView.findViewById(R.id.imageViewItem);


        holder.buttonPlus = (ButtonRectangle) convertView.findViewById(R.id.buttonPlus);
        holder.cartQtyTextView = (TextView) convertView.findViewById(R.id.textViewCartQty);

        // Check & Set
        if (holder.buttonPlus != null) {
            holder.buttonPlus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int i = 0;
                    if (holder.cartQtyTextView != null) {
                        holder.cartQtyTextView.setText("" + ++i);
                    }
                }
            });
        }
        holder.buttonPlus.setBackgroundColor(Color.WHITE);
        holder.buttonPlus.setTextColor(Color.parseColor("#333333"));

        holder.buttonMinus = (ButtonRectangle) convertView.findViewById(R.id.buttonMinus);

        // Check & Set
        if (holder.buttonMinus != null) {
            holder.buttonMinus.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int i = 0;
                    if (holder.cartQtyTextView != null) {
                        holder.cartQtyTextView.setText("" + --i);
                    }
                }
            });
        }
        holder.buttonMinus.setBackgroundColor(Color.WHITE);
        holder.buttonMinus.setTextColor(Color.parseColor("#333333"));
        convertView.setTag(holder);
    } else {
        holder = (Holder) convertView.getTag();
    }

    return convertView;
}

Activity

listViweMenu.destroyDrawingCache();
listViweMenu.setVisibility(ListView.INVISIBLE);
listViweMenu.setVisibility(ListView.VISIBLE);
menuListAdapter.notifyDataSetChanged();
List<uk.co.bapos.android.baposwaiter.data.models.menu.MenuItem> itemsList
            = MenuItemController.fetchAllCategoryItems(this, String.valueOf(new ArrayList<>(menuItemData.entrySet()).get(position).getValue()));
listDataMenu.clear();
listDataMenu.addAll(itemsList);

How may I fix this?

You are calling getTag(), setTag() and setting the data in wrong place. Try this:

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

            holder = new Holder();
            LayoutInflater inflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.menu_list_item, parent);

            holder.textViewItemName = (TextView) convertView.findViewById(R.id.textViewItemName);
            holder.textViewPrice = (TextView) convertView.findViewById(R.id.textViewPrice);
            holder.imageView = (ImageView) convertView.findViewById(R.id.imageViewItem);
            holder.buttonPlus = (ButtonRectangle) convertView.findViewById(R.id.buttonPlus);
            holder.cartQtyTextView = (TextView) convertView.findViewById(R.id.textViewCartQty);
            holder.buttonMinus = (ButtonRectangle) convertView.findViewById(R.id.buttonMinus);
            convertView.setTag(holder);
        } else {
            holder = (Holder) convertView.getTag();
        }
            final MenuItem listItem = objects.get(position);
            holder.textViewItemName.setText(listItem.getItemName());
            holder.textViewPrice.setText("$ ".concat(String.valueOf(listItem.getItemPrice())));
            // Check & Set
            if (holder.buttonPlus != null) {
                holder.buttonPlus.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int i = 0;
                        if (holder.cartQtyTextView != null) {
                            holder.cartQtyTextView.setText("" + ++i);
                        }
                    }
                });
            }
            holder.buttonPlus.setBackgroundColor(Color.WHITE);
            holder.buttonPlus.setTextColor(Color.parseColor("#333333"));

            // Check & Set
            if (holder.buttonMinus != null) {
                holder.buttonMinus.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int i = 0;
                        if (holder.cartQtyTextView != null) {
                            holder.cartQtyTextView.setText("" + --i);
                        }
                    }
                });
            }
            holder.buttonMinus.setBackgroundColor(Color.WHITE);
            holder.buttonMinus.setTextColor(Color.parseColor("#333333"));

        }
        return convertView;
    }

After getting all the id's of views use setTag() and if view is not null use getTag() to get all id's back. Only after that set data to the views.

In Activity :

ArrayAdapter adapter = myAdapter();//pass arraylist or data to adapter here
listview.setAdapter(adapter);

Try this.

LayoutInflater inflater = (LayoutInflater) this.context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.menu_list_item, parent);
//initializing your view elements
 convertView.setTag(holder);
}
else{
holder = (Holder) convertView.getTag();
}
// do other stuff after if-else, setting the values to view elements

You need to understand why holder is used and set as tag.

If convertView is not null means you will be reusing the view (this improves performance and saves memory) Now what you are doing when it is not null is holder = (Holder) convertView.getTag(); and returning sameConvertView so you get the same view

What you need to do after getting holder tag is change the view information using holder Eg holder.textViewItemName.setText(listItem.getItemName());//Needs to get the current list item based on position.

@Override public View getView(int position, View convertView, ViewGroup parent) 
 { 
if (convertView == null) 
  { 
    final MenuItem listItem = objects.get(position); 
    holder = new Holder(); LayoutInflater inflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.menu_list_item, parent);
    holder.textViewItemName = (TextView)convertView.findViewById(R.id.textViewItemName);
    holder.textViewPrice = (TextView) convertView.findViewById(R.id.textViewPrice);
    holder.imageView = (ImageView) convertView.findViewById(R.id.imageViewItem); 
    holder.buttonPlus = (ButtonRectangle) convertView.findViewById(R.id.buttonPlus); 
    holder.cartQtyTextView = (TextView) convertView.findViewById(R.id.textViewCartQty);
    holder.buttonMinus = (ButtonRectangle) convertView.findViewById(R.id.buttonMinus);  

   convertView.setTag(holder); }
   else 
     { 
   holder = (Holder) convertView.getTag();
    }
   holder.textViewItemName.setText(listItem.getItemName()); 
   holder.textViewPrice.setText("$ ".concat(String.valueOf(listItem.getItemPrice()))); // Check & Set if (holder.buttonPlus != null) { 
   holder.buttonPlus.setOnClickListener(new View.OnClickListener() 
  {

     @Override public void onClick(View v)
 {
 int i = 0; if (holder.cartQtyTextView != null) 
{ 
 holder.cartQtyTextView.setText("" + ++i); 
 } 
} 
  });
 } 

 holder.buttonPlus.setBackgroundColor(Color.WHITE);   
 holder.buttonPlus.setTextColor(Color.parseColor("#333333"));

 // Check & Set if (holder.buttonMinus != null)
 { 
 holder.buttonMinus.setOnClickListener(new View.OnClickListener() 
 { 
 @Override public void onClick(View v)
 {
  int i = 0; if (holder.cartQtyTextView != null) 
 { 
  holder.cartQtyTextView.setText("" + --i); 
  } 
 } }); } 
  holder.buttonMinus.setBackgroundColor(Color.WHITE);    
  holder.buttonMinus.setTextColor(Color.parseColor("#333333")); 
  return convertView; 
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM