【问题标题】:GridView Always Scroll To The Top After Success Load Next Page成功加载下一页后,GridView总是滚动到顶部
【发布时间】:2017-09-18 12:31:15
【问题描述】:

我在使用recyclerviewGridview 工作时遇到了困难。问题是当我的应用程序成功加载下一页(下一个数据)时,recyclerview 总是回到顶部。

我希望 recyclerview 从最后一个索引开始。

示例:首页加载 10 个项目,成功借出下一页后,回收站视图从项目 8 开始滚动。

为了解决这个问题,我已经尝试了stackoverflow上的所有解决方案,但仍然一无所获。

这是我的代码:

package com.putuguna.sitehinduapk.adapters;

import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.putuguna.sitehinduapk.R;
import com.putuguna.sitehinduapk.activities.DetailBlogPostActivity;
import com.putuguna.sitehinduapk.models.listposts.ItemPostModel;
import com.putuguna.sitehinduapk.utils.GlobalFunction;
import com.putuguna.sitehinduapk.utils.GlobalVariable;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



public abstract class ListPostAdapter extends RecyclerView.Adapter<ListPostAdapter.ViewHolder>{

    private List<ItemPostModel> mListPost;
    private Context mContext;

    public ListPostAdapter(List<ItemPostModel> mListPost, Context mContext) {
        this.mListPost = mListPost;
        this.mContext = mContext;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.adapter_item_list_post, null);
        return new ViewHolder(view);

    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        final ItemPostModel post = mListPost.get(position);

        List<String> listURL = extractUrls(post.getContentPosting());

        Glide.with(mContext)
                .load(listURL.get(0))
                .into(holder.ivImagePost);

        holder.tvTitle.setText(post.getTitle());

        holder.llItemPost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //TO DO OnClick
            }
        });
        List<String> listLabel = post.getListLabel();
        String labelPost="";
        for(int i=0; i<listLabel.size();i++){
            labelPost += "#"+listLabel.get(i) + " ";
        }
        holder.tvLabel.setText(labelPost);

        if ((position >= getItemCount() - 1))
            load();
    }

    public abstract void load();


    @Override
    public int getItemCount() {
        return mListPost.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{

        public ImageView ivImagePost;
        public TextView tvTitle;
        public LinearLayout llItemPost;
        public TextView tvLabel;

        public ViewHolder(View itemView) {
            super(itemView);

            ivImagePost = (ImageView) itemView.findViewById(R.id.iv_image_post);
            tvTitle = (TextView) itemView.findViewById(R.id.tv_blog_title);
            llItemPost = (LinearLayout) itemView.findViewById(R.id.ll_item_post);
            tvLabel = (TextView) itemView.findViewById(R.id.textview_label_adapter);
        }
    }

    public static List<String> extractUrls(String input) {
        List<String> result = new ArrayList<String>();

        Pattern pattern = Pattern.compile(
                "\\b(((ht|f)tp(s?)\\:\\/\\/|~\\/|\\/)|www.)" +
                        "(\\w+:\\w+@)?(([-\\w]+\\.)+(com|org|net|gov" +
                        "|mil|biz|info|mobi|name|aero|jobs|museum" +
                        "|travel|[a-z]{2}))(:[\\d]{1,5})?" +
                        "(((\\/([-\\w~!$+|.,=]|%[a-f\\d]{2})+)+|\\/)+|\\?|#)?" +
                        "((\\?([-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?" +
                        "([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)" +
                        "(&(?:[-\\w~!$+|.,*:]|%[a-f\\d{2}])+=?" +
                        "([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)*)*" +
                        "(#([-\\w~!$+|.,*:=]|%[a-f\\d]{2})*)?\\b");

        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) {
            result.add(matcher.group());
        }

        return result;
    }
}

