利用ViewPageIndicator+ViewPager实现左右滑动带图标tab标签功能

ViewPageIndicator,说白了就是ViewPager的分页指示器。JakeWharton的开源控件ViewPageIndicator提供了标签指引效果:底部小圆点的、底部图标的、底部指示线的、顶部tab标签的(掉图标的tab标签等)、顶部title的等效果,都可以自己修改适合自己的style显示样式。

今天主要介绍的是利用ViewPageIndicator+ViewPager实现左右滑动带图标tab标签功能。

首先我们需要去去Github下载类库:https://github.com/JakeWharton/Android-ViewPagerIndicator。下载下来之后里边主要有两个文件:sample和library。sample里边主要是运行例子,以上所说的效果sample中都有;library是库工程,会作为我们的项目依赖库。


新建一个Android项目工程,将library引入。如果新建的项目libs目录下有android-support-v4.jar,你要将其删除,因为ViewPageIndicator里面有这个库,我们的项目中不允许存在两个android-support-v4.jar,不删除编译不能通过。

下面主要介绍代码,首先看布局文件,很简单,上边一个main_head主页的标题栏,下边tab标签指示器,最下边一个ViewPager。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/white"
    android:orientation="vertical" >

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

    <com.viewpagerindicator.TabPageIndicator
        android:id="@+id/indicator"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>
MainActivity代码:

package com.chuan.viewpagerindicatortest;
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 com.viewpagerindicator.IconPagerAdapter;
import com.viewpagerindicator.TabPageIndicator;


public class MainActivity extends FragmentActivity {
    private static final String[] CONTENT = new String[] { "最新", "最热","穿越"}; 
    private static final int[] ICONS = new int[] {
            R.drawable.news,
            R.drawable.hot,
            R.drawable.random,
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentPagerAdapter adapter = new GoogleMusicAdapter(getSupportFragmentManager());

        ViewPager pager = (ViewPager)findViewById(R.id.pager);
        pager.setAdapter(adapter);

        TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
        indicator.setViewPager(pager);
    }

    class GoogleMusicAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
        public GoogleMusicAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
        }


        @Override
        public CharSequence getPageTitle(int position) {
            return CONTENT[position % CONTENT.length].toUpperCase();
        }

        @Override public int getIconResId(int index) {
          return ICONS[index];
        }

      @Override
        public int getCount() {
          return CONTENT.length;
        }
    }
}

首先我们先定义title和图标的集合,然后 实例化ViewPager和TabPageIndicator,要显示图标就需要重写继承自FragmentPagerAdapter并实现IconPagerAdapter的Adapter类,本例GoogleMusicAdapter。然后设置设置TabPageIndicator和ViewPager关联,就是调用TabPageIndicator的setViewPager(ViewPager view)方法,这样子我们就实现了点击上面的Tab,下面的ViewPager切换,滑动ViewPager上面的Tab跟着切换,ViewPager的item,也就是Fragment,我这里只用了一个TextView来显示从MainActivity传递过来的Tab的标题,只是为了模拟平常我们实际使用中,从Activity传递参数给Fragment,下面是TestFragment代码,其中具体的穿值就是在GoogleMusicAdapter中的getItem中。

 package com.chuan.viewpagerindicatortest;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

public final class TestFragment extends Fragment {
    private static final String KEY_CONTENT = "TestFragment:Content";

    public static TestFragment newInstance(String content) {
        TestFragment fragment = new TestFragment();

        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 20; i++) {
            builder.append(content).append(" ");
        }
        builder.deleteCharAt(builder.length() - 1);
        fragment.mContent = builder.toString();

        return fragment;
    }

    private String mContent = "???";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
            mContent = savedInstanceState.getString(KEY_CONTENT);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        TextView text = new TextView(getActivity());
        text.setGravity(Gravity.CENTER);
        text.setText(mContent);
        text.setTextSize(20 * getResources().getDisplayMetrics().density);
        text.setPadding(20, 20, 20, 20);

        LinearLayout layout = new LinearLayout(getActivity());
        layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        layout.setGravity(Gravity.CENTER);
        layout.addView(text);

        return layout;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(KEY_CONTENT, mContent);
    }
}


当然我们还需要改变标签的显示样式,就需要修改style文件,在AndroidManifest.xml的activity中引用我们自定义style样式


