【问题标题】:OnLoadMore Functionality using RecyclerView使用 RecyclerView 的 OnLoadMore 功能
【发布时间】:2019-01-21 11:27:17
【问题描述】:

尝试应用 onLoadmore 功能,在我更新每个请求的适配器后 Recyclerview 带到第一个元素,我想从最后添加的列表中继续查看

MainActivity 代码:

    public class Inbox extends Fragment {
private  RecyclerView mRecycler;
private  InboxAdapter mAdapter;
SwipeRefreshLayout swipeContainer;
TextView txtnomail;
static String strtoken;
static int inboxcount;
ImageView Img;
List<MailDataModel> data = new ArrayList<>();
private  Context context = null;
int page;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View rootview=inflater.inflate(R.layout.fragment_inbox, container, false);
    Img=rootview.findViewById(R.id.gifloader);
    mRecycler = (RecyclerView)rootview.findViewById(R.id.inbox_recycler);
    txtnomail = (TextView) rootview.findViewById(R.id.nomail_inbox);
    swipeContainer=(SwipeRefreshLayout)rootview.findViewById(R.id.swipeContainer_inbox);
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
    SharedPreferences.Editor editor = prefs.edit();
    inboxcount = prefs.getInt("inboxcount", 0);
    editor.apply();
    MainActivity activity = (MainActivity) getActivity();
    assert activity != null;
    strtoken = activity.getMyData();
    RetrieveInboxMails retrieveInboxMails=new RetrieveInboxMails();
    retrieveInboxMails.execute(String.valueOf(page));
    context=getActivity();

    swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            RetrieveInboxMails retrieveInbox=new RetrieveInboxMails();
            retrieveInbox.execute(String.valueOf(page));
        }
    });
    // Configure the refreshing colors
    swipeContainer.setColorSchemeResources(
            android.R.color.holo_blue_light,
            android.R.color.holo_blue_light,
            android.R.color.holo_blue_light,
            android.R.color.holo_blue_dark);
    mAdapter = new InboxAdapter(mRecycler, context, data);
    mRecycler.setAdapter(mAdapter);
    mAdapter.notifyItemInserted(data.size());
    return rootview;
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    //you can set the title for your toolbar here for different fragments different titles
    getActivity().setTitle("Inbox");
}


public  class RetrieveInboxMails extends AsyncTask<String, String, String> {


    List<MailDataModel> tempdata = new ArrayList<>();
    final MailDataModel health = new MailDataModel();

    @Override
    protected void onPreExecute() {


        //  Img.setVisibility(View.VISIBLE);
        //  txtnomail.setVisibility(View.GONE);



    }
    @Override
    protected String doInBackground(String... strings) {
        try {


            String pages=strings[0];
            // Creating & connection Connection with url and required Header.
            URL url = new URL("http://api- 
         telemed.3cubehealth.com/api/fetchLocalEmails? 
        category=inbox&limit="+10+"&page="+pages);
            // URL url = new URL("http://api- 
           telemed.3cubehealth.com/api/fetchLocalEmails? 
             category=inbox&limit=10&page=0");
            HttpURLConnection urlConnection = (HttpURLConnection) 
              url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setRequestProperty("Content-Type",  
             "application/json");
            urlConnection.setRequestProperty("Authorization", "Bearer " + 
           strtoken);
            urlConnection.setDoInput(true);
            //POST or GET
            urlConnection.connect();
            int statusCode = urlConnection.getResponseCode();
            // Connection success. Proceed to fetch the response.
            if (statusCode == 200) {
                InputStream it = new 
              BufferedInputStream(urlConnection.getInputStream());
                InputStreamReader read = new InputStreamReader(it);
                BufferedReader buff = new BufferedReader(read);
                StringBuilder dta = new StringBuilder();
                String chunks;
                while ((chunks = buff.readLine()) != null) {
                    dta.append(chunks);
                }
                chunks = dta.toString();
                return chunks;
            }
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return strtoken;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        swipeContainer.setRefreshing(false);
        Img.setVisibility(View.GONE);
        try {
            JSONArray jsonArray = new JSONArray(result);
            // Extract data from json and store into ArrayList as class 
             objects
            for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject json_data = jsonArray.getJSONObject(i);
                health.setVessalName(json_data.getString("from_name"));
                health.setEmailId(json_data.getString("from_email"));
                health.setId(json_data.getInt("id"));
                health.setSubject(json_data.getString("subject"));
                health.setTransId(json_data.getInt("trans_id"));
                String date = json_data.getString("message_date");
                String message = json_data.getString("message_html");
                health.setStatus(json_data.getString("email_status"));
                if (context != null) {
                    SharedPreferences prefs_file = 
                PreferenceManager.getDefaultSharedPreferences(context);
                    SharedPreferences.Editor editor_file = prefs_file.edit();
                    editor_file.putString("result", result);
                    editor_file.apply();
                }

                health.setMessage(message);
                DateFormat inputFormatter1 = new SimpleDateFormat("yyyy-MM- 
                                                                  dd");
                Date date1 = inputFormatter1.parse(date);

                DateFormat outputFormatter1 = new SimpleDateFormat("d MMM");
                String output1 = outputFormatter1.format(date1);
                health.setDate(output1);
                data.add(health);

                if (context != null) {
                    mRecycler.setLayoutManager(new 
                LinearLayoutManager(context));




                }
            }
            mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
                @Override
                public void onLoadMore() {
                    if (data.size() <=inboxcount) {
                        data.add(null);
                        mAdapter.notifyItemInserted(data.size());
                        new Handler().postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                data.remove(data.size() -1);
                                mAdapter.notifyItemRemoved(data.size());

                                page++;
                                new 
                   RetrieveInboxMails().execute(String.valueOf(page));
                                mAdapter.notifyDataSetChanged();
                                mAdapter.setLoaded();
                            }
                        }, 2000);
                    } else {
                        Toast.makeText(context, "Loading data completed", 
              Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
        catch(JSONException e){
            e.printStackTrace();
        } catch(ParseException e){
            e.printStackTrace();
        }
    }
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
    MenuItem mSearchMenuItem = menu.findItem(R.id.option_menu_search);
    SearchView searchView = (SearchView) mSearchMenuItem.getActionView();
    searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);

    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {

            mAdapter.getFilter().filter(newText);
            return false;
        }
    });


}




    }

