Search code examples
javaandroidgridviewadapterpicasso

GridView items restart android


I have a Gridview where I set some items from an array of string. The code works fine, but I have a problem with it.

Everytime I add items, it "add" 10 of them and instead of jumping to the item 11, it go back to the first one. So the final result is something like:

1. 1
2. 2
3. 3
4. 4
5. 5
6. 6
7. 7
8. 8
9. 9
10. 10
11. 1
12. 2
...

As I've seen, when I navigate up/down it restart loading the data from the beggining. Could somebody help me please? I don't know where the problem can be.

CustomGridViewActivity.java:

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

public class CustomGridViewActivity extends BaseAdapter {

    private Context mContext;
    private final String[] gridViewString;
    private final String[] gridViewImageId;

    public CustomGridViewActivity(Context context, String[] gridViewString, String[] gridViewImageId) {
        mContext = context;
        this.gridViewImageId = gridViewImageId;
        this.gridViewString = gridViewString;
    }

    @Override
    public int getCount() {
        return gridViewString.length;
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

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

    @Override
    public View getView(int i, View convertView, ViewGroup parent) {
        View gridViewAndroid;
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (convertView == null) {

            gridViewAndroid = new View(mContext);
            gridViewAndroid = inflater.inflate(R.layout.gridview_layout, null);
            TextView textViewAndroid = (TextView) gridViewAndroid.findViewById(R.id.android_gridview_text);
            ImageView imageViewAndroid = (ImageView) gridViewAndroid.findViewById(R.id.android_gridview_image);
            textViewAndroid.setText(gridViewString[i]);
            Picasso
                    .with(mContext)
                    .load(gridViewImageId[i])
                    .fit() // will explain later
                    .into((ImageView) imageViewAndroid);
            //imageViewAndroid.setImageResource(gridViewImageId[i]);
        } else {
            gridViewAndroid = (View) convertView;
        }

        return gridViewAndroid;
    }
}

gridview_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/android_custom_gridview_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/android_gridview_image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="15dp" />

    <TextView
        android:id="@+id/android_gridview_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:textSize="12sp" />
</LinearLayout>

content_main.xml:

<GridView
    android:id="@+id/grid_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnWidth="90dp"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:layout_alignParentStart="true"
    android:layout_alignParentEnd="true" />

Common.java:

   //SearchPanel
    static String[] gridViewString = new String[30];
    static String[] gridViewImages = new String[30];

MainActivity.java:

public void Search() {
    //GridView
    CustomGridViewActivity adapterViewAndroid = new CustomGridViewActivity(MainActivity.this, Common.gridViewString, Common.gridViewImages);
    androidGridView=(GridView)findViewById(R.id.grid_view);
    androidGridView.setAdapter(adapterViewAndroid);
    androidGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int i, long id) {
            Toast.makeText(MainActivity.this, "GridView Item: " + Common.gridViewString[+i], Toast.LENGTH_LONG).show();
        }
    });
}

(JUST IN CASE, the data from the "Common" file is added by JSON and it's all different)


Solution

  • In your adapter's getView() method move the lines where you set the text and setup Picasso outside of the if-else block:

    if (convertView == null) {
       ...
    } else {
       ...
    }
    textViewAndroid.setText(gridViewString[i]);
    Picasso
           .with(mContext)
           .load(gridViewImageId[i])
           .fit() // will explain later
           .into((ImageView) imageViewAndroid);
    return gridViewAndroid;
    

    Right now you're setting the text and image only when the row is being freshly built(convertView being null). As that row view will be recycled(used) for other rows as well, you end up with the old information as you aren't setting up the previously constructed row with new data.