相信很多人都喜欢iphone 酷炫的界面,虽然android的原生控件已经足够漂亮,但是往往不能满足用户越来越挑剔的眼光。其实,我们完全可以自己来绘制界面。今天我就来分享下做一个和iphone一样的tab界面。下面先来看下iphone上的效果

android UI进阶之仿iphone的tab效果

在开始之前,我们必须掌握最基础的,也就是android中图形界面的绘制。首先讲下简单图形的绘制,这里我们就借绘制这个的背景部分来讲下吧。直接看代码

public classItab extendsView{

privatePaintmPaint;

publicItab(Contextcontext,AttributeSetattrs){ // 构造器,View下构造器有三种方式,在xml中配置必须实现这种方式
super(context,attrs);

}

@Override
protected voidonDraw(Canvascanvas)
{

super.onDraw(canvas);

mPaint= newPaint(); // 创建画笔
mPaint.setStyle(Paint.Style.FILL); // 设置画笔为实心

Rectr= newRect(); // 创建一个矩形
this.getDrawingRect(r);

canvas.drawColor(0xFF000000);
mPaint.setColor(0xFF434343);
canvas.drawLine(r.left,r.top+1,r.right,r.top+1,mPaint); // 绘制这个矩形图形
}
}

在xml中这样配置

<? xmlversion="1.0"encoding="utf-8" ?>
< RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation
="vertical"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:background
="#C5CCD4FF"
>
< com.notice520.itab.Itab
android:id ="@+id/Tabs"
android:layout_width
="fill_parent"
android:layout_height
="49px"
android:layout_alignParentBottom
="true"
/>
</ RelativeLayout >

这样就会得到如下的效果,这显然不是我们想要的。

android UI进阶之仿iphone的tab效果

不过别着急,我们只要在onDraw()这个方法里面添加如下一段代码:

intcolor=46;

for( inti=0;i<24;i++)
{
mPaint.setARGB(255,color,color,color);
canvas.drawRect(r.left,r.top+i+1,r.right,r.top+i+2,mPaint);
color--;
}

通过循环的绘制,我们就可以得到如下的效果

是不是很简单呢。图形绘制中还有一个比较重要的是贴图的绘制。同样这个例子,我们在这个背景上绘制一个图标,非常的简单,同样在onDraw()这个方法里面添加如下代码

Bitmapicon=BitmapFactory.decodeResource(getResources(),R.drawable.monitor);
Paintp= newPaint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
p.setColor(Color.WHITE);
canvas.drawBitmap(icon,10,10,p);

代码非常简单,第一行获得图片资源,第二行第一一个画笔,同时打开抗锯齿和过滤,第三行设置画笔颜色,最后一行绘制图片。

来看看效果

还不错吧,当然要实现完全的tab效果,这还是远远不够的。

这个例子参考国外rolle3k共享的代码,感谢rolle3k。

我们继续来完成Itab这个类,同时把他放到MainAcitvity(继承Activity)这个类内部,这样,整个程序只需一个类就可以了。(上篇博客例子运行需要再建一个Activity的子类来作为lanucher)。废话不多说了,看看代码


