如何停止刷新recyclerview数据每次滚动到Android的最高位置

问题描述 投票:2回答:5

我正在尝试使用recyclerview进行布局,例如视频。我做了一个recyclerview,它在一定间隔后会更新列表,但问题是在数据更新后它会自动滚动到最高位置。我想制作类似视频的内容。https://youtu.be/omcS-6LeKoo我尝试了来自SO的链接RecyclerView scrolls to top position when change the adapter dataRecyclerView notifyDataSetChanged scrolls to top position但无法解决。以下是我的尝试

@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());
            }
        });
    }
android android-recyclerview
5个回答
1
投票

问题可能是由于您在网络回调方法onResponse()中设置了新的适配器引用。尝试在onCreate中设置适配器,然后在回调中更新数据集。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView = findViewById(R.id.recyclerViewId);
    recyclerView.setAdapter(yourAdapter);
}

在网络回调中,

@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()方法以更新列表,如下所示。

class YourAdapter extends RecyclerView.Adapter<>{
      priavate List<> list = new ArrayList();

      public void setDataSet(newList:List<>){ 
          list.clear();
          list.addAll(newList);
          notifyDataSetChanged();
      }
}

0
投票

请勿使用adapter.notifyDataSetChanged();方法,因为我认为您的主视图必须为包装内容,所以请设置固定高度,例如150dp。

尝试其他方法,如notifyItemChanged(),notifyItemRangeChanged(),notifyItemInserted()


0
投票

您正在更改响应时一次又一次地设置适配器,因此您应该更改列表并在onCreate中设置适配器。

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());
            }
        });
    }

0
投票

这些代码行为您造成了问题。您每次调用API时都要设置一个新的适配器参考和线性布局管理器参考。

                            adapter = new Adapter(getApplicationContext(),list);
                            StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL);
                            recyclerView.setLayoutManager(layoutManager);
                            recyclerView.setAdapter(adapter);

要执行所需的任务,您需要执行以下步骤-

  1. 第一次设置LayoutManageradapter
  2. 在适配器类中创建setDataList方法。并将您的更新的列表设置为适配器列表。
  3. 然后每次调用API时,都要将该列表设置为setDataList,然后调用适配器类的adapter.notifyDataSetChanged()方法。

以上步骤将解决您的问题。试一试。


0
投票

您每次都设置一个新的适配器,并且新的布局管理器响应会出现。这可能会导致这种类型的问题。您需要在onCreate中设置适配器和布局管理器。只需更新适配器列表以响应api。

根据this答案,您仅需要线性布局管理器。

@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());
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.