<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
1.設定一個懸浮的檢視掛在recycleView頂部,隨著item的移動位置,懸浮標題自動跟隨移動或者是保持原地不動。
2.使用recyclerView的ItemDecoration,給指定的item設定不同的itemDecoration,並且跟隨item的移動而移動或者保持不變。
本文采用第二種方式實現,效果圖:
這是個介面,一共有六個方法:
public static abstract class ItemDecoration { /** * Draw any appropriate decorations into the Canvas supplied to the RecyclerView. * Any content drawn by this method will be drawn before the item views are drawn, * and will thus appear underneath the views. * * @param c Canvas to draw into * @param parent RecyclerView this ItemDecoration is drawing into * @param state The current state of RecyclerView */ public void onDraw(Canvas c, RecyclerView parent, State state) { onDraw(c, parent); } /** * Draw any appropriate decorations into the Canvas supplied to the RecyclerView. * Any content drawn by this method will be drawn after the item views are drawn * and will thus appear over the views. * * @param c Canvas to draw into * @param parent RecyclerView this ItemDecoration is drawing into * @param state The current state of RecyclerView. */ public void onDrawOver(Canvas c, RecyclerView parent, State state) { onDrawOver(c, parent); } /** * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies * the number of pixels that the item view should be inset by, similar to padding or margin. * The default implementation sets the bounds of outRect to 0 and returns. * * <p> * If this ItemDecoration does not affect the positioning of item views, it should set * all four fields of <code>outRect</code> (left, top, right, bottom) to zero * before returning. * * <p> * If you need to access Adapter for additional data, you can call * {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the * View. * * @param outRect Rect to receive the output. * @param view The child view to decorate * @param parent RecyclerView this ItemDecoration is decorating * @param state The current state of RecyclerView. */ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(), parent); } /** * @deprecated * Override {@link #onDrawOver(Canvas, RecyclerView, RecyclerView.State)} */ @Deprecated public void onDrawOver(Canvas c, RecyclerView parent) { } /** * @deprecated * Override {@link #onDraw(Canvas, RecyclerView, RecyclerView.State)} */ @Deprecated public void onDraw(Canvas c, RecyclerView parent) { } /** * @deprecated * Use {@link #getItemOffsets(Rect, View, RecyclerView, State)} */ @Deprecated public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { outRect.set(0, 0, 0, 0); } }
其中有三個方法是@deprecated的,那麼我們只需要看以下三個方法:
public void onDraw(Canvas c, RecyclerView parent, State state) { onDraw(c, parent); } public void onDrawOver(Canvas c, RecyclerView parent, State state) { onDrawOver(c, parent); } public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(), parent); }
第一個方法的意思是繪製分割線本身;
第二個方法是在item專案繪製完成之後進行的繪製操作(這個會覆蓋在item上面);
第三個方法是設定分割線的左間距,上間距,右間距,下間距,儲存在outRect中。
如圖所示:
其中最底層黃色部分大小是getItemOffsets方法返回的itemDecoration的矩陣設定邊距寬度,onDraw方法根據設定的間距寬度來進行繪製黃色區域,其中棕紅色部分是onDrawOver方法覆蓋繪製在item上層的部分。
我們給每個需要title的item設定rect.top = titleHeight(標題列高度);其他的間距可以先不考慮,不重要;
重寫onDraw方法,繪製我們的itemDecoration標題列;
我們需要重寫onDrawOver方法,在滑動的時候去判斷,
1)如果頂部標題區域是在該標題的items範圍之內的滑動的話,那麼我們需要覆蓋繪製一個處於recyclerView.getpaddingTop位置的title,這樣的話這個範圍內滑動就有一個懸停的標題列;
2)如果頂部的標題列區域恰好下面緊跟著下一個標題列,那麼繼續向上滑動的時候,需要下面的標題列把上面的標題列頂出介面之外。那麼繪製的頂部標題列的起始位置就是所處的item.bottom - titleHeight的位置。
使用以上三個步驟就可以做出一個流暢並且客製化化很高的懸浮標題列功能了。
class MyDecoration(context: Context): RecyclerView.ItemDecoration() { var mPaint:Paint? = null var mPaint2:Paint? = null var mTextPaint:Paint? = null var mTitleHeight:Int? = null var mTitleHeight2:Int? = null var mTitleTextSize:Float? = null init { mTitleHeight = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 30f, context.getResources().getDisplayMetrics() ).toInt() mTitleHeight2 = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 3f, context.getResources().getDisplayMetrics() ).toInt() mTitleTextSize = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16f, context.getResources().getDisplayMetrics() ) mTextPaint = Paint() mTextPaint?.let { it.setTextSize(mTitleTextSize!!) it.setAntiAlias(true) it.setColor(Color.WHITE) } mPaint = Paint() mPaint?.let { it.setAntiAlias(true) it.setColor(Color.RED) } mPaint2 = Paint() mPaint2?.let { it.setAntiAlias(true) it.setColor(Color.BLUE) } } /** * recyclerView繪製onDraw -> item.onDraw -> onDrawOver */ override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { for (index in 0 until parent.childCount) { val childView = parent.getChildAt(index) childView?.let { val rect = Rect() val position = parent.getChildAdapterPosition(it) if (isTitleItem(position)) { rect.top = childView.top - mTitleHeight!! rect.bottom = childView.top } else { rect.top = childView.top - mTitleHeight2!! rect.bottom = childView.top } rect.left = parent.paddingLeft rect.right = parent.width - parent.paddingRight if (isTitleItem(position)) { mPaint?.let { it1 -> c.drawRect(rect, it1) } mTextPaint?.let { it3 -> c.drawText( getTitleStr(position), 0f, rect.top.toFloat() + (mTitleHeight?.div(2.00f)?:0f), it3)} } else { mPaint2?.let { it1 -> c.drawRect(rect, it1) } } } } } /** * recyclerView繪製onDraw -> item.onDraw -> onDrawOver * 繪製覆蓋在item上面的分割線效果 */ override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) { val childView = parent.getChildAt(0) var nextView:View? = null; if (1 < parent.childCount) { nextView = parent.getChildAt(1) } childView?.let { val rect = Rect() val position = parent.getChildAdapterPosition(it) mTitleHeight?.let { height -> if (nextView != null && it.bottom - height < parent.paddingTop && isTitleItem(parent.getChildAdapterPosition(nextView)) && !isSameTitle(parent.getChildAdapterPosition(nextView),position)) { rect.top = it.bottom - height rect.bottom = it.bottom } else { rect.top = parent.paddingTop rect.bottom = rect.top + height } } rect.left = parent.paddingLeft rect.right = parent.width - parent.paddingRight mPaint?.let { it1 -> c.drawRect(rect, it1) } mTextPaint?.let { it3 -> c.drawText( getTitleStr(position), 0f, rect.top + (mTitleHeight?.div(2.00f)?:0f), it3)} } } /** * 用於設定item周圍的偏移量的,類似於設定padding喝margin效果, * 空出的效果用於繪製分割線 */ override fun getItemOffsets( outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State ) { val position:Int = parent.getChildAdapterPosition(view) if (position % 4 == 0) { outRect.top = mTitleHeight!! } else{ outRect.top = mTitleHeight2!! } } fun isTitleItem(position: Int):Boolean { return position % 4 == 0 } fun getTitleStr(position: Int):String { return "標題:${position / 4}" } fun isSameTitle(position1: Int,position2: Int):Boolean { return (position1 / 4) == (position2 / 4) } }
到此這篇關於Android itemDecoration介面實現吸頂懸浮標題的文章就介紹到這了,更多相關Android吸頂懸浮標題內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45