简体   繁体   English

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

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

I have a RecyclerView fetching data from an API.我有一个 RecyclerView 从 API 获取数据。 I am using Volley.我正在使用排球。 I am fetching data in batches of 20 items.我正在分批获取 20 个项目的数据。 I wish to set the scroll position using Linear Layout Manager myLLM.scrollToPositionWithOffset(x,y) so that when next batch of data is fetched the scroll position which currently resets to top is retained at the last item of previous batch.我希望使用线性布局管理器 myLLM.scrollToPositionWithOffset(x,y) 设置滚动 position,以便在获取下一批数据时,当前重置为顶部的滚动 position 保留在上一批的最后一项。

For this i need to add the following line of code at the place shown in the code below.为此,我需要在下面代码所示的位置添加以下代码行。

myLLM.scrollToPositionWithOffset(y,0);

But i am not able to do so.但我不能这样做。 Please guide me on how achieve this.请指导我如何实现这一目标。

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

} }

Following the advice from @mmmcho the issue was solved.按照@mmmcho 的建议,问题得到了解决。 "Set your adapter first, even if your list is empty. Update your list when you get the data. Then call adapter.notifydatasetchanged() method." “首先设置您的适配器,即使您的列表为空。获取数据时更新您的列表。然后调用 adapter.notifydatasetchanged() 方法。”

There is also a crude way of pagination implemented.还有一种粗略的分页方式。 So if someone is looking for easiest RecyclerView pagination, he can also follow the code.(Just have your api data sorted by date and it will work best.)因此,如果有人正在寻找最简单的 RecyclerView 分页,他也可以按照代码进行操作。(只需将您的 api 数据按日期排序,效果最佳。)

The code now looks like follows:代码现在如下所示:

public class ActivityItems extends AppCompatActivity {公共 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();
}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 RecyclerView scrollToPositionWithOffset与动画 - RecyclerView scrollToPositionWithOffset with animation Kotlin/RecyclerView:scrollToPositionWithOffset 未显示 - Kotlin/RecyclerView: scrollToPositionWithOffset Not Showing Up RecyclerView 上 LinearLayoutManager 的 scrollToPositionWithOffset 不起作用 - scrollToPositionWithOffset from LinearLayoutManager on RecyclerView not working 如何在NestedScrollView内的RecyclerView中滚动(x,y)? - How to scrollTo(x, y) in a RecyclerView inside a NestedScrollView? 如果RecyclerView太短,则Android LinearLayoutManager scrollToPositionWithOffset无法正常工作 - android LinearLayoutManager scrollToPositionWithOffset not work if RecyclerView is too short 如何在recyclerview中仅显示2个适合x和y的网格项? - How to show only 2 grid item in the recyclerview that fit in x and y? 如何设置x和y协调Android - how to set x and y coorinates android 如何在Android应用程序中设置x,y值? - How to set x,y value in android application? 如何设置scrollView scrollBy传感器x,y? - How to set scrollView scrollBy sensor x, y? 在使用layoutManager的scrollToPositionWithOffset时,项目的recyclerView之间为空白 - Blank between item's recyclerView when scrollToPositionWithOffset with layoutManager
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM