(五)展示界面数据

来源:互联网 发布:词典推荐 知乎 魏 编辑:程序博客网 时间:2024/06/17 00:58

数据源处理完毕后,需要显示在界面上

首先引入了这个比较实用的recycleview库

它支持recycleview的多布局

compile 'cc.solart:turbo-recyclerview-helper:1.0.3-beta'

然后自定义了一个侧边栏控件,主要参照下面这个控件改动的

https://github.com/Solartisan/WaveSideBar

首先在Xml文件中用一个帧布局包裹这个侧边栏控件和recycleview

接下来便是适配器

因为有两种不同的item类型,所以使用了多布局的适配器,具体如下:

/** * Created by Administrator on 2017/7/6 0006. * 音乐列表适配器 */public class MusicListAdapter extends BaseTurboAdapter<Song, BaseViewHolder> {    //构造方法    public MusicListAdapter(Context context, List<Song> data) {        super(context, data);    }    @Override    protected int getDefItemViewType(int position) {        Song song = getItem(position);        return song.type;    }    @Override    protected BaseViewHolder onCreateDefViewHolder(ViewGroup parent, int viewType) {        /**         * 1代表歌曲         * 0代表首字母         */        if (viewType == 1)            return new SongHolder(inflateItemView(R.layout.item_song, parent));        else            return new PinnedHolder(inflateItemView(R.layout.item_pinned_header, parent));    }    @Override    protected void convert(final BaseViewHolder holder, final Song item) {        if (holder instanceof SongHolder) {            ((SongHolder) holder).song_name.setText(item.song);            ((SongHolder) holder).singer_name.setText(item.singer);            /**             *  接口回调第四步 在onBindViewHolder方法内,实现回调             */            if (mOnItemClickListener != null) {                //ItemView设置监听器                ((SongHolder) holder).item_song.setOnClickListener(new View.OnClickListener() {                    @Override                    public void onClick(View view) {                        mOnItemClickListener.onItemClick((SongHolder) holder, holder.getLayoutPosition() - getHeaderViewsCount(),item);                    }                });            }        } else {            String letter = item.pys.substring(0, 1);            ((PinnedHolder) holder).song_tip.setText(letter);        }    }    public int getLetterPosition(String letter) {        for (int i = 0; i < getData().size(); i++) {            if (getData().get(i).type == 0 && getData().get(i).pys.equals(letter)) {                return i;            }        }        return -1;    }    /**     * 歌曲控件绑定     */    public class SongHolder extends BaseViewHolder {        TextView song_name;        TextView singer_name;        RelativeLayout item_song;        public SongHolder(View view) {            super(view);            song_name = findViewById(R.id.song_name);            singer_name = findViewById(R.id.singer_name);            item_song = findViewById(R.id.item_song);        }    }    /**     * 首字母控件绑定     */    class PinnedHolder extends BaseViewHolder {        TextView song_tip;        public PinnedHolder(View view) {            super(view);            song_tip = findViewById(R.id.song_tip);        }    }    //接口回调第二步 新建私有变量用于保存用户设置的监听器及其set方法    private OnItemClickListener mOnItemClickListener;    /**     * 接口回调第一步 新建内部接口,用来做点击监听     */    public interface OnItemClickListener {        void onItemClick(SongHolder view, int position,Song item);    }    //接口回调第三步 设置set方法    public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {        this.mOnItemClickListener = mOnItemClickListener;    }}

适配器完成后,回到音乐列表界面

Recycleview设置LayoutManager为线性方向

同时自定义了一个分割线用来设置列表字母标题

分割线的registerTypePinnedHeader方法中第一个参数输入的是字母标题的type类型

自定义分割线如下:

/** * Created by Administrator on 2017/7/6 0006. * 自定义的recycleview分割线 */public class PinnedHeaderDecoration extends RecyclerView.ItemDecoration {    private int mHeaderPosition;    private int mPinnedHeaderTop;    private boolean mIsAdapterDataChanged;    private Rect mClipBounds;    private View mPinnedHeaderView;    private RecyclerView.Adapter mAdapter;    private final SparseArray<PinnedHeaderCreator> mTypePinnedHeaderFactories = new SparseArray<>();    private final RecyclerView.AdapterDataObserver mAdapterDataObserver = new RecyclerView.AdapterDataObserver() {        @Override        public void onChanged() {            mIsAdapterDataChanged = true;        }    };    public PinnedHeaderDecoration() {        this.mHeaderPosition = -1;    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        createPinnedHeader(parent);        if (mPinnedHeaderView != null) {            int headerEndAt = mPinnedHeaderView.getTop() + mPinnedHeaderView.getHeight();            View v = parent.findChildViewUnder(c.getWidth() / 2, headerEndAt + 1);            if (isPinnedView(parent, v)) {                mPinnedHeaderTop = v.getTop() - mPinnedHeaderView.getHeight();            } else {                mPinnedHeaderTop = 0;            }            mClipBounds = c.getClipBounds();            mClipBounds.top = mPinnedHeaderTop + mPinnedHeaderView.getHeight();            c.clipRect(mClipBounds);        }    }    @Override    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        if (mPinnedHeaderView != null) {            c.save();            mClipBounds.top = 0;            c.clipRect(mClipBounds, Region.Op.UNION);            c.translate(0, mPinnedHeaderTop);            mPinnedHeaderView.draw(c);            c.restore();        }    }    private void createPinnedHeader(RecyclerView parent) {        updatePinnedHeader(parent);        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager == null || layoutManager.getChildCount() <= 0) {            return;        }        int firstVisiblePosition = ((RecyclerView.LayoutParams) layoutManager.getChildAt(0).getLayoutParams()).getViewAdapterPosition();        int headerPosition = findPinnedHeaderPosition(parent, firstVisiblePosition);        if (headerPosition >= 0 && mHeaderPosition != headerPosition) {            mHeaderPosition = headerPosition;            int viewType = mAdapter.getItemViewType(headerPosition);            RecyclerView.ViewHolder pinnedViewHolder = mAdapter.createViewHolder(parent, viewType);            mAdapter.bindViewHolder(pinnedViewHolder, headerPosition);            mPinnedHeaderView = pinnedViewHolder.itemView;            // read layout parameters            ViewGroup.LayoutParams layoutParams = mPinnedHeaderView.getLayoutParams();            if (layoutParams == null) {                layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);                mPinnedHeaderView.setLayoutParams(layoutParams);            }            int heightMode = View.MeasureSpec.getMode(layoutParams.height);            int heightSize = View.MeasureSpec.getSize(layoutParams.height);            if (heightMode == View.MeasureSpec.UNSPECIFIED) {                heightMode = View.MeasureSpec.EXACTLY;            }            int maxHeight = parent.getHeight() - parent.getPaddingTop() - parent.getPaddingBottom();            if (heightSize > maxHeight) {                heightSize = maxHeight;            }            // measure & layout            int ws = View.MeasureSpec.makeMeasureSpec(parent.getWidth() - parent.getPaddingLeft() - parent.getPaddingRight(), View.MeasureSpec.EXACTLY);            int hs = View.MeasureSpec.makeMeasureSpec(heightSize, heightMode);            mPinnedHeaderView.measure(ws, hs);            mPinnedHeaderView.layout(0, 0, mPinnedHeaderView.getMeasuredWidth(), mPinnedHeaderView.getMeasuredHeight());        }    }    private int findPinnedHeaderPosition(RecyclerView parent, int fromPosition) {        if (fromPosition > mAdapter.getItemCount() || fromPosition < 0) {            return -1;        }        for (int position = fromPosition; position >= 0; position--) {            final int viewType = mAdapter.getItemViewType(position);            if (isPinnedViewType(parent, position, viewType)) {                return position;            }        }        return -1;    }    private boolean isPinnedViewType(RecyclerView parent, int adapterPosition, int viewType) {        PinnedHeaderCreator pinnedHeaderCreator =  mTypePinnedHeaderFactories.get(viewType);        return pinnedHeaderCreator != null && pinnedHeaderCreator.create(parent, adapterPosition);    }    private boolean isPinnedView(RecyclerView parent, View v) {        int position = parent.getChildAdapterPosition(v);        if (position == RecyclerView.NO_POSITION) {            return false;        }        return isPinnedViewType(parent, position, mAdapter.getItemViewType(position));    }    private void updatePinnedHeader(RecyclerView parent) {        RecyclerView.Adapter adapter = parent.getAdapter();        if (mAdapter != adapter || mIsAdapterDataChanged) {            resetPinnedHeader();            if (mAdapter != null) {                mAdapter.unregisterAdapterDataObserver(mAdapterDataObserver);            }            mAdapter = adapter;            if (mAdapter != null) {                mAdapter.registerAdapterDataObserver(mAdapterDataObserver);            }        }    }    private void resetPinnedHeader() {        mHeaderPosition = -1;        mPinnedHeaderView = null;    }    public void registerTypePinnedHeader(int itemType, PinnedHeaderCreator pinnedHeaderCreator) {        mTypePinnedHeaderFactories.put(itemType, pinnedHeaderCreator);    }    public interface PinnedHeaderCreator {        boolean create(RecyclerView parent, int adapterPosition);    }}


侧边滑动栏调用下列方法即可实现定位

mSideBarView.setOnTouchLetterChangeListener(new WaveSideBarView.OnTouchLetterChangeListener() {    @Override    public void onLetterChange(String letter) {        int pos = adapter.getLetterPosition(letter);        if (pos != -1) {            recycler_music.scrollToPosition(pos);            mLayoutManager.scrollToPositionWithOffset(pos, 0);        }    }})


原创粉丝点击