当前位置: 移动技术网 > IT编程>移动开发>Android > Android中实现可滑动的Tab的3种方式

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

ddwyt,小葡萄爸爸,弃妃修仙

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>

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网