欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中实现可滑动的Tab的3种方式

程序员文章站 2022-06-19 19:55:43
1. 第一种,使用 tabhost + viewpager 实现该方法会有一个bug,当设置tabhost.setcurrenttab()为0时,viewpager不显示(...

1. 第一种,使用 tabhost + viewpager 实现
该方法会有一个bug,当设置tabhost.setcurrenttab()为0时,viewpager不显示(准确的说是加载),只有点击其他任意一个tab后才会加载。

有解的同学吼一声~~~~~~~

Android中实现可滑动的Tab的3种方式

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,怎么搞?

Android中实现可滑动的Tab的3种方式

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 实现
该方法不错,推荐使用。

Android中实现可滑动的Tab的3种方式

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>