(五)展示界面数据
来源:互联网 发布:词典推荐 知乎 魏 编辑:程序博客网 时间: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); } }})
阅读全文
0 0
- (五)展示界面数据
- 数据存储和界面展示
- android02-数据存储和界面展示
- Android:数据存储和界面展示
- 数据存储和界面展示一
- 数据存储和界面展示二
- 【Python数据分析与展示】(五)pandas库数据分析
- 关于融云的集成二(数据展示到聊天界面)
- Android视频学习(一):数据存储与界面展示1
- Android视频学习(二):数据存储与界面展示2
- 用百度map api展示时空数据(五)--老地图的添加与删除
- Fiddler的实践心得(五):重新认识Inspectors->WebForms、TextView、SyntaxView选项展示的数据
- iphone利用xml传递数据,展示载Table界面中
- Iphone利用JSON传递数据,展示在Table界面中
- iPhone利用xml传递数据,展示载Table界面中
- Iphone利用JSON传递数据,展示在Table界面中
- iphone利用xml传递数据,展示载Table界面中
- Iphone利用JSON传递数据,展示在Table界面中
- CSU1830(数据很多时,怎么用dijkstra算法处理)
- Java虚拟机体系结构深入研究总结
- Appium的定位方法
- 环形打印矩阵
- 移动开发框架选型
- (五)展示界面数据
- 最长递增子序列
- java中list、set和map 的区别
- 使用Node.js+Socket.IO搭建WebSocket实时应用
- Android5.0特性
- Insertion Sort List问题及解法
- ios cookie概念介绍
- VS2013 编写汇编程序
- Ultra-QuickSort(逆序数)