Android 二次最佳化個人封裝新聞可滑動標題欄
小菜前段時間根據超多 star 的 自己修改封裝了仿網易頂部滑動標題欄 滑動內容可以是文字也可以是網路圖示,並整理了兩篇小部落格:
因小菜自己封裝的 TabSlideLayout 在滑動過程中沒有回彈的動畫效果,而 預設的滑動過程中也沒有動畫效果,而小菜技術太渣,所以只能照葫蘆畫瓢,按照 FlycoTabLayout 中的 CommonTabLayout 樣式,二次最佳化一下自己的 TabSlideLayout。
小菜修改封裝的 TabSlideLayout 是一個不限制欄目個數,超過螢幕範圍可滑動切換的頂部 Tab 佈局,item 的內容可以是文字也可以是圖片,並且支援對文字和圖片對繪色。
小菜測試步驟如下:
在 attrs 中新增如下屬性,分別時是否回彈效果/是否回彈/回彈效果時長;並在 TabSlideLayout 中新增相應的 get/set 方法,從而方便在 Java 程式碼中動態設定;
<attr name="tl_indicator_anim_enable"/><attr name="tl_indicator_anim_duration"/><attr name="tl_indicator_bounce_enable"/>
mIndicatorAnimEnable = ta.getBoolean(R.styleable.SlidingTabLayout_tl_indicator_anim_enable, true); mIndicatorBounceEnable = ta.getBoolean(R.styleable.SlidingTabLayout_tl_indicator_bounce_enable, true); mIndicatorAnimDuration = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_anim_duration, -1);public void setIndicatorAnimDuration(long indicatorAnimDuration) { this.mIndicatorAnimDuration = indicatorAnimDuration; }public void setIndicatorAnimEnable(boolean indicatorAnimEnable) { this.mIndicatorAnimEnable = indicatorAnimEnable; }public void setIndicatorBounceEnable(boolean indicatorBounceEnable) { this.mIndicatorBounceEnable = indicatorBounceEnable; }public long getIndicatorAnimDuration() { return mIndicatorAnimDuration; }public boolean isIndicatorAnimEnable() { return mIndicatorAnimEnable; }public boolean isIndicatorBounceEnable() { return mIndicatorBounceEnable; }
照葫蘆畫瓢,繼承屬性動畫的 ValueAnimator,並實現基本動畫效果;
@Overridepublic void onAnimationUpdate(ValueAnimator animation) { View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab); IndicatorPoint p = (IndicatorPoint) animation.getAnimatedValue(); mIndicatorRect.left = (int) p.left; mIndicatorRect.right = (int) p.right; if (mIndicatorWidth < 0) { //indicatorWidth小於0時,原jpardogo's PagerSlidingTabStrip } else {//indicatorWidth大於0時,圓角矩形以及三角形 float indicatorLeft = p.left + (currentTabView.getWidth() - mIndicatorWidth) / 2; mIndicatorRect.left = (int) indicatorLeft; mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth); } invalidate(); }
核心重要的第一步,調整 onDraw() 方法中繪製底部選中狀態的判斷處理,只需在第一次繪製即可,以後的滑動和選中狀態無需繪製,這樣可以防止在選擇頂部滑動過程中跳動;
private boolean mIsFirstDraw = true;//draw indicator lineif (mIndicatorAnimEnable) { if (mIsFirstDraw) { mIsFirstDraw = false; calcIndicatorRect(); } } else { calcIndicatorRect(); }
核心重要第二步,重寫 setCurrentTab 方法,分別獲取當前選中位置的座標和 item 陣列位置以及下一次選中位置的座標和 item 陣列位置;
public void setCurrentTab(int currentTab, boolean smoothScroll) { mLastTab = this.mCurrentTab; this.mCurrentTab = currentTab; updateTabSelection(currentTab); if (mFragmentChangeManager != null) { mFragmentChangeManager.setFragments(currentTab); } if (mIndicatorAnimEnable) { calcOffset(); } else { invalidate(); } }
核心重要第三步,設定 TabSlideLayout item 的點選事件或 ViewPager 滑動時的效果,若只需要 item 點選時回彈效果,則直接設定 item 佈局的點選事件既可以,呼叫步驟四的方法;若設定 ViewPager 滑動時回彈效果,在 onPageSelected 方法中呼叫步驟四方法,並重寫 onPageScrolled 方法;
@Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { /** * position:當前View的位置 * mCurrentPositionOffset:當前View的偏移量比例.[0,1) */ scrollToCurrentTab(); invalidate(); }
Tips: 若 ViewPager 的 onPageSelected 呼叫步驟四方法後,在 item 點選時可去掉步驟四方法的呼叫,否則點選時,會回彈兩次,效果不佳。
-
以上基本可以實現滑動過程和點選過程中的回彈動畫效果,但是有個效果不佳的地方是:中間內容滾動過程中,文字切換居中渲染顏色時很生硬,效果不佳。TabSlideLayout 方式 item 個數沒有限制,整個內容超過螢幕寬度,滑動過程中內容位置會變化,這可能也是 中沒有新增動畫效果的原因之一。小菜嘗試的解決辦法有兩個,第一個是在呼叫 scrollTo 方法時新增延遲;第二個是在渲染文字顏色過程中新增延遲;小菜個人更傾向於後者,給人感覺會順暢一些,但依舊並非是最佳的解決方法,仍有待研究。
預設不支援回彈效果
// 方案一:new Handler().postDelayed(new Runnable(){ public void run() { scrollTo(tempX, 0); } }, mIndicatorBounceEnable ? 600 : 250);// 方案二:if (tab_title != null) { new Handler().postDelayed(new Runnable(){ public void run() { tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor); if (mTextBold == TEXT_BOLD_WHEN_SELECT) { tab_title.getPaint().setFakeBoldText(isSelect); } } }, mIndicatorBounceEnable ? 400 : 250); }
小菜再一次體會到,最佳化與封裝是一個耗時、用心的漫長過程,需要不斷的測試和嘗試。小菜現在的解決方案也並非最佳效果,不合理的地方還請各位多多指教。
ACE01_4.jpg
作者:阿策神奇
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4328/viewspace-2822343/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 元件化封裝之標題欄Toolbar元件化封裝
- 直播app開發,封裝式標題欄APP封裝
- 基於鴻蒙ArkUI封裝標題欄TitleBar導航元件鴻蒙UI封裝元件
- jQuery單行新聞標題向上滾動詳解jQuery
- android volley解析與二次封裝Android封裝
- Android 自定義標題欄Android
- 直播app原始碼,標題欄隨頁面滑動之title移動定位效果APP原始碼
- Android從零擼美團(三) - Android多標籤tab滑動切換 - 自定義View快速實現高度定製封裝AndroidView封裝
- Android從零擼美團(三) – Android多標籤tab滑動切換 – 自定義View快速實現高度定製封裝AndroidView封裝
- Flutter Dio二次封裝Flutter封裝
- axios二次封裝iOS封裝
- 二次封裝WebDriverWait封裝WebAI
- Android studio隱藏標題欄Android
- 【Flutter 專題】130 圖解 DraggableScrollableSheet 可手勢滑動的選單欄Flutter圖解
- 寫了個移動端可滑動(慣性滑動&回彈)Vue導航欄元件 ly-tabVue元件
- 網際網路新聞擬出新規:轉載新聞不得歪曲標題原意
- 移動新聞網站,掌上移動新聞,移動新聞客戶端,jQuery Mobile移動新聞網站,移動新聞網站demo,新聞閱讀器開發網站客戶端jQuery
- Python爬蟲百度新聞標題Python爬蟲
- Android可滑動Tab的3種實現方法Android
- axios的二次封裝iOS封裝
- elment dialog二次封裝封裝
- OpenResty Redis操作二次封裝RESTRedis封裝
- FMDB 二次封裝,面向模型封裝模型
- android去掉標題欄和狀態列Android
- Android studio | 去除頂部標題欄Android
- 【iOS_GitHub】新聞頻道欄(網易新聞,新浪新聞,搜狐新聞,今日頭條,聚划算,騰訊視訊,優酷等類的頻道欄),支援小紅點標識 && 懶載入 && 快取 && 排序 && 增刪等...iOSGithub快取排序
- Android入門教程 | DrawerLayout 側滑欄Android
- 粘性控制元件,滑動停留StickLayout(導航欄滑動停留)控制元件
- CSS新聞標題後面跟著new圖示CSS
- jQuery 項卡標題欄閃爍提示新資訊jQuery
- 炫酷:一句程式碼實現標題欄、導航欄滑動隱藏,ByeBurger庫的使用和實現
- Dapper的封裝、二次封裝、官方擴充套件包封裝,以及ADO.NET原生封裝APP封裝套件
- 06#Web 實戰:實現可滑動的標籤頁Web
- axios二次封裝學習iOS封裝
- 二次封裝 query ajax 辦法封裝
- uview-ui toast 二次封裝ViewUIAST封裝
- Android Actionbar(標題欄)的背景設定Android
- android應用中去掉標題欄的方法Android