如何设置RecyclerView的scrollToPositionWithOffset(x,y)?

How to set the scrollToPositionWithOffset(x,y) of RecyclerView?

我有一个从 API 获取数据的 RecyclerView。我正在使用排球。 我正在分批获取 20 个项目的数据。 我希望使用线性布局管理器 myLLM.scrollToPositionWithOffset(x,y) 设置滚动位置,以便在获取下一批数据时,当前重置为顶部的滚动位置保留在上一批的最后一项。

为此,我需要在下面代码所示的位置添加以下代码行。

myLLM.scrollToPositionWithOffset(y,0);

但是我做不到。请指导我如何实现这一目标。

public class ActivityItems extends AppCompatActivity {

private RecyclerView myRvItems;
private ItemsAdapter myItemsAdapter;
private ArrayList<ItemsModel> myItemsFeedList;
private RequestQueue myRequestQueue;
private ProgressBar itemsProgressBar;
Boolean isScrolling = false;
int currentItems, totalItems, scrolledOutItems, x = 0, y = (x + 20);

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

    getSupportActionBar().setTitle("Inventory Items");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    myRvItems = findViewById(R.id.rvItems);
    itemsProgressBar = findViewById(R.id.pbItems);

    final LinearLayoutManager myLLM = new LinearLayoutManager(this);
    myRvItems.setLayoutManager(myLLM);

    myItemsFeedList = new ArrayList<>();
    myRequestQueue = Volley.newRequestQueue(this);

    parseJSON();

    myRvItems.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if(newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
                isScrolling = true;
            }
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            currentItems = myLLM.getChildCount();
            totalItems = myLLM.getItemCount();
            scrolledOutItems = myLLM.findFirstVisibleItemPosition();

            if(isScrolling && (currentItems + scrolledOutItems == totalItems)){
                isScrolling = false;
                parseJSON();
                myLLM.scrollToPositionWithOffset(4, 20);
            }
        }
    });

}

private void parseJSON() {

    itemsProgressBar.setVisibility(View.VISIBLE);
    String url = "http://restapis.xyv.com/api/list";

    JsonObjectRequest myRequest = new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {

                    try {
                        JSONArray myJSONArray = response.getJSONArray("Data");

                        for (int i = x; i < y && i < myJSONArray.length(); i++){

                            JSONObject myData = myJSONArray.getJSONObject(i);

                            String itemID = myData.getString("ItemID");
                            String itemName = myData.getString("ItemName");
                            String itemRackNo = myData.getString("RackNo");

                            myItemsFeedList.add(new ItemsModel(itemID,itemName,itemRackNo));

    **//   I WANT TO SET THE SCROLL POSITION HERE BUT THIS NOT WORKING**
    **//   myLLM.scrollToPositionWithOffset(y,0);**

                        }

                        myItemsAdapter = new ItemsAdapter(myItemsFeedList,ActivityItems.this );
                        myRvItems.setAdapter(myItemsAdapter);
                        itemsProgressBar.setVisibility(View.GONE);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    myRequestQueue.add(myRequest);

}

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return super.onSupportNavigateUp();
}

}

根据@mmmcho 的建议,问题已解决。 "Set your adapter first, even if your list is empty. Update your list when you get the data. Then call adapter.notifydatasetchanged() method."

还有一种粗略的分页方式。因此,如果有人正在寻找最简单的 RecyclerView 分页,他也可以按照代码进行操作。(只要让您的 api 数据按日期排序,效果最好。)

代码现在如下所示:

public class ActivityItems 扩展 AppCompatActivity {

private RecyclerView myRvItems;
private ItemsAdapter myItemsAdapter;
private ArrayList<ItemsModel> myItemsFeedList;
private RequestQueue myRequestQueue;
private ProgressBar itemsProgressBar;
Boolean isScrolling = false;
int currentItems, totalItems, scrolledOutItems, fetchSize = 6 , x = 0, y = (x + fetchSize);

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

    getSupportActionBar().setTitle("Inventory Items");
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    myRvItems = findViewById(R.id.rvItems);
    itemsProgressBar = findViewById(R.id.pbItems);

    final LinearLayoutManager myLLM = new LinearLayoutManager(this);
    myRvItems.setLayoutManager(myLLM);

    myItemsFeedList = new ArrayList<>();
    myItemsAdapter = new ItemsAdapter(myItemsFeedList,ActivityItems.this );
    myRvItems.setAdapter(myItemsAdapter);

    myRequestQueue = Volley.newRequestQueue(this);

    parseJSON();


    myRvItems.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if(newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
                isScrolling = true;
            }
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            currentItems = myLLM.getChildCount();
            totalItems = myLLM.getItemCount();
            scrolledOutItems = myLLM.findFirstVisibleItemPosition();

            if(isScrolling && (currentItems + scrolledOutItems == totalItems)){
                isScrolling = false;
                y = x + fetchSize;
                parseJSON();

            }
        }
    });

}

private void parseJSON() {

    itemsProgressBar.setVisibility(View.VISIBLE);
    String url = "http://restapis.xyn.com/api/list";

    JsonObjectRequest myRequest = new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {

                    try {
                        JSONArray myJSONArray = response.getJSONArray("Data");

                        for (int i = x; i < y && i < myJSONArray.length(); i++){

                            JSONObject myData = myJSONArray.getJSONObject(i);

                            String itemID = myData.getString("ItemID");
                            String itemName = myData.getString("ItemName");
                            String itemRackNo = myData.getString("RackNo");

                            myItemsFeedList.add(new ItemsModel(itemID,itemName,itemRackNo));
                            x = x+1;
                        }

                        myItemsAdapter.notifyDataSetChanged();
                        itemsProgressBar.setVisibility(View.GONE);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    myRequestQueue.add(myRequest);

}

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return super.onSupportNavigateUp();
}}