public static classiTab extendsView
{
privatePaintmPaint; // 背景画笔
privatePaintmActiveTextPaint; // 选中
privatePaintmInactiveTextPaint; // 未选中
privateArrayList<TabMember>mTabMembers; // tab成员
private intmActiveTab;
privateOnTabClickListenermOnTabClickListener= null;

publiciTab(Contextcontext,AttributeSetattrs) // 构造器,在里面初始化画笔
{
super(context,attrs);

mTabMembers= newArrayList<MainActivity.iTab.TabMember>();

mPaint= newPaint();
mActiveTextPaint= newPaint();
mInactiveTextPaint= newPaint();

mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(0xFFFFFF00);
mPaint.setAntiAlias( true);

mActiveTextPaint.setTextAlign(Align.CENTER);
mActiveTextPaint.setTextSize(12);
mActiveTextPaint.setColor(0xFFFFFFFF);
mActiveTextPaint.setAntiAlias( true);


mInactiveTextPaint.setTextAlign(Align.CENTER);
mInactiveTextPaint.setTextSize(12);
mInactiveTextPaint.setColor(0xFF999999);
mInactiveTextPaint.setAntiAlias( true);
mActiveTab=0;

}

@Override
protected voidonDraw(Canvascanvas)
{
super.onDraw(canvas);

Rectr= newRect();
this.getDrawingRect(r);

// 计算每个标签能使用多少像素
intsingleTabWidth=r.right/(mTabMembers.size()!=0?mTabMembers.size():1);


// 绘制背景
canvas.drawColor(0xFF000000);
mPaint.setColor(0xFF434343);
canvas.drawLine(r.left,r.top+1,r.right,r.top+1,mPaint);

intcolor=46;

for( inti=0;i<24;i++)
{
mPaint.setARGB(255,color,color,color);
canvas.drawRect(r.left,r.top+i+1,r.right,r.top+i+2,mPaint);
color--;
}

// 绘制每一个tab
for( inti=0;i<mTabMembers.size();i++)
{
TabMembertabMember=mTabMembers.get(i);

Bitmapicon=BitmapFactory.decodeResource(getResources(),tabMember.getIconResourceId());
BitmapiconColored=Bitmap.createBitmap(icon.getWidth(),icon.getHeight(),Bitmap.Config.ARGB_8888);
Paintp= newPaint(Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
CanvasiconCanvas= newCanvas();
iconCanvas.setBitmap(iconColored);

if(mActiveTab==i) // 为已选中的tab绘制一个白蓝的渐变色,未选中的绘制一个白灰的渐变色
{
p.setShader( newLinearGradient(0,0,icon.getWidth(),icon.getHeight(),
0xFFFFFFFF,0xFF54C7E1,Shader.TileMode.CLAMP));
}
else{
p.setShader( newLinearGradient(0,0,icon.getWidth(),icon.getHeight(),
0xFFA2A2A2,0xFF5F5F5F,Shader.TileMode.CLAMP));
}

iconCanvas.drawRect(0,0,icon.getWidth(),icon.getHeight(),p);

for( intx=0;x<icon.getWidth();x++)
{
for( inty=0;y<icon.getHeight();y++)
{
if((icon.getPixel(x,y)&0xFF000000)==0)
{
iconColored.setPixel(x,y,0x00000000);
}
}
}

// 计算tab图片的位置
inttabImgX=singleTabWidth*i+(singleTabWidth/2-icon.getWidth()/2);

// 绘制tab图片选中的和未选中的
if(mActiveTab==i)
{
mPaint.setARGB(37,255,255,255);
canvas.drawRoundRect( newRectF(r.left+singleTabWidth*i+3,r.top+3,
r.left+singleTabWidth*(i+1)-3,r.bottom-2),5,5,mPaint);
canvas.drawBitmap(iconColored,tabImgX,r.top+5, null);
canvas.drawText(tabMember.getText(),
singleTabWidth*i+(singleTabWidth/2),r.bottom-2,mActiveTextPaint);
} else
{
canvas.drawBitmap(iconColored,tabImgX,r.top+5, null);
canvas.drawText(tabMember.getText(),
singleTabWidth*i+(singleTabWidth/2),r.bottom-2,mInactiveTextPaint);
}
}

}
/*
*触摸事件
*/
@Override
public booleanonTouchEvent(MotionEventmotionEvent)
{
Rectr= newRect();
this.getDrawingRect(r);
floatsingleTabWidth=r.right/(mTabMembers.size()!=0?mTabMembers.size():1);

intpressedTab=( int)((motionEvent.getX()/singleTabWidth)-(motionEvent.getX()/singleTabWidth)%1);

mActiveTab=pressedTab;

if( this.mOnTabClickListener!= null)
{
this.mOnTabClickListener.onTabClick(mTabMembers.get(pressedTab).getId());
}

this.invalidate();

return super.onTouchEvent(motionEvent);
}

voidaddTabMember(TabMembertabMember)
{
mTabMembers.add(tabMember);
}

voidsetOnTabClickListener(OnTabClickListeneronTabClickListener)
{
mOnTabClickListener=onTabClickListener;
}

public static classTabMember // 处理tab成员
{
protected intmId;
protectedStringmText;
protected intmIconResourceId;

TabMember( intId,StringText, inticonResourceId)
{
mId=Id;
mIconResourceId=iconResourceId;
mText=Text;
}

public intgetId()
{
returnmId;
}

publicStringgetText()
{
returnmText;
}

public intgetIconResourceId()
{
returnmIconResourceId;
}

public voidsetText(StringText)
{
mText=Text;
}

public voidsetIconResourceId( inticonResourceId)
{
mIconResourceId=iconResourceId;
}
}

public static interfaceOnTabClickListener
{
public abstract voidonTabClick( inttabId);
}
}

这是MainActivity这个类里面的两个static类,看我写的注释和上篇博客的内容应该都能理解。其中还定义了触摸事件,实现点击tab出现不同布局的效果。接下来我们只需要在我们的layout上添加就可以了,我们继续写一个内部类

public static classiRelativeLayout extendsRelativeLayout // 注意,还是声明为静态
{
privatePaintmPaint;
privateRectmRect;

publiciRelativeLayout(Contextcontext,AttributeSetattrs)
{
super(context,attrs);

mRect= newRect();
mPaint= newPaint();

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setColor(0xFFCBD2D8);
}

@Override
protected voidonDraw(Canvascanvas)
{
super.onDraw(canvas);

canvas.drawColor(0xFFC5CCD4);

this.getDrawingRect(mRect);

for( inti=0;i<mRect.right;i+=7) // 绘制屏幕背景的纹理效果
{
canvas.drawRect(mRect.left+i,mRect.top,mRect.left+i+2,mRect.bottom,mPaint);
}

}
}


private static final intTAB_HIGHLIGHT=1;
private static final intTAB_CHAT=2;
private static final intTAB_LOOPBACK=3;
private static final intTAB_REDO=4;
privateiTabmTabs;
privateLinearLayoutmTabLayout_One;
privateLinearLayoutmTabLayout_Two;
privateLinearLayoutmTabLayout_Three;
privateLinearLayoutmTabLayout_Four;
privateLinearLayoutmTabLayout_Five;

@Override
public voidonCreate(BundlesavedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);


mTabs=(iTab) this.findViewById(R.id.Tabs);
mTabLayout_One=(LinearLayout) this.findViewById(R.id.TabLayout_One);
mTabLayout_Two=(LinearLayout) this.findViewById(R.id.TabLayout_Two);
mTabLayout_Three=(LinearLayout) this.findViewById(R.id.TabLayout_Three);
mTabLayout_Four=(LinearLayout) this.findViewById(R.id.TabLayout_Four);
mTabLayout_Five=(LinearLayout) this.findViewById(R.id.TabLayout_Four); // 偷个懒,不写第五个界面啦

mTabs.addTabMember( newTabMember(TAB_HIGHLIGHT,"精选",R.drawable.jingxuan));
mTabs.addTabMember( newTabMember(TAB_CHAT,"类别",R.drawable.cat));
mTabs.addTabMember( newTabMember(TAB_LOOPBACK,"25大排行榜",R.drawable.rank));
mTabs.addTabMember( newTabMember(TAB_REDO,"搜索",R.drawable.search));
mTabs.addTabMember( newTabMember(TAB_REDO,"更新",R.drawable.download)); // 添加tab

/* 初始显示第一个界面 */
mTabLayout_One.setVisibility(View.VISIBLE);
mTabLayout_Two.setVisibility(View.GONE);
mTabLayout_Three.setVisibility(View.GONE);
mTabLayout_Four.setVisibility(View.GONE);

mTabs.setOnTabClickListener( newOnTabClickListener(){
@Override
public voidonTabClick( inttabId) // 实现点击事件
{
if(tabId==TAB_HIGHLIGHT)
{
mTabLayout_One.setVisibility(View.VISIBLE);
mTabLayout_Two.setVisibility(View.GONE);
mTabLayout_Three.setVisibility(View.GONE);
mTabLayout_Four.setVisibility(View.GONE);
} else if(tabId==TAB_CHAT)
{
mTabLayout_One.setVisibility(View.GONE);
mTabLayout_Two.setVisibility(View.VISIBLE);
mTabLayout_Three.setVisibility(View.GONE);
mTabLayout_Four.setVisibility(View.GONE);
} else if(tabId==TAB_LOOPBACK)
{
mTabLayout_One.setVisibility(View.GONE);
mTabLayout_Two.setVisibility(View.GONE);
mTabLayout_Three.setVisibility(View.VISIBLE);
mTabLayout_Four.setVisibility(View.GONE);
} else if(tabId==TAB_REDO)
{
mTabLayout_One.setVisibility(View.GONE);
mTabLayout_Two.setVisibility(View.GONE);
mTabLayout_Three.setVisibility(View.GONE);
mTabLayout_Four.setVisibility(View.VISIBLE);
}
}
});
}

