简体   繁体   中英

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

I have a RecyclerView fetching data from an API. I am using Volley. I am fetching data in batches of 20 items. 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.

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. "Set your adapter first, even if your list is empty. Update your list when you get the data. Then call adapter.notifydatasetchanged() method."

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

The code now looks like follows:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM