【问题标题】:RecyclerView already scrolled to bottom when activity starts活动开始时 RecyclerView 已经滚动到底部
【发布时间】:2017-09-02 23:04:56
【问题描述】:

我的活动中有带有 RecyclerView 的片段,但是每当我启动片段时,RecyclerView 已经滚动到底部。要加载更多项目,用户必须向上滚动一点,然后再滚动回底部,当加载更多项目时,RecyclerView 会再次滚动到新的底部。

这是片段中的代码。

public class FavouriteFragment extends Fragment{

public RecyclerView recyclerView ;
public RecyclerView.Adapter adapter ;
public LinearLayoutManager layoutManager ;

int pastVisiblesItems, visibleItemCount, totalItemCount;

Constants constants;
ArrayList<CardSetterGetter> arrayList;
private List<CardSetterGetter> imagelist;
int start ;
public int end ;
boolean loading = true ;
int totalcount ;
ArrayList<String> imageNameArray ;
String androidId;
String categoryName ;
String cateGoryFlag = "false";
String url;
String tagname = "";

ArrayList<String> title ;
ProgressBar progressBar ;

TextView errormsg ;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //to hide search
    setHasOptionsMenu(true);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
    MenuItem item = menu.findItem(R.id.search);
    item.setVisible(false);
}



@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.favourite_fragment,container,false);

    arrayList = new ArrayList<CardSetterGetter>();
    imageNameArray =  new ArrayList<String>();
    start = 0;
    end = start + 2 ;

    imagelist = new ArrayList<CardSetterGetter>();

    recyclerView = (RecyclerView)view.findViewById(R.id.recyclerview);
    progressBar = (ProgressBar)view.findViewById(R.id.progressBar);
    errormsg = (TextView) view.findViewById(R.id.error);

    getdata();

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if(dy > 0)
            {
                visibleItemCount = layoutManager.getChildCount();
                totalItemCount = layoutManager.getItemCount();
                pastVisiblesItems = layoutManager.findFirstVisibleItemPosition();
                int i = visibleItemCount + pastVisiblesItems ;
                System.out.println(i);
                System.out.println(totalItemCount);

                if(loading) {
                    if (i == totalItemCount) {
                        loading = false ;
                        start = arrayList.size() ;
                        end = arrayList.size() + 2 ;
                        requestWithSomeHttpHeaders2(start,end);
                        new Handler().postDelayed(new Runnable() { // This thread runs in the UI
                            @Override
                            public void run() {
                                loading = true;
                            }
                        },2000);
                    }
                }
            }
        }
    });
    requestWithSomeHttpHeaders2(start, end);

    return view ;
}

public void requestWithSomeHttpHeaders2(int s , int e) {
    RequestQueue queue = Volley.newRequestQueue(getActivity());

    url = "my url";

    StringRequest postRequest = new StringRequest(Request.Method.GET, url ,
            new Response.Listener<String> ()
            {
                @Override
                public void onResponse(String response) {
                    try {
                        progressBar.setVisibility(View.GONE);
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray payload = jsonObject.getJSONArray("Payload");
                        JSONObject MetaData = jsonObject.getJSONObject("MetaData");
                        System.out.println(response);
                        totalcount = MetaData.getInt("TotalCount");
                        System.out.println("200" + "    " + totalcount);
                        System.out.println("payload  length"+payload.length());

                        int i ;
                        for(i =0 ; i < payload.length() ; i++)
                        {

                            System.out.println(payload.getJSONObject(i).getString("image_title"));
                            System.out.println(payload.getJSONObject(i).getString("image_title"));
                            System.out.println(payload.getJSONObject(i).getString("image_file"));
                            System.out.println(payload.getJSONObject(i).getString("image_description"));
                            System.out.println(payload.getJSONObject(i).getString("image_category"));
                            System.out.println(payload.getJSONObject(i).getString("image_tags"));
                            System.out.println(payload.getJSONObject(i).getString("id"));
                            System.out.println(payload.getJSONObject(i).getString("favourite"));

                            String newString = payload.getJSONObject(i).getString("image_file").replace("original_image", "thumbnail");
                            CardSetterGetter all = new CardSetterGetter(payload.getJSONObject(i).getString("image_file"),
                                    payload.getJSONObject(i).getString("image_title"),
                                    payload.getJSONObject(i).getString("image_description"),
                                    payload.getJSONObject(i).getString("image_category"),
                                    payload.getJSONObject(i).getString("image_tags"),
                                    payload.getJSONObject(i).getString("id"),
                                    payload.getJSONObject(i).getString("favourite"));

                            System.out.println("i value is " + i);

                            arrayList.add(all);
                            Handler handler = new Handler();

                            final Runnable r = new Runnable() {
                                public void run() {
                                    adapter = new RecyclerViewAdapter(getActivity(),arrayList,imageNameArray,totalItemCount);
                                    recyclerView.setHasFixedSize(true);
                                    layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
                                    recyclerView.setLayoutManager(layoutManager);
                                    recyclerView.setAdapter(adapter);
                                    adapter.notifyDataSetChanged();
                                    //adapter.notifyItemInserted(arrayList.size() - 1);
                                    if (end >= totalcount)
                                    {
                                        int index = totalcount -1 ;
                                        recyclerView.scrollToPosition(index);
                                    }
                                    else {
                                        recyclerView.scrollToPosition(end);
                                    }
                                }
                            };

                            handler.post(r);

                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("error" + e);

                    }

                }

            },


            new Response.ErrorListener()
            {
                @Override
                public void onErrorResponse(VolleyError error) {


                    // TODO Auto-generated method stub
                    Log.d("ERROR","error => "+error.toString());
                    // definitions.setText("check your internet connection");
                    NetworkResponse networkResponse = error.networkResponse;
//                        Log.e("Volley", "Error. HTTP Status Code:"+networkResponse.statusCode);
                    if (networkResponse != null) {
                        Log.e("Volley", "Error. HTTP Status Code:"+networkResponse.statusCode);
                    }

                    if (error instanceof TimeoutError) {
                        Log.e("Volley", "TimeoutError");
                    }else if(error instanceof NoConnectionError){
                        Log.e("Volley", "NoConnectionError");
                    } else if (error instanceof AuthFailureError) {
                        Log.e("Volley", "AuthFailureError");
                    } else if (error instanceof ServerError) {
                        Log.e("Volley", "ServerError");
                    } else if (error instanceof NetworkError) {
                        Log.e("Volley", "NetworkError");
                    } else if (error instanceof ParseError) {
                        Log.e("Volley", "ParseError");
                    }
                }

            }

    );

    queue.add(postRequest);

}
public void getdata(){
    try {
        SharedPreferences sharedPref = getActivity().getSharedPreferences("mobileId" , Context.MODE_PRIVATE);
        androidId = sharedPref.getString("mobileId" , "");
        sharedPref = getActivity().getSharedPreferences("categoryInfo" , Context.MODE_PRIVATE);
        categoryName = sharedPref.getString("categoryName" , "");
        cateGoryFlag = sharedPref.getString("categoryFlag" , "");
        tagname = sharedPref.getString("tagname" , "");

    }catch (Exception e){

    }


}
}

