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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 直播app開發,封裝式標題欄APP封裝
- 基於鴻蒙ArkUI封裝標題欄TitleBar導航元件鴻蒙UI封裝元件
- 寫了個移動端可滑動(慣性滑動&回彈)Vue導航欄元件 ly-tabVue元件
- 【Flutter 專題】130 圖解 DraggableScrollableSheet 可手勢滑動的選單欄Flutter圖解
- Android從零擼美團(三) – Android多標籤tab滑動切換 – 自定義View快速實現高度定製封裝AndroidView封裝
- Android從零擼美團(三) - Android多標籤tab滑動切換 - 自定義View快速實現高度定製封裝AndroidView封裝
- jQuery單行新聞標題向上滾動詳解jQuery
- Android studio | 去除頂部標題欄Android
- 直播app原始碼,標題欄隨頁面滑動之title移動定位效果APP原始碼
- axios二次封裝iOS封裝
- 二次封裝WebDriverWait封裝WebAI
- Android入門教程 | DrawerLayout 側滑欄Android
- Flutter Dio二次封裝Flutter封裝
- elment dialog二次封裝封裝
- axios的二次封裝iOS封裝
- Python爬蟲百度新聞標題Python爬蟲
- Android 採用AOP方式封裝6.0許可權管理Android封裝
- Dapper的封裝、二次封裝、官方擴充套件包封裝,以及ADO.NET原生封裝APP封裝套件
- axios二次封裝學習iOS封裝
- Selenium二次封裝-Python版本封裝Python
- OpenResty Redis操作二次封裝RESTRedis封裝
- Android中取消系統標題欄的幾種方式Android
- 基於workerman-jsonrpc二次封裝的一個packageJSONRPC封裝Package
- Android 設定TextView滑動滾動條和滑動效果AndroidTextView
- Flutter之可滑動WidgetFlutter
- 06#Web 實戰:實現可滑動的標籤頁Web
- uview-ui toast 二次封裝ViewUIAST封裝
- CSS新聞標題後面跟著new圖示CSS
- Android 禁止ViewPager左右滑動AndroidViewpager
- 一次Android動畫工具類的封裝Android動畫封裝
- 封裝、許可權修飾符、封裝的案例封裝
- Qt隱藏系統標題欄,使用自定義標題欄QT
- jQuery 項卡標題欄閃爍提示新資訊jQuery
- Android的標題欄,狀態列圖示文字顏色及背景動態變化Android
- WPF如何封裝一個可擴充套件的Window封裝套件
- 基於Glide4.7.1二次封裝IDE封裝
- selenium-webdriver的二次封裝(十)Web封裝
- android 6.0許可權機制的簡單封裝(支援批量申請許可權)Android封裝