MainActivity.java这个代码

 private void getListPost(){
        mSwipeRefreshLayout.setRefreshing(true);

        String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);

        BloggerApiService apiService = BloggerApiClient.getClient().create(BloggerApiService.class);
        Call<ListPostModel> call = apiService.getListPost(GlobalVariable.APP_KEY_V3);

        call.enqueue(new Callback<ListPostModel>() {
            @Override
            public void onResponse(Call<ListPostModel> call, Response<ListPostModel> response) {
                ListPostModel listpost = response.body();
                initDataView(listpost);
                mSwipeRefreshLayout.setRefreshing(false);

            }

            @Override
            public void onFailure(Call<ListPostModel> call, Throwable t) {
                mSwipeRefreshLayout.setRefreshing(false);
                Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });

    }

    /**
     * this method used for post (next page)
     */
    private void getNextListPost(){
        mSwipeRefreshLayout.setRefreshing(true);

        String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
        BloggerApiService apiService = BloggerApiClient.getClient().create(BloggerApiService.class);
        Call<ListPostModel>  call = apiService.getNexPageListPost(GlobalVariable.APP_KEY_V3,nextPageToken);

        call.enqueue(new Callback<ListPostModel>() {
            @Override
            public void onResponse(Call<ListPostModel> call, Response<ListPostModel> response) {
                ListPostModel listpost = response.body();
                initDataView2(listpost);
                mSwipeRefreshLayout.setRefreshing(false);

            }

            @Override
            public void onFailure(Call<ListPostModel> call, Throwable t) {
                mSwipeRefreshLayout.setRefreshing(false);
                Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });

    }


    @Override
    public void onRefresh() {
        mListPost.clear();
        getListPost();
    }

    private void initDataView(ListPostModel listpost){
        GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
        mListPost.addAll(listpost.getListItemsPost());
        mPostAdapter = new ListPostAdapter(mListPost, this) {
            @Override
            public void load() {
                ItemPostModel item = mListPost.get(mListPost.size()-1);
                getNextListPost();
            }
        };

        mRecyclerviewPost.setAdapter(mPostAdapter);
        //mPostAdapter.notifyDataSetChanged();

        mRecyclerviewPost.setHasFixedSize(true);
        mGridViewLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
        mGridViewLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
        mRecyclerviewPost.setLayoutManager(mGridViewLayoutManager);
    }


    /**
     * this method used for set view (next page)
     * @param listpost
     */
    private void initDataView2(ListPostModel listpost){
        GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
        final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
        List<ItemPostModel> itemNextPost = listpost.getListItemsPost();
//        itemNextPost.addAll(mListPost);
        mListPost.addAll(itemNextPost);
        mPostAdapter = new ListPostAdapter(mListPost, this) {
            @Override
            public void load() {
                ItemPostModel item = mListPost.get(mListPost.size()-1);
                if(nextPageToken==null){

                }else{
                    getNextListPost();
                }
            }
        };

        mRecyclerviewPost.setAdapter(mPostAdapter);
        mRecyclerviewPost.setHasFixedSize(true);
        mGridViewLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
        mGridViewLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
        mRecyclerviewPost.setLayoutManager(mGridViewLayoutManager);
an
    }

任何建议将不胜感激。

【问题讨论】:

    标签: android gridview pagination android-recyclerview


    【解决方案1】:

    代码的问题是,您将完整的数据再次重置到适配器中并再次将其设置为 RecyclerView,这就是为什么它在 RecyclerView 中重新实例化所有内容,即滚动到顶部。取而代之的是,您可以尝试将更新的数据添加/追加到列表中(保存数据的位置),然后调用adapter.notifyDataSetChanged(); 方法。它会自动添加更新的数据,您无需再次设置回收站视图。

    可能对于您的情况,您需要更改您的initDataView2() mehtod,如下所示

      private void initDataView2(ListPostModel listpost){
            GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
             mListPost.addAll(listpost.getListItemsPost());\
             mPostAdapter .notifyDataSetChanged();
        }
    

    对于 nextPageToken 的事情,你可以进入你的主代码 onCreate() 或你已经有适配器初始化的 initDataView() 方法

    像这样,

      private void initDataView(ListPostModel listpost){
            GlobalFunction.saveString(this,GlobalVariable.keySharedPreference.TOKEN_PAGINATION, listpost.getNextPageToken());
            final String nextPageToken = GlobalFunction.getStrings(this, GlobalVariable.keySharedPreference.TOKEN_PAGINATION);
            mListPost.addAll(listpost.getListItemsPost());
            mPostAdapter = new ListPostAdapter(mListPost, this) {
                @Override
                public void load() {
                    ItemPostModel item = mListPost.get(mListPost.size()-1);
                    if(nextPageToken==null){
    
                    }else{
                        getNextListPost();
                    }
                }
            };
    
            mRecyclerviewPost.setAdapter(mPostAdapter);
            //mPostAdapter.notifyDataSetChanged();
    
            mRecyclerviewPost.setHasFixedSize(true);
            mGridViewLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
            mGridViewLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
            mRecyclerviewPost.setLayoutManager(mGridViewLayoutManager);
        }
    

    我希望它会起作用:)

    【讨论】:

    • 谢谢兄弟,您的代码使recyclerview 从最后一项滚动,但它带来了新问题,mListPost 总是从头开始添加第一个数据。如何解决?
    • 很高兴听到这个消息。但我没有得到你。您能否详细说明一下新问题?这样我可以帮助你
    • 例如:第一页有1-10条,下一页有11-20条。在mListPost 添加最后一项(11-20)之后,mListPost 再次添加第一页 1-10 项和下一页 11-20 项。没有尽头。
    • 好的,知道了。您确定仅从 getNextListPost() API > 获取更新数据,即(11-20)吗?如果是,则不会产生问题,但实际上并非如此。他们再次给出总数 1-20 ,以便它也绑定该数据。请检查一次
    • 谢谢@King of Masses 兄弟!通过一点点修改你的代码就像我需要的那样工作得很好。赞赏!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2017-03-21
    • 2012-04-04
    • 1970-01-01
    • 2016-08-26
    • 2020-07-11
    相关资源
    最近更新 更多