我尝试删除 if else 部分代码,但这会使 recyclerView 在用户到达 recyclerView 底部时滚动到顶部。

如果您需要更多代码或RecyclerViewAdapter 的代码,请告诉我。

【问题讨论】:

  • 您是否尝试过使用其他 Manager 构造函数:LinearLayoutManager(activity,orientation, reverseLayout) ?如果我没记错的话,我在使用 RecyclerView 时遇到了类似的问题,我通过设置布局方向(垂直或水平,无论你需要什么)来解决它。
  • @EdoardoArnaudo 不,我没试过。我不知道该怎么做。你能发布一个答案来解释更多吗

标签: android android-fragments android-recyclerview


【解决方案1】:

我通过为布局管理器提供正确的方向解决了类似的问题。我会将您的代码更改为:

public RecyclerView.Adapter adapter ;
adapter = new RecyclerViewAdapter(getActivity(),arrayList,imageNameArray,totalItemCount);
recyclerView.setHasFixedSize(true);

//This line should do the trick:
//first parameter is the context
//second parameter is the orientation
//third parameter is used for reverse layout (if you need to show items from last to first)
layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);

//probably better to use notifyDataSetChanged to let the adapter know you just initialized it (instead of notifying a single element)
adapter.notifyDataSetChanged();

不确定为什么还要向适配器提供总项目数,但这超出了问题的范围,肯定不会产生任何问题。

编辑: 现在您发布了整个片段代码,我发现至少有几个问题: - RecyclerView 的初始化不应该在可运行文件中,而应该在 onCreateView 或一些启动函数中。您只需要设置一次管理器和适配器。 - 您向适配器提供imageNameArray,但您在哪里插入新项目?如果您希望 RecyclerView 向下滚动到最后插入的项目,您首先需要向 ArrayList 添加一个项目,然后通知该位置的插入,如下所示:

int position = imageNameAray.size();
imageNameArray.add(item);
adapter.notifyItemInserted(position); //this makes the view update the item in that position, making the recycler to scroll there

【讨论】:

  • 感谢您的帮助,但没有奏效。 recyclerView 的行为与更改之前完全相同。我是否应该保留这些更改,即使它们没有任何区别?
  • 是的,明确布局方向肯定更好!如果您从片段中提供更多代码可能会有所帮助,例如:您在哪里初始化 recyclerView,您如何获取数据......仅使用该 sn-p 可能还不够。旁注:如果可以,请避免手动调用 scrollToPosition,如果配置正确,回收器应该会正常运行。
  • 立即查看代码。我添加了整个片段的代码。
  • 首先请帮助我了解您在哪里将项目插入到 arrayList 中!您不必(也不应该)在每一步都设置 recyclerView,而是应该初始化一次,然后在 arrayList 中插入每个新项目并通知适配器(请记住,您提供了对适配器的 arrayList 引用,所以它已经可以访问整个列表)。
  • 好的,感谢您为 btw 付出的努力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
相关资源
最近更新 更多