Android實(shí)現(xiàn)網(wǎng)易Tab分類排序控件實(shí)現(xiàn)
先看看效果圖:
1、XML布局引入
<com.net168.lib.SortTabLayout android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="wrap_content" />
2、設(shè)置數(shù)據(jù)源數(shù)據(jù),也就是每個(gè)item的對應(yīng)文本數(shù)據(jù)
//構(gòu)造數(shù)據(jù)源,暫時(shí)僅支持String List<String> data = new ArrayList<String>(); for (int i = 0; i < 20; i ++) { data.add("item" + i); } //設(shè)置數(shù)據(jù)源 vSortLayout.setShowData(data, 1);
3、設(shè)置,用于交互點(diǎn)擊和長按的事件
vSortLayout.setOnSelectListener(new onSelectListener() { //點(diǎn)擊事件,點(diǎn)擊Tab布局里面的item觸發(fā) @Override public void onSelect(View v, int index) { Toast.makeText(MainActivity.this, "你點(diǎn)擊了item ,內(nèi)容為:" + ((TextView)v).getText(), Toast.LENGTH_SHORT).show(); } //長按事件,長按Tab布局里面的item觸發(fā) @Override public void onLongSelect(View v) { Toast.makeText(MainActivity.this, "長按Tab,開始排列", Toast.LENGTH_SHORT).show(); } });
4、開始排序和結(jié)束排序的接口
//如果參數(shù)是true的話,開始排序,也就是可以拖動(dòng) vSortLayout.setIsMoveList(true); //結(jié)束排序,并且會(huì)返回選擇tab的當(dāng)前新位置 vSortLayout.getAndFinishSortData();
未完善的自定義功能
1、現(xiàn)在僅僅是支持String,并且布局也無法自定義,后續(xù)可能會(huì)完善Tab的item的View的自定義輸入
2、現(xiàn)在布局的行數(shù)和間距由硬代碼控制,并沒有形成簡便易懂的接口
PS:調(diào)試間距的方法,主要調(diào)試下列幾個(gè)參數(shù)
/** * 配置參數(shù)區(qū)域 * mMaxRow : 每行的個(gè)數(shù) * Magin Width Tab的間隔和本身的寬度的占比 * 例如mMaxRow = 4,則寬度會(huì)由此策略分配 * |Magin|View|Magin|View|Magin|View|Magin|View|Magin| * 記控件寬度為這么分配 : 總寬度 = 5 * Magin + 4 * View, 而 Magin : View = mRowMagin : mRowWidth * 可以推導(dǎo)出各個(gè)控件的寬度,高度也如此計(jì)算 */ private final int mMaxRow = 4; private final int mRowMagin = 5; private final int mRowWidth = 26; private final int mColumnMagin = 4; private final int mColumnHeight = 10;
3、回滾不流暢,后期可以引入Scroller來控制緩慢回滾
實(shí)現(xiàn)原理
1、布局item排序采用基于ViewGroup的自定義布局,在onLayout的方法邏輯根據(jù)配置參數(shù)區(qū)域的參數(shù)進(jìn)行計(jì)算配置
@Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { final int childCount = getChildCount(); int row = 0; int column = 0; int startWidth = 0; int startHeight = 0; for (int i = 0; i < childCount; i++) { View childeView = childList.get(i); row = i / 4; column = i % 4; startWidth = (int) ((column * (mRowWidth + 2 * mRowMagin) + mRowMagin) * mChildeItemSize); startHeight = (int) ((row * (mColumnHeight + 2 * mColumnMagin) + mColumnMagin) * mChildeItemSize); childeView.layout(startWidth ,startHeight ,(int)(startWidth + mRowWidth * mChildeItemSize), (int)(startHeight + mColumnHeight * mChildeItemSize)); } }
2、滑動(dòng)模塊部分,在onTouchEvent里面根據(jù)坐標(biāo)的捕獲,有坐標(biāo)分析出對應(yīng)的子Item,利用View.layout()方法讓拖動(dòng)的View跟隨手指移動(dòng),參加代碼
private void moveChildView(float x, float y) { if (mMoveChildView != null) { int left = (int) (((mChildIndex % 4) * (mRowWidth + 2 * mRowMagin) + mRowMagin) * mChildeItemSize); int top = (int) (((mChildIndex / 4) * (mColumnHeight + 2 * mColumnMagin) + mColumnMagin) * mChildeItemSize); int width = (int) (left + mRowWidth * mChildeItemSize); int heigth = (int) (top + mColumnHeight * mChildeItemSize); int moveX = (int) (x - beginX); int moveY = (int) (y - beginY); mMoveChildView.layout(left + moveX, top + moveY, width + moveX, heigth + moveY); mMoveChildView.invalidate(); } }
3、動(dòng)畫模塊,由于考慮低版本和不想引入過多的開源庫,故采用普通的動(dòng)畫實(shí)現(xiàn)
具體參見beginAnimation(final int start,final int end, boolean forward)方法。
4、整體流程
a、Touch的down事件,捕捉當(dāng)前的x、y數(shù)據(jù),計(jì)算出被移動(dòng)的View的所對應(yīng)index,并且其余view開始抖動(dòng)動(dòng)畫
b、move事件,將被選中的view根據(jù)x、y利用layout方法進(jìn)行跟隨手指移動(dòng)
c、up事件,執(zhí)行位置調(diào)整動(dòng)畫,并且在調(diào)整完畢后,進(jìn)行新位置的設(shè)置
完整代碼:https://github.com/ganchuanpu/SortTabLayout.git
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android使用WebView實(shí)現(xiàn)截圖分享功能
這篇文章主要為大家詳細(xì)介紹了Android使用WebView實(shí)現(xiàn)截圖分享功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android Studio連接手機(jī)設(shè)備教程
這篇文章主要為大家詳細(xì)介紹了Android Studio連接手機(jī)設(shè)備教程,非常完整的連接步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Android UI設(shè)計(jì)系列之HTML標(biāo)簽實(shí)現(xiàn)TextView設(shè)置中文字體加粗效果(6)
這篇文章主要介紹了Android UI設(shè)計(jì)系列之使用HTML標(biāo)簽,實(shí)現(xiàn)在TextView中對中文字體加粗的效果,具有一定的實(shí)用性和參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06Android 6.0 無法在SD卡創(chuàng)建目錄的方法
今天小編就為大家分享一篇Android 6.0 無法在SD卡創(chuàng)建目錄的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08Android調(diào)試神器stetho使用詳解和改造
今天小編就為大家分享一篇關(guān)于Android調(diào)試神器stetho使用詳解和改造,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-02-02Android Room數(shù)據(jù)庫自動(dòng)升級與遷移的策略
在 Android 應(yīng)用開發(fā)中,Room 是 Google 提供的一個(gè)輕量級數(shù)據(jù)庫框架,用于簡化與 SQLite 的交互,本文將介紹 Room 數(shù)據(jù)庫升級的幾種場景和常見的處理方法,包括手動(dòng)遷移和自動(dòng)遷移的策略,需要的朋友可以參考下2024-09-09Android編程實(shí)現(xiàn)ImageView圖片拋物線動(dòng)畫效果的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)ImageView圖片拋物線動(dòng)畫效果的方法,實(shí)例分析了Android實(shí)現(xiàn)拋物線運(yùn)動(dòng)的算法原理與相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Android控件之ImageView用法實(shí)例分析
這篇文章主要介紹了Android控件之ImageView用法,以實(shí)例形式較為詳細(xì)的分析了ImageView控件用于顯示圖片的使用方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09