<style name="StyledIndicators" parent="@android:style/Theme.Light">
        <item name="android:windowNoTitle">true</item>
        <item name="vpiCirclePageIndicatorStyle">@style/CustomCirclePageIndicator</item>
        <item name="vpiLinePageIndicatorStyle">@style/CustomLinePageIndicator</item>
        <item name="vpiTitlePageIndicatorStyle">@style/CustomTitlePageIndicator</item>
        <item name="vpiTabPageIndicatorStyle">@style/CustomTabPageIndicator</item>
        <item name="vpiUnderlinePageIndicatorStyle">@style/CustomUnderlinePageIndicator</item>
    </style>

    <style name="CustomTitlePageIndicator">
        <item name="android:background">#18FF0000</item>
        <item name="footerColor">#FFAA2222</item>
        <item name="footerLineHeight">1dp</item>
        <item name="footerIndicatorHeight">3dp</item>
        <item name="footerIndicatorStyle">underline</item>
        <item name="android:textColor">#AA000000</item>
        <item name="selectedColor">#FF000000</item>
        <item name="selectedBold">true</item>
    </style>

    <style name="CustomLinePageIndicator">
        <item name="strokeWidth">4dp</item>
        <item name="lineWidth">30dp</item>
        <item name="unselectedColor">#FF888888</item>
        <item name="selectedColor">#FF880000</item>
    </style>

    <style name="CustomCirclePageIndicator">
        <item name="fillColor">#FF888888</item>
        <item name="strokeColor">#FF000000</item>
        <item name="strokeWidth">2dp</item>
        <item name="radius">10dp</item>
        <item name="centered">true</item>
    </style>

    <style name="CustomTabPageIndicator" parent="Widget.TabPageIndicator">
        <item name="android:background">@drawable/custom_tab_indicator</item>
        <item name="android:textAppearance">@style/CustomTabPageIndicator.Text</item>
        <item name="android:textColor">#FF555555</item>
        <item name="android:textSize">16sp</item>
        <item name="android:divider">@drawable/custom_tab_indicator_divider</item>
        <item name="android:dividerPadding">10dp</item>
        <item name="android:showDividers">middle</item>
        <item name="android:paddingLeft">8dp</item>
        <item name="android:paddingRight">8dp</item>
        <item name="android:fadingEdge">horizontal</item>
        <item name="android:fadingEdgeLength">8dp</item>
    </style>

    <style name="CustomTabPageIndicator.Text" parent="android:TextAppearance.Medium">
        <item name="android:typeface">monospace</item>
    </style>

    <style name="CustomUnderlinePageIndicator">
        <item name="selectedColor">#FFCC0000</item>
        <item name="android:background">#FFCCCCCC</item>
        <item name="fadeLength">1000</item>
        <item name="fadeDelay">1000</item>
    </style>

 

为了实现滑动时标签图标的变化更加明显我们在定义图标集合时应该引用我们在drawable文件夹中的自定义图片文件hot.xml等

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/hot_select" />
    <item android:drawable="@drawable/hot_default" />
</selector>

由于类库中的标签状态图片是蓝色的我们也可以通过修改style中CustomTabPageIndicator的android:background中的drawable来实现我们想要的效果

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Non focused states -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_unselected" />
    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_selected" />
    <!-- Focused states -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_unselected_focused" />
    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/custom_tab_indicator_selected_focused" />
    <!-- Pressed -->
    <!--    Non focused states -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_unselected_pressed" />
    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_selected_pressed" />
    <!--    Focused states -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_unselected_pressed" />
    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/custom_tab_indicator_selected_pressed" />
</selector>

使用ViewPageIndicator默认图标不能居中,所以我们需要修改一下类库library中TabPageIndicator.java文件。我们需要自定义TextView,在TabPageIndicator的继承自TextView中的TabView类中我们需要继承我们自定义的TextView类DrawableCenterTextView,DrawableCenterTextView的内容如下:

package com.viewpagerindicator;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.TextView;

public class DrawableCenterTextView extends TextView {

    public DrawableCenterTextView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }

    public DrawableCenterTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DrawableCenterTextView(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable[] drawables = getCompoundDrawables();
        if (drawables != null) {
            Drawable drawableLeft = drawables[0];
            Drawable drawableRight = drawables[2];
            if (drawableLeft != null || drawableRight != null) {
                float textWidth = getPaint().measureText(getText().toString());
                int drawablePadding = getCompoundDrawablePadding();
                int drawableWidth = 0;
                if (drawableLeft != null)
                    drawableWidth = drawableLeft.getIntrinsicWidth();
                else if (drawableRight != null) {
                    drawableWidth = drawableRight.getIntrinsicWidth();
                }
                float bodyWidth = textWidth + drawableWidth + drawablePadding;
                canvas.translate((getWidth() - bodyWidth) / 2, 0);
            }
        }
        super.onDraw(canvas);
    }
}

图标居中感谢:http://www.cnblogs.com/

最后我们看运行效果


总结使用ViewPagerIndicator还是可以很方便的实现我们想要的效果。

源码下载地址:http://download.csdn.net/detail/xiaoxiaoma_yi/8119057



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值