How to stop refreshing recyclerview data scroll to top position android everytime
Asked Answered
C

6

5

I am trying to make a layout with recyclerview something like the video. I made a recyclerview which update list after certain interval but the problem is after data update it scroll to top position automatically. I want to make something like the video. https://youtu.be/omcS-6LeKoo I have tried with link from SO RecyclerView scrolls to top position when change the adapter data RecyclerView notifyDataSetChanged scrolls to top position but unable to solve. below is my attempt

@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());
            }
        });
    }
Cellarer answered 14/11, 2019 at 5:24 Comment(6)
Post your adapter codeInelegancy
adapter code : paste.org/101308Cellarer
instead of setting adapter again on refresh, just do notfyDataSetChanged()Skim
@Skim did not workCellarer
Need to see your adapter code then.Skim
@Skim check comment, i gave adapter code linkCellarer
B
4

These lines of code are causing the problem for you. You're setting a new adapter reference and linear layout manager reference every time of your API calling.

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

To Do your desired task you need to do following steps -

  1. Just set your LayoutManager and adapter for the first time.
  2. Make a setDataList method in your adapter class. And set your updated list to adapter list.
  3. And then every time of calling API set that list to setDataList and call adapter.notifyDataSetChanged() method of your adapter class.

The above steps will solve your problem. Just give it a try.

Boxfish answered 14/11, 2019 at 5:43 Comment(0)
U
2

The problem is probably because of you are setting new adapter reference in network callback method onResponse(). Try setting adapter in onCreate and then update dataset in callback.

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

In network callback,

@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  

            }
        }

Implement setDataSet() method in your adapter to update list like below.

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

      public void setDataSet(newList:List<>){ 
          list.clear();
          list.addAll(newList);
          notifyDataSetChanged();
      }
}
Upsurge answered 14/11, 2019 at 5:42 Comment(3)
let me time to give a tryCellarer
or if you still want to stick to a position just get that position and call this before notifying adapter recyclerView.scrollToPosition(pos); //use to focus the item with index adapter.notifyDataSetChanged();Maggi
your ans did not work too. list not showing up either.Cellarer
R
0

Don't use adapter.notifyDataSetChanged(); method because I think your main view must be wrap content so either set a fixed height like 150dp.

Try different methods like notifyItemChanged(), notifyItemRangeChanged(), notifyItemInserted()

Rhines answered 14/11, 2019 at 5:32 Comment(0)
C
0

You are setting adapter again and again when the response is changing, so you should change list and set adapter in 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());
            }
        });
    }
Cosmonaut answered 14/11, 2019 at 5:35 Comment(3)
had tried with this before but did not work. infact did not blink but not update the list items and views accordinglyCellarer
It seems there is an issue in your adapter, please check this #35147966Cosmonaut
Sorry can't open this link.Cosmonaut
H
0

You are setting a new adapter every time and a new layout manager response comes. which may cause this type of problem. you need to set adapter and layout manager in onCreate. just update adapter list in response of the api.

according to this answer you need linear layout manager only.

@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());
        }
    });
}
Heck answered 14/11, 2019 at 5:44 Comment(0)
E
0

you can do by following way

First get the count of your current datalist

int position = datalist.size();

after adding data into datalist call DataAdapter.notifyDataSetChanged();

then move cursor to position in recyclerview recyclerView.scrollToPosition(position);

Happy coding...!

Emlin answered 9/1, 2020 at 7:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.