其中onDraw()方法里面实现了背景的纹理效果,配合xml里面背景色的配置,实现了如下图所示的效果:

android UI进阶之仿iphone的tab效果

是不是非常漂亮呢。下面就是xml里面的配置了

<? xmlversion="1.0"encoding="utf-8" ?>

< view xmlns:android ="http://schemas.android.com/apk/res/android"
class
="com.notice520.MainActivity$iRelativeLayout"
android:orientation
="vertical"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:background
="#C5CCD4FF"
>
< LinearLayout
android:id ="@+id/TabLayout_One"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:layout_above
="@+id/Tabs"
>
< ScrollView android:layout_width ="fill_parent" android:layout_height ="wrap_content" >
< RelativeLayout
android:layout_width ="fill_parent"
android:layout_height
="fill_parent"
android:visibility
="visible"
>
< TextView
android:textColor ="@android:color/black"
android:textSize
="30sp"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:text
="春节快乐!!"
/>
</ RelativeLayout >
</ ScrollView >
</ LinearLayout >

< LinearLayout
android:id ="@+id/TabLayout_Two"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:layout_above
="@+id/Tabs"
>
< ScrollView android:layout_width ="fill_parent" android:layout_height ="wrap_content" >
< RelativeLayout
android:layout_width ="fill_parent"
android:layout_height
="fill_parent"
android:visibility
="visible"
android:layout_above
="@+id/Tabs"
>
< Button
android:layout_width ="wrap_content"
android:layout_height
="wrap_content"
android:text
="祝大家事业有成!"
android:textSize
="30sp"
/>
</ RelativeLayout >
</ ScrollView >
</ LinearLayout >
< LinearLayout
android:id ="@+id/TabLayout_Three"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:layout_above
="@+id/Tabs"
>
< ScrollView android:layout_width ="fill_parent" android:layout_height ="wrap_content" >
< RelativeLayout
android:layout_width ="fill_parent"
android:layout_height
="fill_parent"
android:visibility
="visible"
android:layout_above
="@+id/Tabs"
>
< ImageView

