【问题标题】:Android Recyclerview load more on scrolltopAndroid Recyclerview 在滚动顶部加载更多
【发布时间】:2016-10-04 23:56:51
【问题描述】:

嘿社区我想在聊天应用程序中创建一个RecyclerView

我试过setStackFromEnd,效果很好。

final LinearLayoutManager llm = new LinearLayoutManager(getApplicationContext());
    llm.setOrientation(LinearLayoutManager.VERTICAL);
    llm.setStackFromEnd(true);

我在加载更多基于本教程的代码,在教程结束时你应该会看到一个视频:Recyclerview Bottom Progress

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            totalItemCount = linearLayoutManager.getItemCount();
            lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();

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

所以我需要在聊天应用程序中创建一个RecyclerView。从头开始的堆栈运行良好,但是当我到达顶部而不是到达底部时,我需要触发加载更多方法。还要在顶部而不是底部添加新项目。提前致谢。

【问题讨论】:

  • 您是自动加载较早的消息,还是希望在顶部显示一个“加载较早的消息”按钮,例如 whatsapp,然后单击该按钮,以加载较早的消息?
  • @MukeshRana 是的,这正是我想做的。

标签: android android-recyclerview


【解决方案1】:

如果您只想在顶部显示Button“加载早期消息”,则无需使用onScrollListener。您可以简单地为您的负载创建一个xml 更多Button,将其作为RecyclerView 的第一行并创建一个Interface 来处理点击事件。我正在从我的一个项目中发布Adpater 的代码。希望这将有助于您获得一些想法以进一步进行。

/**
 * Created by Mukesh on 21/12/2015.
 */
public class ChatListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context mContext;
    private List<UserMessage> userMessagesList;
    private LayoutInflater mLayoutInflater;
    private static final int ROW_TYPE_LOAD_EARLIER_MESSAGES = 0;
    private static final int ROW_TYPE_SENDER = 1;
    private static final int ROW_TYPE_RECEIVER = 2;
    private int userId;
    private boolean isLoadEarlierMsgs;
    private LoadEarlierMessages mLoadEarlierMessages;

    public ChatListAdapter(Context context, int userId, List<UserMessage> userMessagesList) {
        mContext = context;
        this.userMessagesList = userMessagesList;
        mLayoutInflater = LayoutInflater.from(mContext);
        this.userId = userId;
        mLoadEarlierMessages = (LoadEarlierMessages) mContext;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case ROW_TYPE_LOAD_EARLIER_MESSAGES:
                return new LoadEarlierMsgsViewHolder(mLayoutInflater.inflate(R.layout
                        .row_load_earlier_messages, parent, false));
            case ROW_TYPE_SENDER:
                return new SenderMsgViewHolder(mLayoutInflater.inflate(R.layout.row_sender_msg,
                        parent, false));
            case ROW_TYPE_RECEIVER:
                return new ReceiverMsgViewHolder(mLayoutInflater.inflate(R.layout
                        .row_receiver_msg, parent, false));
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (getItemViewType(position)) {
            case ROW_TYPE_LOAD_EARLIER_MESSAGES:
                LoadEarlierMsgsViewHolder loadEarlierMsgsViewHolder =
                        (LoadEarlierMsgsViewHolder) holder;
                if (isLoadEarlierMsgs) {
                    loadEarlierMsgsViewHolder.btLoadEarlierMessages
                            .setOnClickListener(new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    if (mLoadEarlierMessages != null) {
                                        mLoadEarlierMessages.onLoadEarlierMessages();
                                    }
                                }
                            });
                } else {
                    loadEarlierMsgsViewHolder.btLoadEarlierMessages.setVisibility(View.GONE);
                }
                break;
            case ROW_TYPE_SENDER:
                SenderMsgViewHolder senderMsgViewHolder = (SenderMsgViewHolder) holder;
                // set data for your sender chat bubble
                break;
            case ROW_TYPE_RECEIVER:
                ReceiverMsgViewHolder receiverMsgViewHolder = (ReceiverMsgViewHolder) holder;
                // set data for your receiver chat bubble
                break;
        }
    }

    @Override
    public int getItemCount() {
        return userMessagesList.size() + 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return ROW_TYPE_LOAD_EARLIER_MESSAGES; // row load earlier messages
        } else if (userMessagesList.get(position - 1).getUser_id() == userId) {
            return ROW_TYPE_SENDER; // sender row;
        } else {
            return ROW_TYPE_RECEIVER; // receiver row;
        }
    }

    public interface LoadEarlierMessages {
        void onLoadEarlierMessages();
    }


    public void setLoadEarlierMsgs(boolean isLoadEarlierMsgs) {
        this.isLoadEarlierMsgs = isLoadEarlierMsgs;
    }

    static class LoadEarlierMsgsViewHolder extends RecyclerView.ViewHolder {

        @Bind(R.id.btLoadEarlierMsgs) Button btLoadEarlierMessages;

        public LoadEarlierMsgsViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    static class SenderMsgViewHolder extends RecyclerView.ViewHolder {

        public SenderMsgViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    static class ReceiverMsgViewHolder extends RecyclerView.ViewHolder {

        public ReceiverMsgViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}

最后在ChatActivityOverride onLoadEarlierMessages() 方法中实现LoadEarlierMessages 监听器

    /**
     * Created by Mukesh on 21/12/2015.
     */
    public class ChatActivity extends AppCompatActivity
            implements ChatListAdapter.LoadEarlierMessages {

       // getting users recent messages and init RecyclerView
       private void showUserMessages() {
        // initialising LayoutManager for RecyclerView and setting that to RecyclerView
        mLinearLayoutManager = new LinearLayoutManager(this);
        mLinearLayoutManager.setStackFromEnd(true); // to start the list from bottom
        rvChatsList.setLayoutManager(mLinearLayoutManager);

        // initialising RecyclerView Adapter and setting that to the RecyclerView
        mChatListAdapter = new ChatListAdapter(this, userId, userMessagesList);
        rvChatsList.setAdapter(mChatListAdapter);

        // getting count of friend/contact messages and toggling visibility of load more button accordingly
        int count = mDataBaseHandler.getCountOfMessages(contactId);
        if (count != 0) {
            if (count > Constants.MESSAGES_LIMIT_FOR_LOCAL_DATABASE) {
                mChatListAdapter.setLoadEarlierMsgs(true);
            } else {
                mChatListAdapter.setLoadEarlierMsgs(false);
            }
            userMessagesList.addAll(mDataBaseHandler.getAllMessagesOfContact(contactId));
            mChatListAdapter.notifyDataSetChanged();
        }

    }

        @Override
        public void onLoadEarlierMessages() {
            ArrayList<UserMessage> tempList = mDataBaseHandler
                    .getPreviousMessagesOfContact(contactId, userMessagesList.size());
            if (tempList.size() > 0) {
                if (tempList.size() < Constants.MESSAGES_LIMIT_FOR_LOCAL_DATABASE) {
                    mChatListAdapter.setLoadEarlierMsgs(false);
                }
                View v = rvChatsList.getChildAt(0);
                int top = (v == null) ? 0 : v.getTop();
                for (int i = 0; i < tempList.size(); i++) {
                    userMessagesList.add(0, tempList.get(i));
                }
                mChatListAdapter.notifyDataSetChanged();
                mLinearLayoutManager.scrollToPositionWithOffset(tempList.size(), top);
            } else {
                mChatListAdapter.setLoadEarlierMsgs(false);
            }
        }

    }

希望这会有所帮助..!!

【讨论】:

  • 我想我明白了,你总是在第一个位置而不是最后一个位置添加新消息。我是这样使用的:userMessagesList.add(tempList.get(i));我会在我打开电脑时尝试这个。
  • 如果您更新您的 recyclerview 代码,您如何初始化您的 recyclerview 并将其提供给任何数据。这是一个很好的答案谁想从零开始做一个像我这样的recylerview
  • 很高兴为您提供帮助。更新了代码以便更好地理解:)
  • 很好的解决方案。我看到你没有处理 ROW_TYPE_LOAD_EARLIER_MESSAGES 项目类型的额外项目,为此你不需要 getItemCount() 返回原始大小+1,只需返回原始大小。在您的活动中强制在 list.addAll(newMessageList) 之后的列表中添加空对象,当调用加载更多时只需删除 list.remove(list.size()-1) 然后在列表中添加新项目 list.addAll( newMessageList),然后再次添加空对象
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多