当我滚动我的Recyclerview时,图像会不断改变它的位置并重复图像

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当我滚动我的Recyclerview时,图像会不断改变它的位置并重复图像相关的知识,希望对你有一定的参考价值。

Image before scroll -Image After Scroll 我正在尝试开发类似壁纸应用程序的应用程序,当我选择任何类别然后打开它,当我滚动这个RecyclerView时,从api加载页面2图像等等,但当我滚动RecyclerView图像更改它的位置和加载重复它的。 PLZ帮我解决了这个问题。

我的适配器:

  public class ImageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private Context mCtx;
private ImageView link;
private boolean isLoading;
private List<Image> imageList;
private int visibleThreshold = 4;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
private int lastVisibleItem, totalItemCount;
private OnLoadMoreListener onLoadMoreListener;

public ImageAdapter(RecyclerView recyclerView, List<Image> imageList, Context mCtx) {
    this.mCtx = mCtx;
    this.imageList = imageList;
    if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
        final LinearLayoutManager gridLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                    totalItemCount = gridLayoutManager.getItemCount();
                    lastVisibleItem = gridLayoutManager.findLastVisibleItemPosition();

                    if (!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                        if (onLoadMoreListener != null) {
                            onLoadMoreListener.onLoadMore();
                        }
                        isLoading = true;
                    }
                }
   //                }
        });
    }
}


public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
    this.onLoadMoreListener = mOnLoadMoreListener;
}

@Override
public int getItemViewType(int position) {
    return imageList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}


@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    if (viewType == VIEW_TYPE_ITEM) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View v = inflater.inflate(R.layout.list_items, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    } else if (viewType == VIEW_TYPE_LOADING) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_loading, parent, false);
        LoadingViewHolder vh1 = new LoadingViewHolder(view);
        return vh1;
    }
    return null;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    if (holder instanceof ViewHolder) {
        final Image image = imageList.get(position);
        final String imgUrl = image.getThumb();
        link.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent intent = new Intent(v.getContext(), ViewImage.class);
                intent.putExtra("URL", imgUrl);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                v.getContext().startActivity(intent);
            }
        });

        Glide.with(mCtx).load(imgUrl).into(link);

    } else if (holder instanceof LoadingViewHolder) {
        LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
        loadingViewHolder.progressBar.setIndeterminate(true);
    }

}


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

public void setLoaded() {
    isLoading = false;
}

private class LoadingViewHolder extends RecyclerView.ViewHolder {
    public ProgressBar progressBar;

    LoadingViewHolder(View view) {
        super(view);
        progressBar = view.findViewById(R.id.progressBar1);
    }
}

class ViewHolder extends RecyclerView.ViewHolder {

    ViewHolder(View v) {
        super(v);
        link = v.findViewById(R.id.link);
    }
}

}

我的活动:

public class MainActivity extends AppCompatActivity {

int i = 1;
String query;
List<Image> imageList;
RecyclerView listView;
ImageAdapter adapter;
private static String JSON_URL;
private static final String TAG = "Tj";
ProgressBar progressBar;

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

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    //initializing listview and hero list
    listView = findViewById(R.id.listView);
    imageList = new ArrayList<>();

    Intent intent = getIntent();
    query = intent.getStringExtra("category");
    JSON_URL = "https://api.unsplash.com/search/photos?query=" + query +
            "&client_id=xxxxx&page=" + i;
    Log.d(TAG, "Query " + JSON_URL);

    loadHeroList();

}

