自定义TabHost实现背景图片随选项卡切换滑动效果

简介:

http://download.csdn.net/detail/hfsu0419/4137990



本例子是对TabHost组件的自定义,实现标签居底显示;每个标签包含图片和文字。

布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@android:id/tabhost"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent" >
  6. <RelativeLayout
  7. android:layout_width="fill_parent"
  8. android:layout_height="wrap_content"
  9. android:background="#F8FFEE" >
  10. <!-- 内容显示 -->
  11. <FrameLayout
  12. android:id="@android:id/tabcontent"
  13. android:layout_width="fill_parent"
  14. android:layout_height="wrap_content" >
  15. <TextView
  16. android:id="@+id/text1"
  17. android:layout_width="fill_parent"
  18. android:layout_height="fill_parent"
  19. android:text="@string/text1"
  20. android:textSize="32dp" />
  21. <TextView
  22. android:id="@+id/text2"
  23. android:layout_width="fill_parent"
  24. android:layout_height="fill_parent"
  25. android:text="@string/text2"
  26. android:textSize="32dp" />
  27. <TextView
  28. android:id="@+id/text3"
  29. android:layout_width="fill_parent"
  30. android:layout_height="fill_parent"
  31. android:text="@string/text3"
  32. android:textSize="32dp" />
  33. </FrameLayout>
  34. <TabWidget
  35. android:id="@android:id/tabs"
  36. android:layout_width="fill_parent"
  37. android:layout_height="wrap_content"
  38. android:layout_alignParentBottom="true"
  39. android:background="@drawable/bottom_tab_bg" >
  40. </TabWidget>
  41. <!-- 选项卡背景图片 -->
  42. <ImageView
  43. android:id="@+id/tab_top_select"
  44. android:layout_width="45dp"
  45. android:layout_height="45dp"
  46. android:layout_alignParentBottom="true"
  47. android:src="@drawable/topbar_select" />
  48. </RelativeLayout>
  49. </TabHost>
