admin管理员组

文章数量:1550528

运行效果

在编写代码之前,先看看最终运行效果:


代码编写

首先自定义一个控件,名叫ViewPagerIndicate,继承HorizontalScrollView,实现View.OnClickListener接口监听,代码如下:
package com.example.viewpagerindicate.view;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class ViewPagerIndicate extends HorizontalScrollView implements OnClickListener {
	
	private Context mContext;
	private LayoutInflater mInflater;
	private ViewPager mViewPager;
	//onMeasure是否准备完成
	private boolean isMeasureOk;
	//是否可以绘制下划线
	private boolean isDrawOK;
	//HorizontalScrollView只能有1个子View(这里用线性布局)
	private LinearLayout mWapper;
	//标签
	private ArrayList<TextView> mTextViews;
	//标签正常颜色和高亮颜色
	private int mTextNormalColor, mTextHighlightColor;
	//总宽度
	private int mTotalWidth;
	//1个标签的宽和高
	private int mTabWidth, mTabHeight;  
	private Paint mPaint;
	//下划线的位置
	private float mTranslateX;
	
	public ViewPagerIndicate(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		mInflater = LayoutInflater.from(context);
		mPaint = new Paint();
		isMeasureOk = isDrawOK = false;
	}
	
	/**
	 * 重置下划线的粗细和颜色
	 * @param size 下划线粗细
	 * @param color 下划线颜色
	 */
	public void resetUnderline(int size, int color) {
		mPaint.setStrokeWidth((int) TypedValue.applyDimension(
				TypedValue.COMPLEX_UNIT_DIP, size, mContext.getResources().getDisplayMetrics()));
		mPaint.setColor(color);
	}
	
	/**
	 * 重置标签的布局样式、标题和颜色
	 * @param tabId 布局样式id
	 * @param titles 标题集合
	 * @param colors 颜色集合
	 */
	public void resetText(int tabId, String[] titles, int[] colors) {
		mTextNormalColor = colors[0];
		mTextHighlightColor = colors[1];
		mTextViews = new ArrayList<TextView>();
		for (int i = 0; i < titles.length; i++) {
			TextView tv = (TextView) mInflater.inflate(tabId, null);
			tv.setText(titles[i]);
			tv.setTag(i);
			tv.setOnClickListener(this);
			mTextViews.add(tv);
		}
		setTextHighlight(0);
	}
	
	/**
	 * 高亮对应位置的标签颜色
	 * @param pos 对应位置
	 */
	private void setTextHighlight(int pos) {
		for (int i = 0; i < mTextViews.size(); i++) {
			if (i == pos)
				mTextViews.get(pos).setTextColor(mTextHighlightColor);
			else
				mTextViews.get(i).setTextColor(mTextNormalColor);
		}
	}
	
	/**
	 * 之所以设置此方法,主要是用于网络获取数据,而不是使用静态文本;
	 * 当网络请求成功,手动调用该方法完成初始化
	 */
	public void setOk() {
		isMeasureOk = true;
		isDrawOK = true;
		requestLayout();
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		//必须放在super.onMeasure的前面,否则后面无法获得子View的宽高
		if (isMeasureOk) {
			removeAllViews();
			mWapper = new LinearLayout(mContext);
			for (TextView tv : mTextViews) {
				mWapper.addView(tv);
			}
			addView(mWapper);
		}
		
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		
		if (isMeasureOk) {
			if (mTextViews.size() > 0) {
				mTotalWidth = getMeasuredWidth();
				TextView tv = (TextView) mWapper.getChildAt(0);
				mTabWidth = tv.getMeasuredWidth();
				mTabHeight = tv.getMeasuredHeight();
			}
			isMeasureOk = false;
		}
	}
	
	/**
	 * 设置下划线的位置
	 * @param pos ViewPager对应的索引位置
	 * @param posOffset ViewPager滑动百分比
	 */
	private void drawUnderline(int pos, float posOffset) {
		mTranslateX = pos * mTabWidth + posOffset * mTabWidth;
		invalidate();
	}
	
	/**
	 * 设置下划线的位置
	 * @param pos ViewPager对应的索引位置
	 */
	private void drawUnderline(int pos) {
		mTranslateX = pos * mTabWidth;
		invalidate();
	}
	
	@Override
	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		if (isDrawOK) {
			//改变下划线的位置
			canvas.translate(mTranslateX, 0);
			//绘制下划线
			canvas.drawLine(0, mTabHeight, mTabWidth, mTabHeight, mPaint);
		}
	}
	
	/**
	 * 重置ViewPager
	 */
	public void resetViewPager(ViewPager viewPager) {
		mViewPager = viewPager;
		mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
			/*ViewPager某项被选中*/
			@Override
			public void onPageSelected(int position) {
				//高亮该项文字
				setTextHighlight(position);
			}
			
			/*ViewPager从某项滑动到另一项*/
			@Override
			public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
				drawUnderline(position, positionOffset);
				//实现标签与下划线一起滚动的效果
				scrollTo((int) ((position + positionOffset - 1) * mTabWidth), 0);
			}
			
			@Override
			public void onPageScrollStateChanged(int arg0) {}
		});
	}
	
	/**
	 * 标签点击事件监听
	 */
	@Override
	public void onClick(View v) {
		int pos = (Integer) v.getTag();
		//让当前标签总是显示在第二个位置
		smoothScrollTo((pos - 1) * mTabWidth, 0);
		drawUnderline(pos);
		mViewPager.setCurrentItem(pos, false);
	}
}
MainActivity代码如下:
package com.example.viewpagerindicate;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.viewpagerindicate.view.ViewPagerIndicate;