适配器代码:

    public class InboxAdapter  extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
Context mcontext;
LayoutInflater inflater;
List<MailDataModel> mailDataModelList;
List<MailDataModel> exampleListFull;
final int VIEW_TYPE_ITEM = 0;
final int VIEW_TYPE_LOADING = 1;
boolean isLoading;
private int visibleThreshold = 8;
private int lastVisibleItem, totalItemCount;
OnLoadMoreListener onLoadMoreListener;

public InboxAdapter(RecyclerView recyclerView, Context context,List<MailDataModel> mailDataModelList) {
    this.mcontext = context;
    // this.inflater = LayoutInflater.from(context);
    this.inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.mailDataModelList = mailDataModelList;
    exampleListFull=new ArrayList<>(mailDataModelList);
    notifyItemRangeChanged(0, mailDataModelList.size()-1);

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
            totalItemCount = linearLayoutManager.getItemCount();
            lastVisibleItem = linearLayoutManager.findFirstVisibleItemPosition();

// lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

            if (!isLoading&&totalItemCount <= (lastVisibleItem + visibleThreshold)) {
                if (onLoadMoreListener != null) {
                    onLoadMoreListener.onLoadMore();
                }
                isLoading = true;
            }

        }
    });

}

@Override
public int getItemViewType(int position) {
    return mailDataModelList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == VIEW_TYPE_ITEM) {
        View view = LayoutInflater.from(mcontext).inflate(R.layout.layout_unread, parent, false);
        return new InboxMailsHolder(view);
    } else if (viewType == VIEW_TYPE_LOADING) {
        View view = LayoutInflater.from(mcontext).inflate(R.layout.item_loading, parent, false);
        return new LoadingViewHolder(view);
    }
    return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof InboxMailsHolder) {
        final MailDataModel data = mailDataModelList.get(position);
        final InboxMailsHolder inboxdMailsHolder = (InboxMailsHolder) holder;
        inboxdMailsHolder.date.setText(data.getDate());
        inboxdMailsHolder.subject.setText(data.getSubject());
        switch (data.getStatus()) {
            case "Read":
                inboxdMailsHolder.cardView.setBackgroundColor(Color.WHITE);
                break;
            case "Sent":
                inboxdMailsHolder.cardView.setBackgroundColor(Color.WHITE);
                break;

// 案例“未读”: // inboxdMailsHolder.cardView.setBackgroundColor(Color.parseColor("#EBEBEB")); 默认: inboxdMailsHolder.cardView.setBackgroundColor(Color.parseColor("#EBEBEB")); 休息; } if (data.getVessalName().equals("null")) { inboxdMailsHolder.emailid.setText(data.getEmailId());

        } else {
            inboxdMailsHolder.emailid.setText(data.getVessalName());
        }

        inboxdMailsHolder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new UnReadAdapter.MailStatusAsync(mcontext).execute(String.valueOf(data.getId()));
                inboxdMailsHolder.subject.setTypeface(null, Typeface.NORMAL);
                inboxdMailsHolder.cardView.setBackgroundColor(Color.WHITE);
                Intent email_intent = new Intent(view.getContext(), MailDetails.class);
                email_intent.putExtra("Date", data.getDate());
                email_intent.putExtra("TransId", data.getTransId());
                email_intent.putExtra("Id", data.getId());
                email_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mcontext.startActivity(email_intent);
            }
        });
    }
    else if (holder instanceof LoadingViewHolder) {
        LoadingViewHolder loadingViewHolder = (LoadingViewHolder) holder;
        loadingViewHolder.progressBar.setIndeterminate(false);
    }
}


