如何更新嵌套的RecyclerView而不滚动到第一个项目

问题描述 投票:0回答:1

我有问题,我想用动态加载数据更新嵌套的RecyclerView。外部的recyclerView是垂直的,内部的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中的列表数量给出了外部recyclerview的行,每个列表中的项目将定义每个内部Recyclerview的列数。

外部回收站视图如下所示:

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

        }
    }

}

为简洁起见,我不发布内部recyclerview适配器的代码,因为没有适配器引用要更新。因此,每隔5秒钟后,主活动会从绑定服务中获取新数据,并将其传递给外部的recyclerview适配器,该适配器查看嵌套数组列表中存在多少列表。然后将每个列表传递给内部回收器视图适配器,然后显示每个列表的元素。所以,我的问题如下:每次更新后,列表都滚动到开头。假设我在第一个列表中有5个元素,并且在更新内部回收器视图自动转到第1个之后滚动到第3个元素。这是一个简短的GIF输出如何:

enter image description here

我查看了以下StackOverflow帖子:How to save RecyclerView's scroll position using RecyclerView.State?

Nested Recyclerview scrolls by itself

How to save scroll position of recyclerview in fragment

How to save scroll position of RecyclerView in Android?

但没有成功。如何更新以便滚动位置不受影响?

谢谢和最好的问候

android scroll android-recyclerview nested position
1个回答
0
投票

保存水平滚动值:

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)

© www.soinside.com 2019 - 2024. All rights reserved.