public class MainActivity extends Activity {
	private ViewPager mViewPager;
	private ViewPagerIndicate mIndicate;
	private int[] mTextColors = {0xFFA0A0A0, 0xFF000000};
	private int mUnderlineColor = 0xFF168EFF;
	private String[] mTitles = new String[] {
			"要闻", "奥运", "视频", "娱乐", "体育", "NBA",
			"财经", "汽车", "科技", "社会", "军事", "国际",
			"时尚", "文化", "游戏", "图片", "数码", "星座",
			"电影", "教育", "美容", "动漫", "理财", "民生"};
	private ArrayList<TextView> mTextViews;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initViewPgaer();
		initViewPagerIndicate();
	}
	
	private void initViewPgaer() {
		mTextViews = new ArrayList<TextView>();
		for (int i = 0; i < mTitles.length; i++) {
			TextView tv = new TextView(this);
			tv.setGravity(Gravity.CENTER);
			tv.setText(mTitles[i]);
			mTextViews.add(tv);
		}
		mViewPager = (ViewPager) findViewById(R.id.viewPager);
		mViewPager.setAdapter(new PagerAdapter() {
			@Override
			public Object instantiateItem(ViewGroup container, int position) {
				TextView tv = mTextViews.get(position);
				container.addView(tv);
				return tv;
			}
			
			@Override
			public void destroyItem(ViewGroup container, int position,
					Object object) {
				container.removeView(mTextViews.get(position));
			}
			
			@Override
			public boolean isViewFromObject(View arg0, Object arg1) {
				return arg0 == arg1;
			}
			
			@Override
			public int getCount() {
				return mTextViews.size();
			}
		});
	}
	
	private void initViewPagerIndicate() {
		mIndicate = (ViewPagerIndicate) findViewById(R.id.indicate);
		//设置标签样式、文本和颜色
		mIndicate.resetText(R.layout.layout_text_indicate, mTitles, mTextColors);
		//设置下划线粗细和颜色
		mIndicate.resetUnderline(4, mUnderlineColor);
		//设置ViewPager
		mIndicate.resetViewPager(mViewPager);
		//设置初始化完成
		mIndicate.setOk();
	}
}

编写布局

activity_main.xml代码如下:
<LinearLayout xmlns:android="http://schemas.android/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFF"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFF"
        android:paddingLeft="10dp"
        android:paddingRight="10dp" >

        <com.example.viewpagerindicate.view.ViewPagerIndicate
            android:id="@+id/indicate"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="none" >
        </com.example.viewpagerindicate.view.ViewPagerIndicate>
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginTop="2dp"
        android:background="#D5D5D5" />

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

</LinearLayout>
layout_text_indicate.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingBottom="10dp"
    android:paddingTop="15dp"
    android:textSize="16sp" >

</TextView>


本文标签: 史上网易新闻客户端效果ViewPagerIndicate