@Override
public int getItemCount() {
    return mailDataModelList == null ? 0 : mailDataModelList.size();
}

public void setLoaded() {
    isLoading = false;
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
    public ProgressBar progressBar;

    public LoadingViewHolder(View view) {
        super(view);
        progressBar = (ProgressBar) view.findViewById(R.id.progressBar1);
    }
}
public class InboxMailsHolder extends RecyclerView.ViewHolder{
    TextView emailid,subject,date;
    CardView cardView;
    public InboxMailsHolder(@NonNull View itemView) {
        super(itemView);
        emailid=itemView.findViewById(R.id.email_id);
        subject=itemView.findViewById(R.id.subject);
        date=itemView.findViewById(R.id.date);
        cardView=itemView.findViewById(R.id.mailcard);
    }
}
@Override
public Filter getFilter() {
    return exampleFilter;
}

private Filter exampleFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<MailDataModel> filteredList = new ArrayList<>();

        if (constraint == null || constraint.length() == 0) {

            filteredList.addAll(exampleListFull);
        } else {
            String filterPattern = constraint.toString().toLowerCase().trim();

            for (MailDataModel item : exampleListFull) {
                if (item.getEmailId().toLowerCase().contains(filterPattern)||item.getSubject().toLowerCase().contains(filterPattern)||item.getMessage().toLowerCase().contains(filterPattern)|| item.getStatus().toLowerCase().contains(filterPattern)) {
                    filteredList.add(item);
                }
            }
        }

        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        mailDataModelList.clear();
        mailDataModelList.addAll((List) results.values);
        notifyDataSetChanged();
    }
};
public void setOnLoadMoreListener(OnLoadMoreListener mOnLoadMoreListener) {
    this.onLoadMoreListener = mOnLoadMoreListener;
}

}

【问题讨论】:

  • 请同时添加代码。
  • 请立即查看
  • 使用google的paging支持库
  • 但这现在几乎完成了,数据是逐页加载的,唯一的问题是适配器在新请求后附加新数据后,回收器视图刷新页面并显示第一个数据
  • 当您将项目添加到您的列表时调用notifyDataSetChanged() 方法而不是此notifyItemInserted(data.size()); 更新您的列表,然后调用此方法notifyDataSetChanged()

标签: java android


【解决方案1】:

每当您获得调用此方法的新项目列表时,您都可以更新您的适配器,从响应传递到此方法获取 MailDataModel 列表。

更新适配器

public void updateAdapter(List<MailDataModel> mailDataModelList){
 for (MailDataModel mailDataModel : mailDataModelList) {
                data.add(mailDataModel);
            }
            mAdapter.setLoaded();
            mAdapter.notifyDataSetChanged();
}

【讨论】:

  • 获取 java.util.ConcurrentModificationException 指向 (MailDataModel mailDataModel : mailDataModelList) { 的行
  • @user10390792 ConcurrentModificationException 发生在您修改列表(通过添加或删除元素)同时使用 Iterator 遍历列表时,因此当您获得响应时分配给新的 ArrayList 并发送到此方法please have look at it
【解决方案2】:

请试试下面的代码,可能有帮助

public void updateAdapter(List<MailDataModel> mailDataModelList){
    data.clear();
    for (int i = mailDataModelList.size(); i <= 0 ; i--) {
        data.add(mailDataModel);  
    }
    mAdapter.setLoaded();
    mAdapter.notifyDataSetChanged();
}

我刚刚清理了以前的数据并以相反的顺序添加了新数据,以便最新的数据位于顶部。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 2019-12-26
    • 2017-07-09
    相关资源
    最近更新 更多