主界面 Activity
package com.test.viewpagerindicator;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Window;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* viewpagerIndicator 标签指示器
*/
public class MainActivity extends FragmentActivity {
private ViewPager mViewPager;
private ViewpagerIndicator mIndicator;
private List<String> titles = Arrays.asList("天龙八部", "西游记", "红楼梦", "三国演义", "水浒传", "聊斋志异", "猛回头", "梦笔溪谈", "红与黑", "封神榜");
private List<VpSimpleFragment> mFragments = new ArrayList<>();
private FragmentPagerAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
initDatas();
mIndicator.setVisibleTabCount(5);
mIndicator.setTabItemTitles(titles);
mViewPager.setAdapter(mAdapter);
mIndicator.setViewPager(mViewPager, 0);
}
private void initView() {
mViewPager = (ViewPager) findViewById(R.id.id_viewpager);
mIndicator = (ViewpagerIndicator) findViewById(R.id.id_indictor);
}
private void initDatas() {
for (String title : titles) {
VpSimpleFragment fragment = VpSimpleFragment.newInstance(title);
mFragments.add(fragment);
}
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
};
}
}
package com.test.viewpagerindicator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
/**
* 2. 绘制三角形
*
*/
public class ViewpagerIndicator extends LinearLayout {
private Paint mPaint;
private Path mPath;
private int mTriangleWidth;
private int mTriangleHeight;
private static final float RADIO_TRIANGLE_WIDTH = 1 / 6F;
private int mInitTranslationX;
private int mTranslationX;
private int mTabVisibleCount;
private static final int COUNT_DEFAULT_TAB = 4;
private List<String> mTitles;
public ViewpagerIndicator(Context context) {
this(context, null);
}
public ViewpagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewpagerIndicator);
mTabVisibleCount = a.getInt(R.styleable.ViewpagerIndicator_visible_tab_count, COUNT_DEFAULT_TAB);
if (mTabVisibleCount < 0) {
mTabVisibleCount = COUNT_DEFAULT_TAB;
}
a.recycle();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setPathEffect(new CornerPathEffect(3));
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
int cCount = getChildCount();
if (cCount == 0) return;
for (int i = 0; i < cCount; i++) {
View view = getChildAt(i);
LinearLayout.LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.weight = 0;
lp.width = getScreenWidth() / mTabVisibleCount;
view.setLayoutParams(lp);
}
setItemClickEvent();
}
/**
* 获得屏幕的宽度
*
* @return
*/
private int getScreenWidth() {
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
canvas.save();
canvas.translate(mInitTranslationX + mTranslationX, getHeight() + 2);
canvas.drawPath(mPath, mPaint);
canvas.restore();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mTriangleWidth = (int) (w / mTabVisibleCount * RADIO_TRIANGLE_WIDTH);
mInitTranslationX = w / mTabVisibleCount / 2 - mTriangleWidth / 2;
initTriangle();
}
private void initTriangle() {
mTriangleHeight = mTriangleWidth / 2;
mPath = new Path();
mPath.moveTo(0, 0);
mPath.lineTo(mTriangleWidth, 0);
mPath.lineTo(mTriangleWidth / 2, -mTriangleHeight);
mPath.close();
}
/**
* 指示器跟随手指进行滚动的计算
*
* @param position
* @param offset
*/
public void scroll(int position, float offset) {
int tabWidth = getWidth() / mTabVisibleCount;
mTranslationX = (int) (tabWidth * offset + tabWidth * position);
if (position >= (mTabVisibleCount - 2) && offset > 0 && getChildCount() > mTabVisibleCount) {
if (mTabVisibleCount != 1) {
this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth + (int) (tabWidth * offset), 0);
} else {
this.scrollTo((int) (tabWidth * offset + tabWidth * position), 0);
}
}
invalidate();
}
public void setTabItemTitles(List<String> titles) {
if (titles != null && titles.size() > 0) {
this.removeAllViews();
mTitles = titles;
for (String title : mTitles) {
addView(generateTextView(title));
}
setItemClickEvent();
}
}
/**
* 设置可见 tab 数量
*
* @param count
*/
public void setVisibleTabCount(int count) {
mTabVisibleCount = count;
}
/**
* 根据title创建tab
*
* @param title
* @return
*/
private View generateTextView(String title) {
TextView textView = new TextView(getContext());
LinearLayout.LayoutParams lp = new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.width = getScreenWidth() / mTabVisibleCount;
textView.setText(title);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(18);
textView.setTextColor(Color.BLUE);
textView.setLayoutParams(lp);
return textView;
}
/**
* 在这里还存在一个问题,如果开发者需要在 mainactivity 中需要调用setOnPageChangeListener() 怎么办呢?
* 所以我们在这里自己定义一个接口 ,方便使用者调用.
*/
public interface PageOnChangeListener {
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
public void onPageSelected(int position);
public void onPageScrollStateChanged(int state);
}
public PageOnChangeListener mListener;
public void setOnPageChangeListener(PageOnChangeListener listener) {
this.mListener = listener;
}
private ViewPager mViewPager;
/**
* 终极大方法
*
* @param viewPager
* @param pos
*/
public void setViewPager(ViewPager viewPager, int pos) {
this.mViewPager = viewPager;
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
scroll(position, positionOffset);
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mListener != null) {
mListener.onPageSelected(position);
}
highLightTextView(position);
}
@Override
public void onPageScrollStateChanged(int state) {
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
});
mViewPager.setCurrentItem(pos);
highLightTextView(pos);
}
/**
* 重置tab文本颜色
*/
public void resetTextViewColor(){
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view instanceof TextView){
((TextView) view).setTextColor(Color.BLUE);
}
}
}
/**
* 高亮显示某个选中的 tab
* @param pos
*/
public void highLightTextView(int pos) {
resetTextViewColor();
View view = getChildAt(pos);
if (view instanceof TextView){
((TextView) view).setTextColor(Color.BLACK);
}
}
/**
* 设置 tab的点击事件
*/
public void setItemClickEvent(){
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
final int finalI = i;
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mViewPager.setCurrentItem(finalI);
}
});
}
}
}
创建的 Fragment
package com.test.viewpagerindicator;
import android.graphics.Color;
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.TextView;
/**
* 1. 编写Fragment
* A simple {@link Fragment} subclass.
*/
public class VpSimpleFragment extends Fragment {
private String mTitle;
public static final String BUNDLE_TITLE = "title";
public static VpSimpleFragment newInstance(String title) {
Bundle bundle = new Bundle();
bundle.putString(BUNDLE_TITLE, title);
VpSimpleFragment fragment = new VpSimpleFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
if (bundle != null) {
mTitle = bundle.getString(BUNDLE_TITLE);
}
TextView textView = new TextView(getActivity());
textView.setText(mTitle);
textView.setGravity(Gravity.CENTER);
textView.setTextColor(Color.RED);
textView.setTextSize(24);
return textView;
}
}
布局文件 activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gaao="http://schemas.android.com/apk/res-atuo/com.test.viewpagerindicator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.test.viewpagerindicator.ViewpagerIndicator
android:id="@+id/id_indictor"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#888"
gaao:visible_tab_count="4"
android:orientation="horizontal">
</com.test.viewpagerindicator.ViewpagerIndicator>
<android.support.v4.view.ViewPager
android:id="@+id/id_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</android.support.v4.view.ViewPager>
</LinearLayout>
布局文件 activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gaao="http://schemas.android.com/apk/res-atuo/com.test.viewpagerindicator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.test.viewpagerindicator.ViewpagerIndicator
android:id="@+id/id_indictor"
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#888"
gaao:visible_tab_count="4"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="短信11"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="收藏22"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="推荐33"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="短信44"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="收藏55"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="推荐66"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="短信77"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="收藏88"
android:textColor="#ccffffff"
android:textSize="18sp"/>
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="推荐99"
android:textColor="#ccffffff"
android:textSize="18sp"/>
</com.test.viewpagerindicator.ViewpagerIndicator>
<android.support.v4.view.ViewPager
android:id="@+id/id_viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
>
</android.support.v4.view.ViewPager>
</LinearLayout>
自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="visible_tab_count" format="integer"/>
<declare-styleable name="ViewpagerIndicator">
<attr name="visible_tab_count"/>
</declare-styleable>
</resources>