private void loadHeroList() {
    //getting the progressbar
    progressBar = findViewById(R.id.progressBar);

    //making the progressbar visible
    progressBar.setVisibility(View.VISIBLE);

    //creating a string request to send request to the url
    StringRequest jsonArrayRequest = new StringRequest(Request.Method.GET, JSON_URL,
            new Response.Listener<String>() {

                @Override
                public void onResponse(String response) {
                    //hiding the progressbar after completion
                    progressBar.setVisibility(View.INVISIBLE);


                    try {
                        //getting the whole json object from the response
                        JSONObject obj = new JSONObject(response);

                        //we have the array named hero inside the object
                        //so here we are getting that json array
                        JSONArray heroArray = obj.getJSONArray("results");

                        //now looping through all the elements of the json array
                        for (int i = 0; i < heroArray.length(); i++) {
                            //getting the json object of the particular index inside the array
                            JSONObject jsonObject = heroArray.getJSONObject(i);

                            JSONObject jsonObject1 = jsonObject.getJSONObject("urls");

                            //creating a hero object and giving them the values from json object
                            Image hero = new Image(jsonObject.getString("id"),
                                    jsonObject.getString("color"),
                                    jsonObject1.getString("full"));


                            //adding the hero to herolist
                            imageList.add(hero);



                            listView.setHasFixedSize(true);
                            // use a grid layout manager
                            listView.setLayoutManager(new GridLayoutManager(MainActivity.this, 2));


                        }

                            //creating custom adapter object
                            adapter = new ImageAdapter(listView, imageList, getApplicationContext());

                            //adding the adapter to listview
                            listView.setAdapter(adapter);

                        //Load More Pages Start Here
                        adapter.setOnLoadMoreListener(new OnLoadMoreListener() {
                            @Override
                            public void onLoadMore() {
                                loadMoreData();
                            }
                        });

                        //Complete for Load More Pages
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    //displaying the error in toast if occurrs
                    Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });

    //creating a request queue
    RequestQueue requestQueue = Volley.newRequestQueue(this);

    //adding the string request to request queue
    requestQueue.add(jsonArrayRequest);
}

private void loadMoreData() {


    imageList.add(null);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            adapter.notifyItemInserted(imageList.size() - 1);
            imageList.remove(imageList.size() - 1);
            adapter.notifyItemRemoved(imageList.size());

            i++;
            Log.d(TAG, "ILoadMore " + i);
            String JSON_URL_LoadMore = "https://api.unsplash.com/search/photos?query=" + query + "&client_id=xxxxx&page=" + i;
            Log.d(TAG, "QueryLoadMore " + JSON_URL_LoadMore);

            StringRequest jsonArrayRequestLoadMore = new StringRequest(Request.Method.GET, JSON_URL_LoadMore,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            //hiding the progressbar after completion
                            progressBar.setVisibility(View.INVISIBLE);


                            try {
                                //getting the whole json object from the response
                                JSONObject obj = new JSONObject(response);

                                //we have the array named hero inside the object
                                //so here we are getting that json array
                                JSONArray heroArray = obj.getJSONArray("results");

                                //now looping through all the elements of the json array
                                for (int i = 0; i < heroArray.length(); i++) {
                                    //getting the json object of the particular index inside the array
                                    JSONObject jsonObject = heroArray.getJSONObject(i);

                                    JSONObject jsonObject1 = jsonObject.getJSONObject("urls");

                                    //creating a hero object and giving them the values from json object
                                    Image hero = new Image(jsonObject.getString("id"),
                                            jsonObject.getString("color"),
                                            jsonObject1.getString("full"));


                                    //adding the hero to herolist
                                    imageList.add(hero);
                                    adapter.notifyItemInserted(imageList.size());
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    },
                    new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            //displaying the error in toast if occurrs
                            Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    });
            //creating a request queue
            RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);

            //adding the string request to request queue
            requestQueue.add(jsonArrayRequestLoadMore);

            adapter.notifyDataSetChanged();
            adapter.setLoaded();
        }
    }, 5000);
}

}
答案

覆盖

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

并使用

Picasso.with(context)
.load(getImgUrl)
.placeholder(R.drawable.user_placeholder)
.fit()
.into(imageView);

要不然

要在滚动时保留和恢复Recyclerview位置,请尝试以下链接。

https://panavtec.me/retain-restore-recycler-view-scroll-position

以上是关于当我滚动我的Recyclerview时,图像会不断改变它的位置并重复图像的主要内容,如果未能解决你的问题,请参考以下文章

recyclerview 在滚动时坚持使用图像放大/缩小动画的位置

notifyDataSetChanged() 时防止 Recyclerview 滚动

使用 Glide 和 RecyclerView 上下滚动时图像消失,图像之间的空间增加

使用导航组件保存 RecyclerView 的滚动

滚动视图时,Recyclerview 在contactsContract 中更改我的phoneNumber 的值

单击项目Android时RecyclerView滚动