Listview rows order changes randomly on scroll of listview in android

I have one ListView and one BaseAdapter.I am downloading Products from webservice and display on listview.It displays properly on listview.

But when I scroll ListView displays rows in random position means sometimes third row display in first position, middle position row display on last position and so on.

  • Google Cloud Vision API Permission Denied
  • BroadcastReceiver onReceive timeout
  • Passing values through bundle and get its value on another activity
  • Proguard configuration for Android Support v4 22.2.0
  • Android Source Repo GPG public key not found
  • How to make an EditText selectable but not editable on Android Ice Cream Sandwich?
  • This is my adapter class

    public class ProductListAdapter extends BaseAdapter implements OnClickListener{
    
        LayoutInflater inflater;
        ArrayList<Product> arrProducts;
        Context c;
    
        public ProductListAdapter(Context c, ArrayList<Product> arrProducts) {
            super();
            inflater = LayoutInflater.from(c);
            this.arrProducts = arrProducts;
            this.c = c;
        }
    
        @Override
        public int getCount() {
            return arrProducts.size();
        }
    
        @Override
        public Object getItem(int position) {
            return arrProducts.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View v, ViewGroup parent) {
            Product product = null;
            if(v == null) {
                v = inflater.inflate(R.layout.product_listview_row, null);
                product = (Product) getItem(position);
                v.setTag(product);
            }else {
                product = (Product)v.getTag();
            }
    
            v.setOnClickListener(this);
    
            TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname);
            tvProductname.setText(product.getTitle());
    
            String strReviewCount = product.getReviews();
            TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews);
            if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews");
    
            Button btnPrice = (Button)v.findViewById(R.id.btnPrice);
            btnPrice.setText(product.getSellingPrice());
    
            return v;
        }
    
        @Override
        public void onClick(View v) {
            Product product = (Product) v.getTag();
            Intent i = new Intent(c, ProductDetails.class);
            i.putExtra(Product.PROD_ID, product.getId());
            startActivity(i);
        }
    
        @Override
        public int getItemViewType(int position) {
            return super.getItemViewType(position);
        }
    
        @Override
        public int getViewTypeCount() {
            return super.getViewTypeCount();
        }
    }
    

    This is ListView on XML layout

    <ListView android:id="@+id/lstProducts" style="@style/fill_parent"
            android:dividerHeight="1dp" android:divider="#dbd3c5"
            android:scrollbars="vertical" android:layout_below="@id/layLine"></ListView>
    

    Also when I change getView() method of BaseAdapter like this it is working fine

    @Override
        public View getView(int position, View v, ViewGroup parent) {
            Product product = null;
            v = inflater.inflate(R.layout.product_listview_row, null);
            product = (Product) getItem(position);
            v.setTag(product);
            v.setOnClickListener(this);
    
            TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname);
            tvProductname.setText(product.getTitle());
    
            String strReviewCount = product.getReviews();
            TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews);
            if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews");
    
            Button btnPrice = (Button)v.findViewById(R.id.btnPrice);
            btnPrice.setText(product.getSellingPrice());
    
            return v;
        }
    

    But problem in this type is I am displaying image of product on listview row which I had not consider here.By using this type of code getView() method always create new View when ever scroll of listView so that I have to download image again and again.I used ImageLoader class which is using cash memory for download images but problem is that when I set image to ImageView many times it giving me out of memory error.

    Please help me out from this problem.

    Thanks

    Related posts:

    Listview itemclick not work
    Accessing custom content provider from different app
    Android ViewAnimator/ViewFlipper/ViewSwitcher and hardcoded value for setDisplayedChild
    How to run an android app on the device with ant
    android.os.NetworkOnMainThreadException . Need to use async task?
    Cardio graph for android
  • Button BackgroundTint not working with AppCompat v23
  • how to refresh custom listview using baseadapter in android
  • What is android:weightSum in android, and how does it work?
  • multiproject gradle build error: package does not exist
  • RelativeLayout: align View centered horizontal or vertical relative to other view
  • How to play multiple video files simultaneously in one layout side by side in different view in Android
  • 2 Solutions collect form web for “Listview rows order changes randomly on scroll of listview in android”

    I landed here because of a link to the right solution.

    The problem here is that you bind your product once to the view when you create a new view. You should call this on every call of getView:

    product = (Product) getItem(position);
    v.setTag(product);
    

    But you could call v.setOnClickListener(this) once you create the view (it won’t change anyway).

    This should do the trick. The view type implementation is just misused here. I recommend to read my answer here…

    Therefore, according to the recommendations made by Knickedi, the getView() method should look like:

    public View getView(int position, View v, ViewGroup parent) {
    
        TextView tvProductname;
        TextView tvReviewsCounts;
        Button btnPrice;
    
        // Phase 1...
        if (v == null) {
            v = inflater.inflate(R.layout.product_listview_row, null);
            v.setOnClickListener(this);
    
            tvProductname = (TextView)v.findViewById(R.id.tvProductname);
            tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews);
            btnPrice = (Button)v.findViewById(R.id.btnPrice);
    
            v.setTag(R.id.tvProductname, tvProductname);
            v.setTag(R.id.tvReviews, tvReviewsCounts);
            v.setTag(R.id.btnPrice, btnPrice);
        }
        else {
            tvProductname = (TextView) v.getTag(R.id.tvProductname);
            tvReviewsCounts = (TextView) v.getTag(R.id.tvReviews);
            btnPrice = (Button) v.getTag(R.id.btnPrice);   
        }
    
        // Phase 2...
        Product product = (Product) getItem(position);
    
        tvProductname.setText(product.getTitle());
        btnPrice.setText(product.getSellingPrice());
    
        String strReviewCount = product.getReviews();
        if(strReviewCount != null)
            tvReviewsCounts.setText(strReviewCount +" Reviews");
    
        return v;
    }
    
    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.