最近項目中需要實現TabHost,鑒於TabHost不能實現想要的功能,所以決定自定義一個控件,用於替代TabHost,實現拖拽,Tab之間的替換等功能.剛整合了一份簡單的代碼,第一次發表文章,寫的不好的地方,望見諒.廢話補多少,貼代碼
.
代碼實現共2個類,TabView和Tab
TabView的繪制方法.
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- canvas.translate(tabViewStart_x, 0);
- if (tabs == null)
- return;
- if (!initTabRegion) {
- // 給每個Tab分配區域.
- initTabRegion();
- // 設置第一個Tab選中.
- setTabFocus(tabs.get(0));
- }
- for (Tab tab : tabs) {
- if (currentTab != tab || !scrollTab) {
- // 調用每個Tab的draw方法.
- tab.draw(canvas);
- }
- }
- if (currentTab != null && scrollTab) {
- // 移動狀態時調用.
- currentTab.drawMovement(canvas, currentTabStart_x + currentTabMove_x);
- }
- canvas.translate(-tabViewStart_x, 0);
- tempRegion.set(0, 55, currentTabStart_x + getWidth(), 60);
- canvas.drawBitmap(TabUtil.tab_band, null, tempRegion, null);
- }
TabView的事件
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- event.setLocation(event.getX() - tabViewStart_x, event.getY());
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // 獲取選中Tab.
- currentTab = getCurrentTab(event, false);
- if (currentTab != null) {
- longPress = true;
- // 長按事件.
- onLongPress();
- currentTabStart_x = currentTab.getRegion().left;
- currentTabMove_x = 0;
- setTabFocus(currentTab);
- }
- x = (int) event.getX();
- y = (int) event.getY();
- break;
- case MotionEvent.ACTION_MOVE:
- if (Math.abs(event.getX() - x) > 10 || Math.abs(event.getY() - y) >10) {
- longPress = false;
- }
- if (currentTab == null) {
- break;
- }
- if (scrollTab) {
- Tab tab = getCurrentTab(event, true);
- // 長按Tab移動,實現Tab之間的替換.
- if (tab != null && currentTab != tab) {
- int tabID = tabs.indexOf(tab);
- int currentTabID = tabs.indexOf(currentTab);
- tabs.set(tabID, currentTab);
- tabs.set(currentTabID, tab);
- initTabRegion();
- }
- } else {
- // 整個View的拖拽.
- tabViewStart_x += (int) event.getX() - x;
- }
- currentTabMove_x = (int) event.getX() - x;
- break;
- case MotionEvent.ACTION_UP:
- longPress = false;
- scrollTab = false;
- if (task != null) {
- task.cancel();
- }
- // 拖拽松開時開啟一個Timer,實現自定義動畫效果.
- task = new TimerTask() {
- @Override
- public void run() {
- animateHandler.sendEmptyMessage(1);
- }
- };
- if (tabViewStart_x > 0) {
- start = 0;
- timer.schedule(task, 0, 20);
- }
- break;
- }
- event.setLocation(event.getX() + tabViewStart_x, event.getY());
- invalidate();
- return true;
- }
Handler接受Timer發送的消息.
- private Handler animateHandler = new Handler() {
- public void dispatchMessage(Android.os.Message msg) {
- // 自定義動畫效果.
- startAnimation(600);
- if (tabViewStart_x <= 0 && task != null) {
- task.cancel();
- tabViewStart_x = 0;
- }
- invalidate();
- };
- };
Tab的繪制方法.
- public void draw(Canvas canvas) {
- canvas.setDrawFilter(pdf);
- if (sheetTabAdd) {
- this.tab_left = TabUtil.tab_off_left;
- this.tab_mid = TabUtil.tab_off_mid;
- this.tab_right = TabUtil.tab_off_right;
- drawBitmap(canvas, region, null);
- } else {
- if (thisFocus) {
- this.tab_left = TabUtil.tab_on_left;
- this.tab_mid = TabUtil.tab_on_mid;
- this.tab_right = TabUtil.tab_on_right;
- } else {
- this.tab_left = TabUtil.tab_off_left;
- this.tab_mid = TabUtil.tab_off_mid;
- this.tab_right = TabUtil.tab_off_right;
- }
- // 繪制圖片.
- drawBitmap(canvas, region, null);
- // 繪制文字.
- canvas.drawText(title, region.left + 45, region.bottom - 12, textPaint);
- }
- }
Tab移動時的繪制方法.
- public void drawMovement(Canvas canvas, int currentMove_x) {
- canvas.setDrawFilter(pdf);
- if (paint == null) {
- paint = new Paint();
- paint.setAlpha(200);
- }
- if (moveRegion == null) {
- moveRegion = new Rect(currentMove_x, region.top, currentMove_x + getTabWidth(), region.bottom);
- } else {
- moveRegion.left = currentMove_x;
- moveRegion.right = currentMove_x + getTabWidth();
- }
- drawBitmap(canvas, moveRegion, paint);
- canvas.drawText(title, currentMove_x + 45, region.bottom - 12, textPaint);
- }