How to stop refreshing recyclerview data scroll to top position android everytime
我正在尝试使用 recyclerview 制作类似于视频的布局。我做了一个recyclerview,它在一定间隔后更新列表,但问题是数据更新后它会自动滚动到顶部位置。我想做类似视频的东西。 https://youtu.be/omcS-6LeKoo
我尝试过来自 SO 的链接
RecyclerView 更改适配器数据时滚动到顶部位置 RecyclerView notifyDataSetChanged 滚动到顶部位置但无法解决。以下是我的尝试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerViewId); handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show(); listShow(); handler.postDelayed(this,1000); } },1000); } void listShow(){ retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class); Call<ModelClass_JSONParse> getDetails = retrofitApiCall; anime = ExtendedAnime.getAll(); getDetails.enqueue(new Callback<ModelClass_JSONParse>() { @Override public void onResponse(Call<ModelClass_JSONParse> call, Response<ModelClass_JSONParse> response) { Log.v("Res",response.toString()); getWithValues = new HashMap<>(); if (response.isSuccessful()){ list.add(mModelClass_adapter); } adapter = new Adapter(getApplicationContext(),list); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); adapter.notifyDataSetChanged(); } } @Override public void onFailure(Call<ModelClass_JSONParse> call, Throwable t) { Log.v("Res",call.toString()); } }); } |
问题可能是因为您在网络回调方法 onResponse() 中设置了新的适配器引用。尝试在 onCreate 中设置适配器,然后在回调中更新数据集。
1 2 3 4 5 6 | protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerViewId); recyclerView.setAdapter(yourAdapter); } |
在网络回调中,
1 2 3 4 5 6 7 8 9 10 11 12 | @Override public void onResponse(Call<ModelClass_JSONParse> call, Response<ModelClass_JSONParse> response) { Log.v("Res",response.toString()); getWithValues = new HashMap<>(); if (response.isSuccessful()){ adapter.setDataSet(newDataList) //not change adapter reference,only update data set } } |
在你的适配器中实现 setDataSet() 方法来更新列表,如下所示。
1 2 3 4 5 6 7 8 9 | class YourAdapter extends RecyclerView.Adapter<>{ priavate List<> list = new ArrayList(); public void setDataSet(newList:List<>){ list.clear(); list.addAll(newList); notifyDataSetChanged(); } } |
您可以按照以下方式进行
首先获取当前数据列表的计数
int 位置 = datalist.size();
将数据添加到数据列表后
调用 DataAdapter.notifyDataSetChanged();
然后将光标移动到recyclerview中的位置
recyclerView.scrollToPosition(位置);
编码愉快……!
您每次都在设置一个新的适配器,并且会出现一个新的布局管理器响应。
这可能会导致此类问题。您需要在 onCreate 中设置适配器和布局管理器。只需更新适配器列表以响应 api.
根据这个答案,您只需要线性布局管理器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerViewId); list= ArrayList<>(); adapter = new Adapter(getApplicationContext(),list); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context, OrientationHelper.VERTICAL, false); recycleView.setLayoutManager(linearLayoutManager); recyclerView.setAdapter(adapter); handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show(); listShow(); handler.postDelayed(this,1000); } },1000); } void listShow(){ retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class); Call<ModelClass_JSONParse> getDetails = retrofitApiCall; anime = ExtendedAnime.getAll(); getDetails.enqueue(new Callback<ModelClass_JSONParse>() { @Override public void onResponse(Call<ModelClass_JSONParse> call, Response<ModelClass_JSONParse> response) { Log.v("Res",response.toString()); getWithValues = new HashMap<>(); if (response.isSuccessful()){ adapter.getList().add(mModelClass_adapter); } adapter.notifyDataSetChanged(); } } @Override public void onFailure(Call<CurrencyModelClass_JSONParse> call, Throwable t) { Log.v("Res",call.toString()); } }); } |
这些代码行给您带来了问题。每次调用 API 时,您都在设置新的适配器引用和线性布局管理器引用。
1 2 3 4 | adapter = new Adapter(getApplicationContext(),list); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); |
要完成您想要的任务,您需要执行以下步骤 -
以上步骤将解决您的问题。试一试。
当响应发生变化时,您会一次又一次地设置适配器,因此您应该更改列表并在 onCreate 中设置适配器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | Arraylist<ModelClass_adapter> list = new Arraylist<ModelClass_adapter>; Adapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = findViewById(R.id.recyclerViewId); //set adapter here adapter = new Adapter(getApplicationContext(),list); StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter); handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { // Toast.makeText(getApplicationContext(),"Updating",Toast.LENGTH_LONG).show(); listShow(); handler.postDelayed(this,1000); } },1000); } void listShow(){ retrofitApiCall = RetrofitInstance.getRetrofitInstance().create(RetrofitApiCall.class); Call<ModelClass_JSONParse> getDetails = retrofitApiCall; anime = ExtendedAnime.getAll(); getDetails.enqueue(new Callback<ModelClass_JSONParse>() { @Override public void onResponse(Call<ModelClass_JSONParse> call, Response<ModelClass_JSONParse> response) { Log.v("Res",response.toString()); getWithValues = new HashMap<>(); if (response.isSuccessful()){ list.clear(); list.add(mModelClass_adapter); } adapter.notifyDataSetChanged(); } } @Override public void onFailure(Call<CurrencyModelClass_JSONParse> call, Throwable t) { Log.v("Res",call.toString()); } }); } |
不要使用
尝试不同的方法,例如 notifyItemChanged()、notifyItemRangeChanged()、notifyItemInserted()