欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)網(wǎng)易Tab分類排序控件實(shí)現(xiàn)

 更新時(shí)間:2017年03月27日 14:13:13   作者:ganchuanpu  
這篇文章主要為大家詳細(xì)介紹了Android仿網(wǎng)易Tab分類排序控件的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

先看看效果圖:

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)文章

最新評論