Как обновить вложенный RecyclerView без прокрутки до первого элемента - PullRequest
0 голосов
/ 26 февраля 2019

У меня проблема в том, что я хочу обновить вложенный RecyclerView с динамической загрузкой данных.Внешний обзор recycler является вертикальным, а внутренний recyclerView - горизонтальным.Итак, я создал 2 адаптера.

Основное действие:

public class GroupScreenActivity extends AppCompatActivity {


    private RecyclerView recyclerView;
    private OuterRecyclerViewAdapter adapter;



    // the service connection
    private ServiceConnection connection = new ServiceConnection() {
         ... // code that handles the service connection (not relevant for my question)
        }
    };

    @Override
    protected void onStart(){
        // code that bind the service to the activity (not really relevant for my question)
    }

    @Override
    protected void onStop(){
    // code that unbinds the service from the activity (not really relevant for my question)
    }

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

        recyclerView = (RecyclerView) findViewById(R.id.recycler_View);

        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        updateUI();
    }

    // a Handler that calls a method of a bound service to retrieve the data of interest
    private void updateUI(final String token){

        final Handler handler = new Handler();

        handler.post(new Runnable() {
            @Override
            public void run() {
                if(bound && (mDownloadCliquesService != null)){

                    // holds the list of the statement lists
                    ArrayList<ArrayList<Statement>> myList = mDownloadCliquesService.getDataOfUser();

                    if(adapter == null){
                        // data is passed to the outer recyclerView adapter

                        adapter = new OuterRecyclerViewAdapter(this, myList);
                        recyclerView.setAdapter(adapter);
                    }
                    else{
                        // notify that the data is changed
                        adapter.notifyDataSetChanged();
                    }

                }
                // repeat the whole after 5 seconds
                handler.postDelayed(this, 5000);
            }
        });
    }
}

Как вы можете видеть: Основное действие просто извлекает некоторые данные из привязанного сервиса и передает их в представление внешнего переработчика.Данные представляют собой список списков типа Statement.Количество списков в myList дает строки внешнего просмотра переработчика, а элементы в каждом списке будут определять количество столбцов каждого внутреннего просмотра переработчика.

Внешний просмотр переработчика выглядит следующим образом:

public class OuterRecyclerViewAdapter extends RecyclerView.Adapter<OuterRecyclerViewAdapter.InnerRecyclerViewHolder> {


    // some instance variables

    public OuterRecyclerViewAdapter( ... ) {
        ...
    }


    @Override
    public InnerRecyclerViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {

        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.inner_recyclerview_layout, parent, false);

        return new InnerRecyclerViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final InnerRecyclerViewHolder holder, int position) {

        // here, I create the inner recycler view adapter. Do I need to update it too???
        adapter = new InnerRecyclerViewAdapter(context, items, position);

        holder.recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
        holder.recyclerView.setAdapter(adapter);
    }

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

    public class InnerRecyclerViewHolder extends RecyclerView.ViewHolder {

        private RecyclerView recyclerView;
        private Button mAddButton;
        private Button mSendButton;
        private TextView tvCliqueName;
        private ArrayList<Object> mList;


        public InnerRecyclerViewHolder(View itemView) {
            super(itemView);

            // using 'itemView', get a reference to the inner recycler view.
            recyclerView = (RecyclerView) itemView.findViewById(R.id.inner_recyclerView);

            // get a reference to the clique name
            tvCliqueName = (TextView) itemView.findViewById(R.id.cliqueName);

            // get a reference to the send button
            mSendButton = (Button) itemView.findViewById(R.id.send);

            // get a reference to the add button
            mAddButton = (Button) itemView.findViewById(R.id.add);

        }
    }

}

Ради краткости я не публикую код для внутреннего адаптера программы повторного просмотра, потому что нет ссылки на адаптер для обновления.Итак, через каждые 5 секунд основное действие получает свежие данные из моей связанной службы и передает их внешнему адаптеру повторного просмотра, который просматривает, сколько списков существует в списке вложенных массивов.Каждый список затем передается во внутренний адаптер представления переработчика, который затем показывает элементы каждого списка.Итак, моя проблема заключается в следующем: после каждого обновления список прокручивается к началу.Допустим, у меня есть 5 элементов в первом списке, и я перехожу к 3-му, после того как обновленное представление внутреннего переработчика автоматически переходит к 1-му.Вот краткий GIF как выглядит вывод:

enter image description here

Я проверил следующие сообщения StackOverflow: Как сохранить позицию прокрутки RecyclerViewиспользование RecyclerView.State?

Вложенные прокрутки Recyclerview самостоятельно прокручиваются

Как сохранить положение прокрутки в обзоре реселлера во фрагменте

Как сохранить положение прокрутки RecyclerView в Android?

Но безуспешно.Как мне обновить, чтобы положение прокрутки не изменилось?

Спасибо и всего наилучшего

1 Ответ

0 голосов
/ 27 февраля 2019

Сохраните значение горизонтальной прокрутки:

outerRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }

    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
        //save dx
    }
});

и восстановите после обновления: outerRecyclerView.setScrollX(dx)

...