Android中实现可滑动的Tab的3种方式
1. 第一种,使用 tabhost + viewpager 实现
该方法会有一个bug,当设置tabhost.setcurrenttab()为0时,viewpager不显示(准确的说是加载),只有点击其他任意一个tab后才会加载。
有解的同学吼一声~~~~~~~
activity:
package com.swordy.demo.android.fragment;
import java.util.random;
import android.os.bundle;
import android.support.v4.app.fragment;
import android.support.v4.app.fragmentactivity;
import android.support.v4.app.fragmentmanager;
import android.support.v4.app.fragmentstatepageradapter;
import android.support.v4.view.pageradapter;
import android.support.v4.view.viewpager;
import android.support.v4.view.viewpager.onpagechangelistener;
import android.view.layoutinflater;
import android.view.view;
import android.view.view.onclicklistener;
import android.view.viewgroup;
import android.widget.tabhost;
import android.widget.tabhost.ontabchangelistener;
import android.widget.tabwidget;
import android.widget.textview;
import com.swordy.demo.android.r;
import com.swordy.library.android.util.elog;
/**
* 1. 使用tabhost和viewpager组合实现一个可以滑动的tab
* 2. bug:如果当前页为0,则viewpager第一次不加载。
*
* @author swordy
* @email mryangjian@live.com
* @since jan 20, 2014
* @version 1.0
*/
public class slidetabs1 extends fragmentactivity
{
private static final string tag = "androiddemos.slidetabs1";
private tabhost mtabhost;
private viewpager mviewpager;
private pageradapter mpageradapter;
private string[] addresses = { "first", "second", "third" };
@override
protected void oncreate(bundle arg0)
{
super.oncreate(arg0);
setcontentview(r.layout.fragment_slidetabs1);
mviewpager = (viewpager) findviewbyid(r.id.viewpager1);
mpageradapter = new mypageradapter(getsupportfragmentmanager());
mviewpager.setadapter(mpageradapter);
mtabhost = (tabhost) findviewbyid(android.r.id.tabhost);
mtabhost.setup();
mtabhost.addtab(mtabhost.newtabspec("one").setindicator("one-1")
.setcontent(r.id.viewpager1));
mtabhost.addtab(mtabhost.newtabspec("two").setindicator("two-2")
.setcontent(r.id.viewpager1));
mtabhost.addtab(mtabhost.newtabspec("three").setindicator("three-3")
.setcontent(r.id.viewpager1));
tabwidget tabwidget = mtabhost.gettabwidget();
int count = tabwidget.getchildcount();
for (int i = 0; i != count; i++)
{
final int index = i;
tabwidget.getchildat(i).setonclicklistener(new onclicklistener() {
@override
public void onclick(view v)
{
mtabhost.setcurrenttab(index);
mviewpager.setcurrentitem(index);
}
});
}
mtabhost.setontabchangedlistener(new ontabchangelistener() {
@override
public void ontabchanged(string tabid)
{
elog.i(tag, "@--> ontabchanged by tabid: " + tabid);
}
});
mviewpager.setonpagechangelistener(new onpagechangelistener() {
@override
public void onpageselected(int arg0)
{
elog.i(tag, "@--> onpageselected: " + arg0);
mtabhost.setcurrenttab(arg0);
}
@override
public void onpagescrolled(int arg0, float arg1, int arg2)
{
}
@override
public void onpagescrollstatechanged(int arg0)
{
}
});
}
private class mypageradapter extends fragmentstatepageradapter
{
public mypageradapter(fragmentmanager fm)
{
super(fm);
}
@override
public fragment getitem(int position)
{
elog.i(tag, "@--> getitem by position" + position);
elog.i(tag, "@--> getitem by position" + position);
return myfragment.create(addresses[position]);
}
@override
public int getcount()
{
return addresses.length;
}
}
public static class myfragment extends fragment
{
public static myfragment create(string address)
{
elog.i(tag, "@--> myfragment.create()");
myfragment f = new myfragment();
bundle b = new bundle();
b.putstring("address", address);
f.setarguments(b);
return f;
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container,
bundle savedinstancestate)
{
random r = new random(system.currenttimemillis());
bundle b = getarguments();
view v = inflater.inflate(r.layout.fragment_viewpager1_layout1, null);
v.setbackgroundcolor(r.nextint() >> 8 | 0xff << 24);
textview txvaddress = (textview) v.findviewbyid(r.id.textview1);
txvaddress.settextcolor(r.nextint() >> 8 | 0xff << 24);
txvaddress.setbackgroundcolor(r.nextint() >> 8 | 0xff << 24);
txvaddress.settext(b.getstring("address", ""));
return v;
}
}
}
布局:
<?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="match_parent"
android:layout_height="match_parent" >
<linearlayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<tabwidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right|center_vertical" />
<framelayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.viewpager
android:id="@+id/viewpager1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</framelayout>
</linearlayout>
</tabhost>
2. 第二种,使用官方提供的方法 actionbar + viewpager 实现
该方法有两个缺陷,或者说不是缺陷,只是我没有找到解决的办法。
第一,tab点上不是很灵敏,可能就是这么设定的,为了防止频繁加载吧,但是体验稍稍不爽;
第二,actionbar在最顶部,如果我的布局是:顶部一个带返回按钮的标题栏,中间是tab,底部是tabcontent,怎么搞?
activity:
package com.swordy.demo.android.fragment;
import java.util.random;
import android.app.actionbar;
import android.app.actionbar.tab;
import android.app.actionbar.tablistener;
import android.os.bundle;
import android.support.v4.app.fragment;
import android.support.v4.app.fragmentactivity;
import android.support.v4.app.fragmentmanager;
import android.support.v4.app.fragmentpageradapter;
import android.support.v4.view.viewpager;
import android.support.v4.view.viewpager.onpagechangelistener;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.widget.textview;
import com.swordy.demo.android.r;
/**
* 1. 使用actionbar和viewpager实现可以滑动的tab
*
* @author swordy
* @email mryangjian@live.com
* @since jan 20, 2014
* @version 1.0
*/
public class slidetabs2 extends fragmentactivity
{
private static final string tag = "androiddemos.slidetabs2";
private viewpager mviewpager;
private actionbar mactionbar;
private mypageradapter mpageradapter;
private string[] addresses = { "first", "second", "third" };
private tab[] mtabs = new tab[addresses.length];
@override
protected void oncreate(bundle savedinstancestate)
{
super.oncreate(savedinstancestate);
setcontentview(r.layout.fragment_viewpager1);
mviewpager = (viewpager) findviewbyid(r.id.viewpager1);
mpageradapter = new mypageradapter(getsupportfragmentmanager());
mviewpager.setadapter(mpageradapter);
mviewpager.setonpagechangelistener(mpagechangelistener);
mactionbar = getactionbar();
mactionbar.setnavigationmode(actionbar.navigation_mode_tabs);
mactionbar.setdisplayshowtitleenabled(false);
mactionbar.setdisplayshowhomeenabled(false);
for (int i = 0; i != addresses.length; i++)
{
mtabs[i] = mactionbar.newtab().settext(addresses[i]).settablistener(mtablistener);
mactionbar.addtab(mtabs[i]);
}
}
private onpagechangelistener mpagechangelistener = new onpagechangelistener() {
@override
public void onpageselected(int arg0)
{
mactionbar.setselectednavigationitem(arg0);
}
@override
public void onpagescrolled(int arg0, float arg1, int arg2)
{
}
@override
public void onpagescrollstatechanged(int arg0)
{
}
};
private tablistener mtablistener = new tablistener() {
@override
public void ontabselected(tab tab, android.app.fragmenttransaction ft)
{
if (tab == mtabs[0])
{
mviewpager.setcurrentitem(0);
} else if (tab == mtabs[1])
{
mviewpager.setcurrentitem(1);
} else if (tab == mtabs[2])
{
mviewpager.setcurrentitem(2);
}
}
@override
public void ontabunselected(tab tab, android.app.fragmenttransaction ft)
{
// todo auto-generated method stub
}
@override
public void ontabreselected(tab tab, android.app.fragmenttransaction ft)
{
// todo auto-generated method stub
}
};
public class mypageradapter extends fragmentpageradapter
{
public mypageradapter(fragmentmanager fm)
{
super(fm);
}
@override
public fragment getitem(int position)
{
return myfragment.create(addresses[position]);
}
@override
public int getcount()
{
return addresses.length;
}
}
public static class myfragment extends fragment
{
public static myfragment create(string address)
{
myfragment f = new myfragment();
bundle b = new bundle();
b.putstring("address", address);
f.setarguments(b);
return f;
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container,
bundle savedinstancestate)
{
random r = new random(system.currenttimemillis());
bundle b = getarguments();
view v = inflater.inflate(r.layout.fragment_viewpager1_layout1, null);
v.setbackgroundcolor(r.nextint() >> 8 | 0xff << 24);
textview txvaddress = (textview) v.findviewbyid(r.id.textview1);
txvaddress.settextcolor(r.nextint() >> 8 | 0xff << 24);
txvaddress.setbackgroundcolor(r.nextint() >> 8 | 0xff << 24);
txvaddress.settext(b.getstring("address", ""));
return v;
}
}
}
布局:
<?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="match_parent"
android:orientation="vertical" >
<android.support.v4.view.viewpager
android:id="@+id/viewpager1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</linearlayout>
3. 【推荐】第三种,使用 tabwidget + viewpager 实现
该方法不错,推荐使用。
activity:
package com.swordy.demo.android.fragment;
import java.util.random;
import android.os.bundle;
import android.support.v4.app.fragment;
import android.support.v4.app.fragmentactivity;
import android.support.v4.app.fragmentmanager;
import android.support.v4.app.fragmentstatepageradapter;
import android.support.v4.view.pageradapter;
import android.support.v4.view.viewpager;
import android.support.v4.view.viewpager.onpagechangelistener;
import android.view.layoutinflater;
import android.view.view;
import android.view.view.onclicklistener;
import android.view.viewgroup;
import android.widget.button;
import android.widget.tabwidget;
import android.widget.textview;
import com.swordy.demo.android.r;
/**
* 1. 使用tabwidget和viewpager实现可滑动的tab
*
* @author swordy
* @email mryangjian@live.com
* @since jan 20, 2014
* @version 1.0
*/
public class slidetabs3 extends fragmentactivity
{
private static final string tag = "androiddemos.slidetabs3";
private viewpager mviewpager;
private pageradapter mpageradapter;
private tabwidget mtabwidget;
private string[] addresses = { "first", "second", "third" };
private button[] mbtntabs = new button[addresses.length];
@override
protected void oncreate(bundle savedinstancestate)
{
super.oncreate(savedinstancestate);
setcontentview(r.layout.fragment_slidetabs3);
mtabwidget = (tabwidget) findviewbyid(r.id.tabwidget1);
mtabwidget.setstripenabled(false);
mbtntabs[0] = new button(this);
mbtntabs[0].setfocusable(true);
mbtntabs[0].settext(addresses[0]);
mbtntabs[0].settextcolor(getresources().getcolorstatelist(r.color.button_bg_color_selector));
mtabwidget.addview(mbtntabs[0]);
/*
* listener必须在mtabwidget.addview()之后再加入,用于覆盖默认的listener,
* mtabwidget.addview()中默认的listener没有nullpointer检测。
*/
mbtntabs[0].setonclicklistener(mtabclicklistener);
mbtntabs[1] = new button(this);
mbtntabs[1].setfocusable(true);
mbtntabs[1].settext(addresses[1]);
mbtntabs[1].settextcolor(getresources().getcolorstatelist(r.color.button_bg_color_selector));
mtabwidget.addview(mbtntabs[1]);
mbtntabs[1].setonclicklistener(mtabclicklistener);
mbtntabs[2] = new button(this);
mbtntabs[2].setfocusable(true);
mbtntabs[2].settext(addresses[2]);
mbtntabs[2].settextcolor(getresources().getcolorstatelist(r.color.button_bg_color_selector));
mtabwidget.addview(mbtntabs[2]);
mbtntabs[2].setonclicklistener(mtabclicklistener);
mviewpager = (viewpager) findviewbyid(r.id.viewpager1);
mpageradapter = new mypageradapter(getsupportfragmentmanager());
mviewpager.setadapter(mpageradapter);
mviewpager.setonpagechangelistener(mpagechangelistener);
mtabwidget.setcurrenttab(0);
}
private onclicklistener mtabclicklistener = new onclicklistener() {
@override
public void onclick(view v)
{
if (v == mbtntabs[0])
{
mviewpager.setcurrentitem(0);
} else if (v == mbtntabs[1])
{
mviewpager.setcurrentitem(1);
} else if (v == mbtntabs[2])
{
mviewpager.setcurrentitem(2);
}
}
};
private onpagechangelistener mpagechangelistener = new onpagechangelistener() {
@override
public void onpageselected(int arg0)
{
mtabwidget.setcurrenttab(arg0);
}
@override
public void onpagescrolled(int arg0, float arg1, int arg2)
{
}
@override
public void onpagescrollstatechanged(int arg0)
{
}
};
private class mypageradapter extends fragmentstatepageradapter
{
public mypageradapter(fragmentmanager fm)
{
super(fm);
}
@override
public fragment getitem(int position)
{
return myfragment.create(addresses[position]);
}
@override
public int getcount()
{
return addresses.length;
}
}
public static class myfragment extends fragment
{
public static myfragment create(string address)
{
myfragment f = new myfragment();
bundle b = new bundle();
b.putstring("address", address);
f.setarguments(b);
return f;
}
@override
public view oncreateview(layoutinflater inflater, viewgroup container,
bundle savedinstancestate)
{
random r = new random(system.currenttimemillis());
bundle b = getarguments();
view v = inflater.inflate(r.layout.fragment_viewpager1_layout1, null);
v.setbackgroundcolor(r.nextint() >> 8 | 0xff << 24);
textview txvaddress = (textview) v.findviewbyid(r.id.textview1);
txvaddress.settextcolor(r.nextint() >> 8 | 0xff << 24);
txvaddress.setbackgroundcolor(r.nextint() >> 8 | 0xff << 24);
txvaddress.settext(b.getstring("address", ""));
return v;
}
}
}
布局:
<?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="match_parent"
android:orientation="vertical" >
<tabwidget
android:id="@+id/tabwidget1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right|center_vertical" />
<android.support.v4.view.viewpager
android:id="@+id/viewpager1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</linearlayout>
推荐阅读