您的位置:首页 > 移动开发 > Android开发

android自定义tabbar,并带badgeview消息提示

2014-10-14 14:10 417 查看
最早的时候,我用的tab都是在屏幕底端的,后来慢慢的流行在屏幕顶端了,按照用户体验来说,顶部确实比底部好,不仅可以防止按到返回键或者Home等引起误操作,而且tab标题在头顶很显眼很醒目。

一开始朋友推荐使用viewpageindicator,这个可以在github上有例子,大家如果没什么特殊需求,基本可以满足要求。根据项目要求我就使用了viewpageindicator,后来项目要求有消息提示,就像ios的badge一样,因此就对viewpageindicator进行修改,改了之后,就出现了下图的情况


就是badge是有了,但是把原本的tab给破坏了,后来我按照viewpageindicator的方式自己写了个例子,加上badge也出现了这种情况,估计tabwidget不适合这种模式(也可能是我水平有限,高手们应该有办法),而且viewpageindicator比较负责,有那么多代码和样式,还得引入library,还得把原本的android-support-v4.jar给删除等等,从而会引起别的问题,虽然都能解决,但是觉得很麻烦,就打算自己再重写一个,tabbar不用tabwidget,而是自己自定义布局tabbar.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<LinearLayout
android:id="@+id/tab_first"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/tab_bg"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dip" >

<TextView
android:id="@+id/text_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/first"
android:textColor="@color/green"
android:textSize="15sp" />
</LinearLayout>

<LinearLayout
android:id="@+id/tab_second"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/tab_bg"
android:clickable="true"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dip"
android:saveEnabled="false" >

<TextView
android:id="@+id/text_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/second"
android:textColor="@color/black"
android:textSize="15sp" />
</LinearLayout>

<LinearLayout
android:id="@+id/tab_third"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/tab_bg"
android:focusable="false"
android:gravity="center"
android:orientation="horizontal"
android:padding="10dip" >

<TextView
android:id="@+id/text_third"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/third"
android:textColor="@color/black"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>

<ImageView
android:id="@+id/tab_under_line"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:background="@drawable/vpi__tab_selected_pressed_holo" >
</ImageView>

</LinearLayout>
整体布局在activity_main.xml里
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<include layout="@layout/tabbar"/>

<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</LinearLayout>


先上个截图看看吧



可能比较粗糙,大家可以自行修改
接着就是初始化一系列view,事件绑定,适配器初始化等
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化屏幕宽度
DisplayMetrics outMetrics = new DisplayMetrics();
getWindow().getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
screenWidth = outMetrics.widthPixels;

//初始化三个页面
FirstTabFragment firstTabFragment = new FirstTabFragment();
SecondTabFragment secondTabFragment = new SecondTabFragment();
ThirdTabFragment thirdTabFragment = new ThirdTabFragment();
fragments.add(firstTabFragment);
fragments.add(secondTabFragment);
fragments.add(thirdTabFragment);
fragSize = fragments.size();

//初始化顶部三个tab
firstTab = (LinearLayout) findViewById(R.id.tab_first);
secondTab = (LinearLayout) findViewById(R.id.tab_second);
thirdTab = (LinearLayout) findViewById(R.id.tab_third);
//给tab设置点击事件
firstTab.setOnClickListener(tabClickListener);
secondTab.setOnClickListener(tabClickListener);
thirdTab.setOnClickListener(tabClickListener);
//初始化tab选中后的下划线
initTabUnderLine();

firstText = (TextView) findViewById(R.id.text_first);
secondText = (TextView) findViewById(R.id.text_second);
thirdText = (TextView) findViewById(R.id.text_third);

viewPager = (ViewPager)findViewById(R.id.viewpager);
pagerAdapter = new MyPageAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
viewPager.setOnPageChangeListener(pageChangeListener);

//example 给第一个tab加上badge
BadgeView badge;
badge = new BadgeView(MainActivity.this, firstTab);
badge.setText("1");
badge.show();
}
最后就是选中的tab下划线(滑块)的处理,在onPageScrolled方法里
//从左到右
if(currentIndex == position) {
LinearLayout.LayoutParams layoutParam = (android.widget.LinearLayout.LayoutParams) tabUnderLine
.getLayoutParams();
layoutParam.leftMargin = (int) (positionOffset * (screenWidth * 1.0 / fragSize) + currentIndex * (screenWidth / fragSize));
tabUnderLine.setLayoutParams(layoutParam);
}
//从右到左
else if(currentIndex > position){
LinearLayout.LayoutParams layoutParam = (android.widget.LinearLayout.LayoutParams) tabUnderLine
.getLayoutParams();
layoutParam.leftMargin = (int) (-(1-positionOffset) * (screenWidth * 1.0 / fragSize) + currentIndex * (screenWidth / fragSize));
tabUnderLine.setLayoutParams(layoutParam);
}
tabbar就这样基本实现了流转,向左滑向右滑,点击tab都没问题,tab点击事件很简单
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == firstTab){
viewPager.setCurrentItem(0);
}
else if(v == secondTab){
viewPager.setCurrentItem(1);
}
else if(v == thirdTab){
viewPager.setCurrentItem(2);
}
}
设置viewpager的当前就行。
最后再来说说消息提醒数目badge,在这里就非常简单,只需获取tab的LinearLayout,在LinearLayout上显示badgeview,不会影响之前的布局

//example 给第一个tab加上badge
BadgeView badge;
badge = new BadgeView(MainActivity.this, firstTab);
badge.setText("1");
badge.show();


语言组织能力不是很好,还望体谅,同时本人也是网上查询了很多例子才写成,多谢各位大神。

具体内容就是下载代码进行理解,下面放出传送门到github上

源代码传送门
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: