Search code examples
androidandroid-recyclerviewandroid-adapterloaderswiperefreshlayout

swipe to refresh recyclerview duplicate item json


I have a problem, when i swipe to refresh the data, the first swipe is ok but after that every swipe reload and add the same data over and over again, by the end i have a list with same items over and over... I'm using a loader. I tried to clear before but i don't understand what's wrong with my code, if someone could explain it to me. Thank You. Here my code :

public static final String EXTRA_URL = "imageUrl";
public static final String EXTRA_APKNAME = "apkname";
public static final String EXTRA_APKSIZE = "apksize";
public static final String EXTRA_APKFILE = "apkfile";

private RecyclerView mRecyclerView;
private MyAdapter mExampleAdapter;
private ArrayList<one_item> mExampleList;
private RequestQueue mRequestQueue;
private SwipeRefreshLayout swipeRefreshLayout;


@SuppressLint("RestrictedApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getSupportActionBar().setTitle("APK VIP CHINA");
    getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);


    swipeRefreshLayout = findViewById(R.id.refreshlayout);
    mRecyclerView = findViewById(R.id.recycler_view);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mExampleList = new ArrayList<>();
    mRequestQueue = Volley.newRequestQueue(this);

    parseJSON();


    swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            parseJSON();
            swipeRefreshLayout.setRefreshing(false);

        }
    });


}

private void parseJSON() {

    String url = "http://apkvip.net/json2.php";
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray jsonArray = response.getJSONArray("data");
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject hit = jsonArray.getJSONObject(i);
                            String creatorName = hit.getString("ten");
                            String creatorsize = hit.getString("apk_size");
                            String creatorfile = hit.getString("link_apk");
                            String imageUrl = hit.getString("link_img");

                            mExampleList.add(new one_item(imageUrl, creatorName, creatorsize, creatorfile));
                        }
                        mExampleAdapter = new MyAdapter(MainActivity.this, mExampleList);
                        mRecyclerView.setAdapter(mExampleAdapter);
                        mExampleAdapter.setOnItemClickListener(MainActivity.this);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    mRequestQueue.add(request);
}

public void onItemClick(int position) {
    Intent detailIntent = new Intent(this, activity_detail.class);
    one_item clickedItem = mExampleList.get(position);
    detailIntent.putExtra(EXTRA_URL, clickedItem.getmImageUrl());
    detailIntent.putExtra(EXTRA_APKNAME, clickedItem.getMapkname());
    detailIntent.putExtra(EXTRA_APKSIZE, clickedItem.getMapksize());
    detailIntent.putExtra(EXTRA_APKFILE, clickedItem.getMapkfile());
    startActivity(detailIntent);
}}

My adapter:

private ArrayList<one_item> mExampleList;

private OnItemClickListener mListener;
public interface OnItemClickListener {
    void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
    mListener = listener;
}


public MyAdapter(Context context, ArrayList<one_item> exampleList) {
    mContext = context;
    mExampleList = exampleList;
}
@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(mContext).inflate(R.layout.one_item, parent, false);
    return new ExampleViewHolder(v);
}
@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
    one_item currentItem = mExampleList.get(position);
    String imageUrl = currentItem.getmImageUrl();
    String apkname = currentItem.getMapkname();
    String apksize = currentItem.getMapksize();
    String apkfile = currentItem.getMapkfile();

    holder.mTextViewname.setText(apkname);
    holder.mTextViewsize.setText(apksize);
    holder.mTextViewfile.setText(apkfile);

    Picasso.get().load(imageUrl).fit().centerInside().into(holder.mImageView);


}
@Override
public int getItemCount() {
    return mExampleList.size();
}

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

public class ExampleViewHolder extends RecyclerView.ViewHolder {
    public ImageView mImageView;
    public TextView mTextViewname, mTextViewsize, mTextViewfile;

    public ExampleViewHolder(View itemView) {
        super(itemView);
        mImageView = itemView.findViewById(R.id.image);
        mTextViewname = itemView.findViewById(R.id.name);
        mTextViewsize = itemView.findViewById(R.id.size);
        mTextViewfile = itemView.findViewById(R.id.file);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mListener != null) {
                    int position = getAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {
                        mListener.onItemClick(position);
                    }
                }
            }
        });}}}

my activitymain.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="5dp">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Recommended Apps"
    android:textColor="#000"
    android:textStyle="bold"
    android:textSize="20sp"
    android:layout_marginBottom="10dp"
    />

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
    android:id="@+id/refreshlayout"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    >


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        android:padding="5dp" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

Solution

  • Just use mExampleList.clear() at the first line of your parseJSON() function and then you'll be able to add the "updated" items.

    In addition I'd suggest that you move swipeRefreshLayout.setRefreshing(false) to the end of Volley onResponse and onError() implementation - Right now you're telling the swipeRefreshLayout to stop refreshing before the request(that happens asynchronously) has finished