android:layout_width ="fill_parent"
android:layout_height
="fill_parent"
android:src
="@drawable/newq"
/>
</ RelativeLayout >
</ ScrollView >
</ LinearLayout >
< LinearLayout
android:id ="@+id/TabLayout_Four"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:layout_above
="@+id/Tabs"
>
< ScrollView android:layout_width ="fill_parent" android:layout_height ="wrap_content" >
< RelativeLayout
android:id ="@+id/TabLayout_Four"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:visibility
="visible"
android:layout_above
="@+id/Tabs"
>
< TextView
android:textColor ="@android:color/black"
android:layout_width
="wrap_content"
android:layout_height
="wrap_content"
android:text
="很简单,是么"
/>
</ RelativeLayout >
</ ScrollView >
</ LinearLayout >
< view
class ="com.notice520.MainActivity$iTab"
android:id
="@+id/Tabs"
android:layout_width
="fill_parent"
android:layout_height
="49px"
android:layout_alignParentBottom
="true"
/>
</ view >

来看看最终的效果吧

android UI进阶之仿iphone的tab效果

是不是还不错呢 希望大家喜欢,有问题可以留言交流。

Trackback:http://www.cnblogs.com/noTice520/archive/2011/01/29/1947490.html

更多相关文章

  1. Android UI设计之自定义TextView属性,实现带边框效果的TextView
  2. Android中如何使用ViewPager实现类似laucher左右拖动效果
  3. 仿网易新闻效果源码分析
  4. Android滤镜效果实现及原理分析
  5. [置顶] 我的Android进阶之旅------>Android颜色值(RGB)所支持的
  6. Android宝典入门篇-进阶
  7. android 实现带清除效果的EditText(附带抖动效果)

随机推荐

  1. android 和linux的休眠唤醒机制
  2. Android(安卓)面试题总结之Android(安卓)
  3. Ubuntu下android学习——(2)Android系统构
  4. [Android算法] Android蓝牙开发浅谈
  5. Android(安卓)设置页面的设计
  6. Android工程 引用另外一个Android工程(类
  7. Android官方离线文档(API文档)打开速度慢的
  8. Android中Cursor关闭的问题
  9. Android应用程序资源管理器(Asset Manager
  10. Android:增强目录选择器对话框