最近项目中需要实现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选中.
- <p> </p> 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);
- }