自定义RadioButton和ViewPager实现TabHost带滑动的页卡效果
程序员文章站
2023-12-14 08:16:28
在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的tabhost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使...
在工作中又很多需求都不是android系统自带的控件可以达到效果的,内置的tabhost就是,只能达到简单的效果 ,所以这个时候就要自定义控件来达到效果:这个效果就是: 使用自定义radiobutton和viewpager实现tabhost带滑动的页卡效果。
这篇文章技术含量一般,大家别见笑。源码我以测试,在底部可下载。
好了先上效果图:
以下是实现步骤:
1、准备自定义radiobutton控件的样式图片等,就是准备配置文件:
(1)、 在项目的values文件夹里面创建 attrs.xml :
复制代码 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myradiobutton">
<attr name="pic" format="reference" />
</declare-styleable>
</resources>
(2)、创建 styles.xml:
复制代码 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="radiobuttonstyle">
<item name="android:button">@null</item>
<item name="android:textsize">12dip</item>
<item name="android:gravity">center_horizontal|bottom</item>
<item name="android:paddingbottom">5dip</item>
</style>
</resources>
(3)、把中文定义在string.xml里:
复制代码 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">hello world, mainact!</string>
<string name="app_name">tabhost</string>
<string name="home">大厅</string>
<string name="account">用户</string>
<string name="beanexchange">玩具</string>
<string name="winacciche">公告</string>
<string name="more">更多</string>
</resources>
(4)、创建myradiobutton类继承radiobutton:
复制代码 代码如下:
package com.dome.viewer.widget;
import com.dome.viewer.r;
import android.content.context;
import android.content.res.typedarray;
import android.graphics.bitmap;
import android.graphics.canvas;
import android.graphics.paint;
import android.graphics.pixelformat;
import android.graphics.drawable.bitmapdrawable;
import android.graphics.drawable.drawable;
import android.graphics.drawable.ninepatchdrawable;
import android.util.attributeset;
import android.widget.radiobutton;
public class myradiobutton extends radiobutton {
private drawable drawable;
public myradiobutton(context context, attributeset attrs) {
super(context, attrs);
typedarray a = context.obtainstyledattributes(attrs, r.styleable.myradiobutton);
drawable = a.getdrawable(r.styleable.myradiobutton_pic);
}
//drawable转换成bitmap
private bitmap drawable2bitmap(drawable drawable) {
if (drawable instanceof bitmapdrawable) {
return ((bitmapdrawable) drawable).getbitmap();
} else if (drawable instanceof ninepatchdrawable) {
bitmap bitmap = bitmap
.createbitmap(
drawable.getintrinsicwidth(),
drawable.getintrinsicheight(),
drawable.getopacity() != pixelformat.opaque ? bitmap.config.argb_8888
: bitmap.config.rgb_565);
canvas canvas = new canvas(bitmap);
drawable.setbounds(0, 0, drawable.getintrinsicwidth(), drawable.getintrinsicheight());
drawable.draw(canvas);
return bitmap;
} else {
return null;
}
}
@override
protected void ondraw(canvas canvas) {
super.ondraw(canvas);
bitmap image = drawable2bitmap(drawable);
if (image != null) {
paint pt = new paint();
pt.setargb(255, 66, 66, 66);
// 消除锯齿
pt.setantialias(true);
// 居中显示图片
int imagex = (int) (this.getwidth() - image.getwidth()) / 2;
canvas.drawbitmap(image, imagex, 2, pt);
pt.setargb(255, 255, 255, 255);
}
}
}
(5)、为activity准备布局文件,命名为:tabhost.xml:
复制代码 代码如下:
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:attrstest="http://schemas.android.com/apk/res/com.dome.viewer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg" >
<relativelayout
android:id="@+id/title"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:background="@drawable/bg_navigation" >
<textview
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centervertical="true"
android:layout_marginleft="5dip"
android:gravity="center"
android:text="首页"
android:textsize="25dip" />
</relativelayout>
<android.support.v4.view.viewpager
android:id="@+id/vpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:paddingbottom="55dip"
android:persistentdrawingcache="animation" />
<radiogroup
android:id="@+id/rg_main_btns"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:layout_alignparentbottom="true"
android:layout_gravity="bottom"
android:background="@drawable/bg_navigation"
android:gravity="center_horizontal"
android:orientation="horizontal" >
<com.dome.viewer.widget.myradiobutton
android:id="@+id/buyhometab"
style="@style/radiobuttonstyle"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
android:checked="true"
attrstest:pic="@drawable/gcdt"
android:text="@string/home" />
<com.dome.viewer.widget.myradiobutton
android:id="@+id/winaffichetab"
style="@style/radiobuttonstyle"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
android:button="@null"
attrstest:pic="@drawable/kjgg"
android:text="@string/winacciche" />
<com.dome.viewer.widget.myradiobutton
android:id="@+id/integraltab"
style="@style/radiobuttonstyle"
android:layout_width="65dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
attrstest:pic="@drawable/jfdh"
android:text="@string/beanexchange" />
<com.dome.viewer.widget.myradiobutton
android:id="@+id/accounttab"
style="@style/radiobuttonstyle"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
attrstest:pic="@drawable/yhzx"
android:text="@string/account" />
<com.dome.viewer.widget.myradiobutton
android:id="@+id/moretab"
style="@style/radiobuttonstyle"
android:layout_width="60dip"
android:layout_height="50dip"
android:background="@drawable/navigation_item"
attrstest:pic="@drawable/more"
android:text="@string/more" />
</radiogroup>
</relativelayout>
(6)、创建tabhostactivity:
复制代码 代码如下:
package com.dome.viewer;
import java.util.arraylist;
import java.util.list;
import android.app.activity;
import android.app.localactivitymanager;
import android.content.intent;
import android.os.bundle;
import android.os.parcelable;
import android.support.v4.view.pageradapter;
import android.support.v4.view.viewpager;
import android.support.v4.view.viewpager.onpagechangelistener;
import android.util.log;
import android.view.view;
import android.view.window;
import android.widget.radiogroup;
public class tabhostactivity extends activity {
@override
protected void onstart() {
super.onstart();
}
private radiogroup radiogroup;
// 页卡内容
private viewpager mpager;
// tab页面列表
private list<view> listviews;
// 当前页卡编号
private localactivitymanager manager = null;
private mypageradapter mpadapter = null;
private int index;
// 更新intent传过来的值
@override
protected void onnewintent(intent intent) {
setintent(intent);
}
@override
protected void onsaveinstancestate(bundle outstate) {
}
@override
public void onbackpressed() {
log.i("","onbackpressed()");
super.onbackpressed();
}
@override
protected void onpause() {
log.i("","onpause()");
super.onpause();
}
@override
protected void onstop() {
log.i("","onstop()");
super.onstop();
}
@override
protected void ondestroy() {
log.i("","ondestroy()");
super.ondestroy();
}
@override
protected void onresume() {
super.onresume();
if(getintent() != null){
index = getintent().getintextra("index", 0);
mpager.setcurrentitem(index);
setintent(null);
}else{
if(index < 4){
index = index+1;
mpager.setcurrentitem(index);
index = index -1;
mpager.setcurrentitem(index);
}else if(index == 4){
index= index-1;
mpager.setcurrentitem(index);
index = index +1;
mpager.setcurrentitem(index);
}
}
}
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
requestwindowfeature(window.feature_no_title);
setcontentview(r.layout.tabhost);
mpager = (viewpager) findviewbyid(r.id.vpager);
manager = new localactivitymanager(this, true);
manager.dispatchcreate(savedinstancestate);
initviewpager();
radiogroup = (radiogroup) this.findviewbyid(r.id.rg_main_btns);
radiogroup.setoncheckedchangelistener(new radiogroup.oncheckedchangelistener() {
public void oncheckedchanged(radiogroup group, int checkedid) {
switch (checkedid) {
case r.id.buyhometab:
index = 0;
listviews.set(0, getview("a", new intent(tabhostactivity.this, onedomeactivity.class)));
mpadapter.notifydatasetchanged();
mpager.setcurrentitem(0);
break;
case r.id.winaffichetab:
index = 1;
listviews.set(1, getview("b", new intent(tabhostactivity.this, towdomeactivity.class)));
mpadapter.notifydatasetchanged();
mpager.setcurrentitem(1);
break;
case r.id.integraltab:
index = 2;
listviews.set(2, getview("c", new intent(tabhostactivity.this, threedomeactivity.class)));
mpadapter.notifydatasetchanged();
mpager.setcurrentitem(2);
break;
case r.id.accounttab:
index = 3;
listviews.set(3, getview("d", new intent(tabhostactivity.this, fourdomeactivity.class)));
mpadapter.notifydatasetchanged();
mpager.setcurrentitem(3);
break;
case r.id.moretab:
index = 4;
listviews.set(4, getview("e", new intent(tabhostactivity.this, fivedomeactivity.class)));
mpadapter.notifydatasetchanged();
mpager.setcurrentitem(4);
break;
default:
break;
}
}
});
}
/**
* 初始化viewpager
*/
private void initviewpager() {
intent intent = null;
listviews = new arraylist<view>();
mpadapter = new mypageradapter(listviews);
intent = new intent(tabhostactivity.this, onedomeactivity.class);
listviews.add(getview("a", intent));
intent = new intent(tabhostactivity.this, towdomeactivity.class);
listviews.add(getview("b", intent));
intent = new intent(tabhostactivity.this, threedomeactivity.class);
listviews.add(getview("c", intent));
intent = new intent(tabhostactivity.this, fourdomeactivity.class);
listviews.add(getview("d", intent));
intent = new intent(tabhostactivity.this, fivedomeactivity.class);
listviews.add(getview("e", intent));
mpager.setoffscreenpagelimit(0);
mpager.setadapter(mpadapter);
mpager.setcurrentitem(0);
mpager.setonpagechangelistener(new myonpagechangelistener());
}
/**
* viewpager适配器
*/
public class mypageradapter extends pageradapter {
public list<view> mlistviews;
public mypageradapter(list<view> mlistviews) {
this.mlistviews = mlistviews;
}
@override
public void destroyitem(view arg0, int arg1, object arg2) {
((viewpager) arg0).removeview(mlistviews.get(arg1));
}
@override
public void finishupdate(view arg0) {
}
@override
public int getcount() {
return mlistviews.size();
}
@override
public object instantiateitem(view arg0, int arg1) {
((viewpager) arg0).addview(mlistviews.get(arg1), 0);
return mlistviews.get(arg1);
}
@override
public boolean isviewfromobject(view arg0, object arg1) {
return arg0 == (arg1);
}
@override
public void restorestate(parcelable arg0, classloader arg1) {
}
@override
public parcelable savestate() {
return null;
}
@override
public void startupdate(view arg0) {
}
}
/**
* 页卡切换监听,viewpager改变同样改变tabhost内容
*/
public class myonpagechangelistener implements onpagechangelistener {
public void onpageselected(int arg0) {
manager.dispatchresume();
switch (arg0) {
case 0:
index = 0;
radiogroup.check(r.id.buyhometab);
listviews.set(0, getview("a", new intent(tabhostactivity.this, onedomeactivity.class)));
mpadapter.notifydatasetchanged();
break;
case 1:
index = 1;
radiogroup.check(r.id.winaffichetab);
listviews.set(1, getview("b", new intent(tabhostactivity.this, towdomeactivity.class)));
mpadapter.notifydatasetchanged();
break;
case 2:
index = 2;
radiogroup.check(r.id.integraltab);
listviews.set(2, getview("c", new intent(tabhostactivity.this, threedomeactivity.class)));
mpadapter.notifydatasetchanged();
break;
case 3:
index = 3;
radiogroup.check(r.id.accounttab);
listviews.set(3, getview("d", new intent(tabhostactivity.this, fourdomeactivity.class)));
mpadapter.notifydatasetchanged();
break;
case 4:
index = 4;
radiogroup.check(r.id.moretab);
listviews.set(4, getview("e", new intent(tabhostactivity.this, fivedomeactivity.class)));
mpadapter.notifydatasetchanged();
break;
}
}
public void onpagescrolled(int arg0, float arg1, int arg2) {
}
public void onpagescrollstatechanged(int arg0) {
}
}
private view getview(string id, intent intent) {
return manager.startactivity(id, intent).getdecorview();
}
}
(7)、然后依次创建5个activity作为页卡,和创建5个xml作为activity的布局文件,如图: