实训第七周(1)

本周我主要想实现聊天界面的RecycleView相关内容。

本次主要实现MsgRecyclerView

public MsgRecyclerView(Context context) {
        this(context, null);
    }

    public MsgRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MsgRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        mLayoutManager = new LinearLayoutManager(getContext());
        setLayoutManager(mLayoutManager);
        mHeadView = new MsgHeadView(getContext());
    }

    public void hideHeadView() {
        mHeadView.setVisibleHeight(0);
        isLoading = false;
    }

    @Override
    public void setAdapter(Adapter adapter) {
        mMsgViewAdapter = new MsgViewAdapter(adapter);
        super.setAdapter(mMsgViewAdapter);
        adapter.registerAdapterDataObserver(mDataObserver);
        mDataObserver.onChanged();
    }

    @Override
    public Adapter getAdapter() {
        return mMsgViewAdapter.getOriginalAdapter();
    }

因为消息列表有MsgHeadView和普通的RecycleView,所以新写了一个Adapter类,用于包含所有的内容:

private class MsgViewAdapter extends Adapter<ViewHolder> {

        private Adapter mAdapter;

        public MsgViewAdapter(Adapter adapter) {
            this.mAdapter = adapter;
        }

        public RecyclerView.Adapter getOriginalAdapter() {
            return this.mAdapter;
        }

        @Override
        public int getItemViewType(int position) {
            if (position == 0) {
                return VIEW_TYPE_HEADER;
            }
            return mAdapter.getItemViewType(position);
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == VIEW_TYPE_HEADER) {
                return new SimpleViewHolder(mHeadView);
            }
            return mAdapter.onCreateViewHolder(parent, viewType);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            if (position == 0) {
                return;
            }
            mAdapter.onBindViewHolder(holder, position);
        }

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

        @Override
        public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
            mAdapter.onViewDetachedFromWindow(holder);
        }

        @Override
        public void onViewRecycled(RecyclerView.ViewHolder holder) {
            mAdapter.onViewRecycled(holder);
        }

        @Override
        public boolean onFailedToRecycleView(RecyclerView.ViewHolder holder) {
            return mAdapter.onFailedToRecycleView(holder);
        }

        @Override
        public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
            mAdapter.unregisterAdapterDataObserver(observer);
        }

        @Override
        public void registerAdapterDataObserver(AdapterDataObserver observer) {
            mAdapter.registerAdapterDataObserver(observer);
        }

        private class SimpleViewHolder extends RecyclerView.ViewHolder {
            SimpleViewHolder(View itemView) {
                super(itemView);
            }
        }
    }

2.为adapter设置观察者

adapter.registerAdapterDataObserver(mDataObserver);

自定义的DataObserver:

private class DataObserver extends RecyclerView.AdapterDataObserver {
        @Override
        public void onChanged() {
            if (mMsgViewAdapter != null) {
                mMsgViewAdapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onItemRangeInserted(int positionStart, int itemCount) {
            mMsgViewAdapter.notifyItemRangeInserted(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount) {
            mMsgViewAdapter.notifyItemRangeChanged(positionStart, itemCount);
        }

        @Override
        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            mMsgViewAdapter.notifyItemRangeChanged(positionStart, itemCount, payload);
        }

        @Override
        public void onItemRangeRemoved(int positionStart, int itemCount) {
            mMsgViewAdapter.notifyItemRangeRemoved(positionStart, itemCount);
        }

        @Override
        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            mMsgViewAdapter.notifyItemMoved(fromPosition, toPosition);
        }
    }

3.下拉刷新相关的view显示:

 @Override
    public boolean onTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // 记录手指按下时坐标
                mLastY = e.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                // 计算手指滑动距离,并更新当前 Y 值
                final float deltaY = e.getRawY() - mLastY;
                mLastY = e.getRawY();
                // 若当前处于列表最上方,且headView 当前显示高度小于完整高度2倍,则更新 headView 的显示高度
                if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0
                        && (deltaY > 0) && !isLoading
                        && mHeadView.getVisibleHeight() <= mHeadView.getHeadHeight() * 2) {
                    mHeadView.setVisibleHeight((int) (deltaY / OFFSET_RADIO + mHeadView.getVisibleHeight()));
                }
                break;
            case MotionEvent.ACTION_UP:
                mLastY = -1;
                // 如果 headView 显示高度大于原始高度,则刷新消息列表
                if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
                    if (!isLoading && mHeadView.getVisibleHeight() > mHeadView.getHeadHeight()) {
                        if (mLoadingListener != null) {
                            mLoadingListener.loadPreMessage();
                            isLoading = true;
                        }
                        mHeadView.setVisibleHeight(mHeadView.getHeadHeight());
                    }else {
                        // 否则,隐藏headView
                        hideHeadView();
                    }
                }
                break;
        }
        return super.onTouchEvent(e);
    }

    public void setLoadingListener(OnLoadingListener loadingListener) {
        mLoadingListener = loadingListener;
    }

    public interface OnLoadingListener {
        void loadPreMessage();
    }

展开阅读全文

没有更多推荐了,返回首页