<?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="fill_parent" android:layout_height="fill_parent" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#F8FFEE" > <!-- 内容显示 --> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/text1" android:textSize="32dp" /> <TextView android:id="@+id/text2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/text2" android:textSize="32dp" /> <TextView android:id="@+id/text3" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/text3" android:textSize="32dp" /> </FrameLayout> <TabWidget android:id="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="@drawable/bottom_tab_bg" > </TabWidget> <!-- 选项卡背景图片 --> <ImageView android:id="@+id/tab_top_select" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignParentBottom="true" android:src="@drawable/topbar_select" /> </RelativeLayout> </TabHost>
MainActivity.java

  1. package com.suxh;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import android.app.TabActivity;
  5. import android.graphics.Color;
  6. import android.os.Bundle;
  7. import android.os.Handler;
  8. import android.os.Message;
  9. import android.util.Log;
  10. import android.view.Gravity;
  11. import android.view.View;
  12. import android.view.animation.TranslateAnimation;
  13. import android.widget.ImageView;
  14. import android.widget.LinearLayout;
  15. import android.widget.TabHost;
  16. import android.widget.TabHost.OnTabChangeListener;
  17. import android.widget.TextView;
  18. public class MainActivity extends TabActivity implements OnTabChangeListener {
  19. // 当前选中的Tab标号
  20. private int mCurSelectTabIndex = 0;
  21. // 默认选中第一个tab页 移动标志操作
  22. private final int INIT_SELECT = 0;
  23. // 滑动动画执行时间
  24. private final int DELAY_TIME = 500;
  25. private TabHost mTabHost;
  26. // 存放Tab页中ImageView信息
  27. public List<ImageView> imageList = new ArrayList<ImageView>();
  28. @Override
  29. public void onCreate(Bundle savedInstanceState) {
  30. super.onCreate(savedInstanceState);
  31. setContentView(R.layout.main);
  32. // 取得TabHost对象
  33. mTabHost = getTabHost();
  34. /* 为TabHost添加标签 */
  35. mTabHost.addTab(mTabHost.newTabSpec("tab_1").setIndicator(composeLayout("优惠信息", R.drawable.pic1_s)).setContent(R.id.text1));
  36. mTabHost.addTab(mTabHost.newTabSpec("tab_2").setIndicator(composeLayout("银行公告", R.drawable.pic2_n)).setContent(R.id.text2));
  37. mTabHost.addTab(mTabHost.newTabSpec("tab_3").setIndicator(composeLayout("金融产品", R.drawable.pic3_n)).setContent(R.id.text3));
  38. // 设置TabHost的背景颜色
  39. mTabHost.setBackgroundColor(Color.argb(150, 22, 70, 150));
  40. // 设置当前选中的Tab页
  41. mTabHost.setCurrentTab(0);
  42. // TabHost添加事件
  43. mTabHost.setOnTabChangedListener(this);
  44. // 初始化移动标识这里移到第一个tab页
  45. initCurSelectTab();
  46. }
  47. /**
  48. * 初始化选中Tab覆盖图片的Handler
  49. */
  50. private Handler initSelectTabHandle = new Handler () {
  51. public void handleMessage (Message msg) {
  52. switch (msg.what) {
  53. case INIT_SELECT:
  54. moveTopSelect(INIT_SELECT);
  55. break;
  56. default:
  57. break;
  58. }
  59. super.handleMessage(msg);
  60. }
  61. };
  62. /**
  63. * 初始化选中Tab覆盖图片
  64. */
  65. public void initCurSelectTab(){
  66. // 默认选中移动图片位置
  67. Message msg = new Message();
  68. msg.what = INIT_SELECT;
  69. initSelectTabHandle.sendMessageDelayed(msg, DELAY_TIME);
  70. }
  71. /**
  72. * Tab页改变
  73. */
  74. public void onTabChanged(String tabId) {
  75. // 设置所有选项卡的图片为未选中图片
  76. imageList.get(0).setImageDrawable(getResources().getDrawable(R.drawable.pic1_n));
  77. imageList.get(1).setImageDrawable(getResources().getDrawable(R.drawable.pic2_n));
  78. imageList.get(2).setImageDrawable(getResources().getDrawable(R.drawable.pic3_n));
  79. if (tabId.equalsIgnoreCase("tab_1")) {
  80. imageList.get(0).setImageDrawable(getResources().getDrawable(R.drawable.pic1_s));
  81. // 移动底部背景图片
  82. moveTopSelect(0);
  83. } else if (tabId.equalsIgnoreCase("tab_2")) {
  84. imageList.get(1).setImageDrawable(getResources().getDrawable(R.drawable.pic2_s));
  85. // 移动底部背景图片
  86. moveTopSelect(1);
  87. } else if (tabId.equalsIgnoreCase("tab_3")) {
  88. imageList.get(2).setImageDrawable(getResources().getDrawable(R.drawable.pic3_s));
  89. // 移动底部背景图片
  90. moveTopSelect(2);
  91. }
  92. }
  93. /**
  94. * 移动tab选中标识图片
  95. * @param selectIndex
  96. * @param curIndex
  97. */
  98. public void moveTopSelect(int selectIndex) {
  99. View topSelect = (View) findViewById(R.id.tab_top_select);
  100. // 起始位置中心点
  101. int startMid = ((View) getTabWidget().getChildAt(mCurSelectTabIndex)).getLeft() + ((View) getTabWidget().getChildAt(mCurSelectTabIndex)).getWidth() / 2;
  102. // 起始位置左边位置坐标
  103. int startLeft = startMid - topSelect.getWidth() / 2;
  104. // 目标位置中心点
  105. int endMid = ((View) getTabWidget().getChildAt(selectIndex)).getLeft() + ((View) getTabWidget().getChildAt(selectIndex)).getWidth() / 2;
  106. // 目标位置左边位置坐标
  107. int endLeft = endMid - topSelect.getWidth() / 2;
  108. TranslateAnimation animation = new TranslateAnimation(startLeft, endLeft - topSelect.getLeft(), 0, 0);
  109. animation.setDuration(200);
  110. animation.setFillAfter(true);
  111. topSelect.bringToFront();
  112. topSelect.startAnimation(animation);
  113. // 改变当前选中按钮索引
  114. mCurSelectTabIndex = selectIndex;
  115. Log.i("fs", "endMid " + endMid + " startLeft " + startLeft + " endLeft" + (endLeft - topSelect.getLeft()));
  116. }
  117. /**
  118. * 这个设置Tab标签本身的布局,需要TextView和ImageView不能重合 s:是文本显示的内容 i:是ImageView的图片位置
  119. */
  120. public View composeLayout(String s, int i) {
  121. // 定义一个LinearLayout布局
  122. LinearLayout layout = new LinearLayout(this);
  123. // 设置布局垂直显示
  124. layout.setOrientation(LinearLayout.VERTICAL);
  125. ImageView iv = new ImageView(this);
  126. imageList.add(iv);
  127. iv.setImageResource(i);
  128. LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  129. lp.setMargins(0, 5, 0, 0);
  130. layout.addView(iv, lp);
  131. // 定义TextView
  132. TextView tv = new TextView(this);
  133. tv.setGravity(Gravity.CENTER);
  134. tv.setSingleLine(true);
  135. tv.setText(s);
  136. tv.setTextColor(Color.WHITE);
  137. tv.setTextSize(10);
  138. layout.addView(tv, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
  139. return layout;
  140. }
  141. }


相关文章
|
4月前
|
Android开发
UniApp Android 页面拖动,去掉半圆形阴影
UniApp Android 页面拖动,去掉半圆形阴影
45 0
|
3月前
|
C++
QT 重写控件(QPushButton为例)实现背景图片的切换和鼠标样式切换
一般在QT开发中,使用setCursor()给控件设置鼠标的样式效果(一般是手型和箭头的切换),一般情况下,这个函数也是起作用的,但是一旦调用了全局QApplication::setOverrideCursor()设置鼠标效果后,在使用setCursor给控件设置鼠标样式就不起效果了,这是QT的机制
75 0
|
4月前
|
C++ UED 索引
C++ Qt开发:StatusBar底部状态栏组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍`QStatusBar`底部状态栏组件的常用方法及灵活运用。`QStatusBar` 是 Qt 中用于在主窗口底部显示状态信息的部件。它通常用于向用户提供应用程序的当前状态、进度信息、或者其他与应用程序运行相关的消息。通过在状态栏上显示文本、永久部件、进度条等内容,可以为用户提供清晰的反馈和实时信息。在设计应用程序界面时,使用状态栏有助于提升用户体验。
37 0
C++ Qt开发:StatusBar底部状态栏组件
|
前端开发 JavaScript
CSS实现背景跟随滑动的按钮菜单效果
通过transition过渡属性,可以将相关css属性的变化,改为一个持续一段时间的连续过程,而不是使css样式的改变立即生效,其过程按照指定的曲线速率变化......
472 0
CSS实现背景跟随滑动的按钮菜单效果
|
Android开发
Android BottomSheetDialog使用实现底部拖动弹窗
Android BottomSheetDialog使用实现底部拖动弹窗
416 0
Android BottomSheetDialog使用实现底部拖动弹窗
swing实现QQ登录界面1.0( 实现了同一张图片只加载一次)、(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件)
swing实现QQ登录界面1.0( 实现了同一张图片只加载一次)、(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件)
186 0
swing实现QQ登录界面1.0( 实现了同一张图片只加载一次)、(以及实现简单的布局面板添加背景图片控件的标签控件和添加一个关闭按钮控件)
|
小程序 JavaScript
小程序自定义底部导航栏,切换不同页面显示不同tabBar
小程序自定义底部导航栏,切换不同页面显示不同tabBar
3323 0
小程序自定义底部导航栏,切换不同页面显示不同tabBar
|
XML Android开发 数据格式
Android开发学习之使用Toolbar实现不同的Fragment使用不同颜色的标题栏与状态栏
Android开发学习之使用Toolbar实现不同的Fragment使用不同颜色的标题栏与状态栏                                            先看效果图。
2829 0
|
Android开发
Android 自定义控件之SlidingMenuVertical顶部悬浮(垂直折叠抽屉,有滑动渐变回调,可自行添加渐变动画)
顶部悬浮(垂直折叠抽屉,有滑动渐变回调,可自行添加渐变动画)
2016 0
UWP 取消GridView、ListView鼠标选中、悬停效果
原文:UWP 取消GridView、ListView鼠标选中、悬停效果 因为经常碰到ListView或者ListBox之类的选中、鼠标悬停样式和自己设置的主题颜色不搭,这时就需要改变这些样式了. 而这里我通过ListView来说明,大致思路其实就是重新定义Item的Template。
1152 0