Android自定义的TabBar
来源:互联网 发布:node.js java 编辑:程序博客网 时间:2024/05/16 11:08
http://www.oschina.net/code/snippet_731007_24519
Android自定义的TabBar,自定义了几个属性,可以在xml布局文件中使用,Tab的标题、图标等属性可以在布局文件中完成配置,Java代码中只需要指定Tab跳转的监听接口。可以在所有Android版本使用,建议配合ViewPager使用。
attrs.xml
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="TabBar"> <attr name="icons" format="reference" /> <!-- icons是一个存放drawable资源文件名的数组 --> <attr name="titles" format="reference" /> <!-- titles是一个存放string的数组 --> <attr name="IconAboveTitle" format="boolean" /> <!-- 允许指定分隔线的drawable --> <attr name="Seperator" format="reference" /> </declare-styleable> </resources>
TabBar.java
package com.pupa.common.widget;import com.pupa.common.util.StringHelper;import com.pupa.TabBarDemo.R;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.Resources;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.Display;import android.view.Gravity;import android.view.View;import android.view.WindowManager;import android.widget.ImageView;import android.widget.ImageView.ScaleType;import android.widget.LinearLayout;import android.widget.TextView;public class TabBar extends LinearLayout {private static final String TAG = "TabBar";private final TabBar mTabBar; // 自己private final Context mContext;private final AttributeSet mAttrs;private int mDefStyle;private Paint mPaint;private int mCurrentTabMaskColor;private int mCurrentTabMaskAlpha;private String mResPackageName;private CharSequence[] mTitles;private CharSequence[] mIconNames;private Drawable[] mIcons;private Drawable mSeperator;private int mSeperatorResId;private int mSeperatorWidth;private boolean mIconAboveTitle;private int mCurrentTabIndex;private int mTabCount;private int mTabWidth;private int mPosition;private OnCurrentTabChangedListener mTabChangedListener;public static final int POSITION_TOP = 1; // 位于顶部或者底部public static final int POSITION_BOTTOM = 2;public TabBar(Context context) {this(context, null);// TODO Auto-generated constructor stub}public TabBar(Context context, AttributeSet attrs) {super(context, attrs);setWillNotDraw(false); // 重要!!!mContext = context;mAttrs = attrs;mCurrentTabIndex = -1;mTabCount = 0;mSeperatorWidth = 0;mPosition = POSITION_TOP;mCurrentTabMaskColor = Color.BLACK;mCurrentTabMaskAlpha = 0x5f;mPaint = new Paint();mTabBar = this;init();// TODO Auto-generated constructor stub}@SuppressWarnings("deprecation")public void init() {getResourcesFromXml();this.setOrientation(LinearLayout.HORIZONTAL);this.setPadding(0, 0, 0, 0);WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);Display dp = wm.getDefaultDisplay();mTabWidth = dp.getWidth();mTabCount = mTitles.length;if (mTabCount > 0) {if (mSeperator != null) {Bitmap bmp = BitmapFactory.decodeResource(getResources(),mSeperatorResId);mSeperatorWidth = bmp.getWidth();mTabWidth = mTabWidth - (mTabCount - 1) * mSeperatorWidth;bmp.recycle();bmp = null;}mTabWidth = mTabWidth / mTabCount; // 计算每个tab的宽度mCurrentTabIndex = 0;}LayoutParams inParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);LayoutParams outParams = new LayoutParams(mTabWidth,LayoutParams.WRAP_CONTENT);LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);View.OnClickListener clkListener = new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint index = (Integer) v.getTag();if (index != mCurrentTabIndex) {if (mTabChangedListener != null)mTabChangedListener.onCurrentTabChanged(index);mCurrentTabIndex = index;mTabBar.invalidate();}}};//逐个添加Tabfor (int i = 0; i < mTabCount; ++i) {LinearLayout tab = new LinearLayout(mContext);tab.setOrientation(LinearLayout.VERTICAL);tab.setPadding(0, 0, 0, 0);tab.setTag(i); // 设置内部标号tab.setClickable(true);ImageView imv = new ImageView(mContext);imv.setScaleType(ScaleType.CENTER);if (i < mIcons.length)imv.setImageDrawable(mIcons[i]);TextView tv = new TextView(mContext);tv.setGravity(Gravity.CENTER_HORIZONTAL);tv.setText(mTitles[i]);if (mIconAboveTitle) { // 图标在标题之上tab.addView(imv, inParams);tab.addView(tv, inParams);} else { // 标题在图标之上tab.addView(tv, inParams);tab.addView(imv, inParams);}tab.setOnClickListener(clkListener);this.addView(tab, outParams);if (mSeperator != null && i < mTabCount - 1) {ImageView sep = new ImageView(mContext);sep.setImageDrawable(mSeperator);this.addView(sep, params);}}}/** * 设置当前Tab的序号 * * @param index * 你想指定的Tab的序号 */public void setCurrentTab(int index) {if (index > -1 && index < mTabCount&&index!=mCurrentTabIndex) {mCurrentTabIndex = index;this.invalidate();if (mTabChangedListener != null)mTabChangedListener.onCurrentTabChanged(mCurrentTabIndex);}}public void setOnCurrentTabChangedListener(OnCurrentTabChangedListener listener) {mTabChangedListener = listener;}/** * 设置TabBar在顶端还是底端.真实位置由你的Activity的布局文件决定,这里仅仅是作一个标识, 根据这个信息可以增加一些自定义的效果 * * @param i * 顶端TabBar.POSITION_TOP或底端TabBar.POSITION_BOTTOM */public void setTabBarPosition(int i) {mPosition = i;}/** * 设定工程中R.java文件的包名,因为在解析出各个Tab的icon时要用到。如果是默认值则无需指定 * * @param name * R.java文件的包名 */public void setResourcesPackageName(String name) {mResPackageName = name;}/** * 设置Tab选中后的颜色,默认alpha为0x5f * * @param c * rgb颜色值 */public void setCurrentTabMaskColor(int rgb) {mCurrentTabMaskColor = rgb;}/** * 设置Tab选中后的颜色.为什么要重载这个方法呢?因为我总是记不住Alpha值0和255谁是全透明, 于是宁愿把ARGB颜色中A跟RGB分开设置。。 * * @param rgb * rgb颜色值 * @param a * alpha值 */public void setCurrentTabMaskColor(int rgb, int a) {mCurrentTabMaskColor = rgb;mCurrentTabMaskAlpha = a;}/** * 获取Tab个数 * * @return Tab个数 */public int getTabCount() {return mTabCount;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int h = this.getHeight();if (mCurrentTabIndex > -1 && mCurrentTabIndex < mTabCount) {int startX = (mTabWidth + mSeperatorWidth) * mCurrentTabIndex;mPaint.setColor(mCurrentTabMaskColor);mPaint.setAlpha(mCurrentTabMaskAlpha);mPaint.setStyle(Paint.Style.FILL);canvas.drawRect(new Rect(startX, 0, startX + mTabWidth, h), mPaint);}}/** * 从布局文件的属性值中解析出各个资源 */private void getResourcesFromXml() {TypedArray ta = mContext.obtainStyledAttributes(mAttrs,R.styleable.TabBar, 0, 0);mIconNames = ta.getTextArray(R.styleable.TabBar_icons);mTitles = ta.getTextArray(R.styleable.TabBar_titles);mIconAboveTitle = ta.getBoolean(R.styleable.TabBar_IconAboveTitle, true);mSeperator = ta.getDrawable(R.styleable.TabBar_Seperator);mSeperatorResId = ta.getResourceId(R.styleable.TabBar_Seperator, -1);if (!StringHelper.notNullAndNotEmpty(mResPackageName))mResPackageName = mContext.getPackageName();if (mTitles == null) {mTitles = new CharSequence[0]; // 避免为null}if (mIconNames == null) {mIconNames = new CharSequence[0]; // 避免为null}Resources res = mContext.getResources();mIcons = new Drawable[mIconNames.length];for (int i = 0; i < mIconNames.length; ++i) {int id = res.getIdentifier(mIconNames[i].toString(), "drawable",mResPackageName);if (id != 0)mIcons[i] = res.getDrawable(id);}ta.recycle();}public interface OnCurrentTabChangedListener {public void onCurrentTabChanged(int index);}}
arrays.xml
<?xml version="1.0" encoding="utf-8"?><resources> <string-array name="tab_titles"> <item>Tab1</item> <item>Tab2</item> </string-array> <string-array name="tab_icons"> <item>tab1_icon</item> <item>tab2_icon</item> </string-array></resources>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:pupa="http://schemas.android.com/apk/res/com.pupa.TabDemo" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.pupa.common.widget.TabBar android:id="@+id/MainTabBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:background="@android:drawable/title_bar" pupa:Seperator="@drawable/tab_seperator" pupa:icons="@array/tab_icons" pupa:titles="@array/tab_titles" > </com.pupa.common.widget.TabBar> <android.support.v4.view.ViewPager android:id="@+id/MainViewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/MainTabBar" /></RelativeLayout>
TabBarDemo.zip ~ 703KB 下载
- Android自定义的TabBar
- 【Android源代码】Android自定义的TabBar
- Android自定义TabBar
- 隐藏自定义的tabBar
- 自定义tabbar的步骤
- 添加自定义的tabBar
- Tabbar的自定义
- 自定义tabBar的使用
- 自定义Tabbar的badgeView
- android 自定义view实现可左右滑动的Tabbar
- Android UI之自定义——类似iOS的Tabbar
- 自定义UITabBarController的tabBar背景图片
- 自定义UITabBarController的tabBar背景图片
- 自定义UITabBarController的tabBar背景图片
- 自定义tabBar的一个方法
- 关于自定义tabbar的实现
- iOS 自定义tabbar的发现
- iOS自定义 TabBar的技巧
- mysql执行sql中文乱码问题
- java工厂模式1
- 技术供应链安全——供应商范围的定义
- windows下android源代码的下载
- UVa 10260 - Soundex
- Android自定义的TabBar
- 对图像进行中值滤波的几种写法以及基于排序阈值的开关中值滤波算法
- 【jQuery】操作DOM方法总结
- Jbpm4.4+hibernate3.5.4+spring3.0.4+struts2.1.8整合例子(附完整的请假流程例子,jbpm基础,常见问题解决)
- C++构造函数和析构函数
- Android/iOS_移动平台自动化测试学习
- android蓝牙开发 蓝牙设备的查找和连接
- grunt入门指南系列一
- ITU-T Technical Paper: IP网络测量模型