用到的知识:
1.ViewPager和Fragment的结合;
2.自定义view;
3.绘图。
package com.xspacing.indicator;
import java.util.ArrayList;
import java.util.List;
import com.xspacing.view.CustomIndicator;
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.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class MainActivity extends FragmentActivity implements OnPageChangeListener, OnClickListener {
private ViewPager mViewPager;
private List<Fragment> mDatas;
private CustomIndicator mCustomIndicator;
private TextView main_tv1;
private TextView main_tv2;
private TextView main_tv3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
initDatas();
}
private void initDatas() {
mDatas = new ArrayList<Fragment>();
mDatas.add(new Fragment1());
mDatas.add(new Fragment2());
mDatas.add(new Fragment3());
mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Fragment getItem(int position) {
return mDatas.get(position);
}
});
mViewPager.setCurrentItem(0);
mViewPager.addOnPageChangeListener(this);
}
private void initViews() {
mViewPager = (ViewPager) findViewById(R.id.main_view_pager);
mCustomIndicator = (CustomIndicator) findViewById(R.id.main_custom_nav);
main_tv1 = (TextView) findViewById(R.id.main_tv1);
main_tv2 = (TextView) findViewById(R.id.main_tv2);
main_tv3 = (TextView) findViewById(R.id.main_tv3);
main_tv1.setOnClickListener(this);
main_tv2.setOnClickListener(this);
main_tv3.setOnClickListener(this);
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
@Override
public void onPageScrolled(int position, float offX, int arg2) {
mCustomIndicator.getViewNewInstance().drawArguments(position, offX);
}
@Override
public void onPageSelected(int arg0) {
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.main_tv1:
mViewPager.setCurrentItem(0);
break;
case R.id.main_tv2:
mViewPager.setCurrentItem(1);
break;
case R.id.main_tv3:
mViewPager.setCurrentItem(2);
break;
default:
break;
}
}
}
package com.xspacing.view;
import com.xspacing.indicator.R;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
/**
*
* @ClassName CustomIndicator.java
* @Description TODO 自定义viewpager指示器
* @author smile
* @version v1.0
* @date 2016年9月29日
*/
public class CustomIndicator extends LinearLayout {
private static final String TAG = "CustomIndicator";
private int mOffsetX;// 指示器偏移值
private int mHeight; // 指示器的高度
private MyView mView; // 指示器 view
private int mScreenW; // 每个tab占据的屏幕宽度
private int mTab_number; // tab的数量
private int mColor; // 指示器的颜色
private int mWidth; // 指示器的宽度
public CustomIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initCustomIndicator(context, attrs);
}
public CustomIndicator(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomIndicator(Context context) {
this(context, null);
}
private void initCustomIndicator(Context context, AttributeSet attrs) {
// 获取xml配置的参数
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomIndicator);
mWidth = (int) ta.getDimension(R.styleable.CustomIndicator_tab_width, 150);
mTab_number = ta.getInt(R.styleable.CustomIndicator_tab_number, 3);
mColor = ta.getColor(R.styleable.CustomIndicator_tab_color, 0x44ff0000);
ta.recycle();
mView = new MyView(getContext());
this.addView(mView);
}
public MyView getViewNewInstance() {
if (mView == null) {
mView = new MyView(getContext());
}
return mView;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mScreenW = w / mTab_number;// 每个tab所占的屏幕
mOffsetX = (mScreenW - mWidth) / 2;// 指示器的偏移值
mHeight = h;
super.onSizeChanged(w, h, oldw, oldh);
}
public class MyView extends View {
private Paint mPaint;
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initMyView();
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context) {
this(context, null);
}
private void initMyView() {
mPaint = new Paint();
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(mColor);
// 画矩形
Rect rect = new Rect(mOffsetX, 0, mOffsetX + mWidth, mHeight);
canvas.drawRect(rect, mPaint);
}
// viewpager滑动不断调用的方法
public void drawArguments(int position, float offX) {
// 偏移值+滑动的值+tab的位置
mOffsetX = (mScreenW - mWidth) / 2 + (int) (offX * mScreenW) + position * mScreenW;
invalidate();// 重绘
}
}
}
package com.xspacing.indicator;
import com.xspacing.indicator.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
*
* @ClassName Fragment1.java
* @Description TODO 页卡1
* @author Smile
* @version v1.0
* @date 2016年9月26日 下午8:07:09
*/
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_tv);
textView.setText("页卡1");
return view;
}
}
package com.xspacing.indicator;
import com.xspacing.indicator.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
*
* @ClassName Fragment1.java
* @Description TODO 页卡2
* @author Smile
* @version v1.0
* @date 2016年9月26日 下午8:07:09
*/
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_tv);
textView.setText("页卡2");
return view;
}
}
package com.xspacing.indicator;
import com.xspacing.indicator.R;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
*
* @ClassName Fragment1.java
* @Description TODO 页卡3
* @author Smile
* @version v1.0
* @date 2016年9月26日 下午8:07:09
*/
public class Fragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_layout, container, false);
TextView textView = (TextView) view.findViewById(R.id.fragment_tv);
textView.setText("页卡3");
return view;
}
}
attrs文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomIndicator">
<attr name="tab_number" format="integer"></attr>
<attr name="tab_width" format="dimension"></attr>
<attr name="tab_color" format="color"></attr>
</declare-styleable>
</resources>
fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/fragment_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xspacing.indicator.MainActivity" >
<LinearLayout
android:background="#44aaa000"
android:id="@+id/main_linear_nav"
android:layout_width="match_parent"
android:layout_height="40dp"
android:paddingTop="10dp"
android:paddingBottom="10dp" >
<TextView
android:id="@+id/main_tv1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="页卡1" />
<TextView
android:id="@+id/main_tv2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="页卡2" />
<TextView
android:id="@+id/main_tv3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="页卡3" />
</LinearLayout>
<com.xspacing.view.CustomIndicator
android:layout_below="@id/main_linear_nav"
android:id="@+id/main_custom_nav"
android:layout_width="match_parent"
android:layout_height="3dp"
app:tab_number="3"
app:tab_width="80dp"
app:tab_color="#44ff0000">
</com.xspacing.view.CustomIndicator>
<android.support.v4.view.ViewPager
android:id="@+id/main_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/main_custom_nav" >
</android.support.v4.view.ViewPager>
</RelativeLayout>
指示器的形状可根据需求修改