我们在android 手机上看到了有一种效果,就是上面是tab 导航栏。下面就是一个fragment,当我们进行滑动下面的fragment 的时候,上面的标题就跟着一起移动。这个是看慕课一个大神写的。
综述
上面的这个效果其实就是上面是一个自定义的LinearLayout 下面是一个ViewPage.通过自定义的东西来实现我们想要的东西。
main.xml 的编辑
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.example.view.ViewPageIndicator
android:id="@+id/myIndicator"
android:layout_height="45dp"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="#000"
>
</com.example.view.ViewPageIndicator>
<android.support.v4.view.ViewPager
android:id="@+id/myViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
</LinearLayout>
就是我们说的是上面有一个自定义的 LinearLayout ,里面可以不先进行添加,之后我们可以进行动态的进行添加。
Activity的编写
package com.example.testviewpage;
import android.app.Activity;
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.os.Bundle;
import android.view.View;
import com.example.fragment.MyFragment;
import com.example.view.ViewPageIndicator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends FragmentActivity {
//自己定义的view
private ViewPageIndicator viewPageIndicator;
//使用viewPager
private ViewPager myViewPager;
//这个是我们使用的标题
/*
这个Arrays.asList 这个函数,所创建的List的容量就是刚开始创建的数量,不会有多余的控件,节省内存。
*/
private List<String> indicators = Arrays.asList("推荐","新闻","娱乐","体育","NBA");
//这个里面是我们在fragment中进行显示的东西
private List<String> strs = Arrays.asList("test1","test2","test3","test4","test5");
private List<MyFragment> fragemetsList = new ArrayList<>();
private FragmentPagerAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//进行初始化控件和数据
initViews();
//添加适配器
myViewPager.setAdapter(myAdapter);
//将viewPager 放入到自定义的控件中去
viewPageIndicator.setViewPage(myViewPager,0);
}
private void initViews() {
viewPageIndicator = (ViewPageIndicator) findViewById(R.id.myIndicator);
myViewPager = (ViewPager) findViewById(R.id.myViewPager);
for (String s:strs) {
fragemetsList.add(MyFragment.getInstance(s));;
}
viewPageIndicator.setTableItem(indicators);
//设置适配器
myAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
@Override
public Fragment getItem(int position) {
return fragemetsList.get(position);
}
@Override
public int getCount() {
return fragemetsList.size();
}
};
}
}
自定义控件
package com.example.view;
import android.content.Context;
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.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
public class ViewPageIndicator extends LinearLayout {
//轨迹
private Path path;
//画笔
private Paint mPaint;
//我们要进行绘制的长方形初始的位置
private int initX;
//我们进行偏移的位置
private int changeX;
//长方形的宽
private int mTriangleWidth;
//比例
private float bili = 4/5f;
//一个屏幕上 进行显示多少个
private final int COUNT = 3;
//标题
private List<String> mTitle;
public ViewPageIndicator(Context context) {
super(context,null);
}
public ViewPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
//初始化画笔
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.parseColor("#00ff00"));
mPaint.setStyle(Paint.Style.FILL);
mPaint.setPathEffect(new CornerPathEffect(3));
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
canvas.translate(initX+changeX,getHeight() -2);
canvas.drawPath(path,mPaint);
canvas.restore();
super.dispatchDraw(canvas);
}
/**
* 这个里面进行初始化我们的长宽的比例
* 只要是大小发生变化的时候就会进行调用这个函数
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//计算宽
mTriangleWidth = (int) (w /COUNT * bili);
//计算初始话的高度
initX = ((w/COUNT)>>1)- (mTriangleWidth>>1);
initTriangle();
}
//初始化长方形
//这个是画长方形 可以是其他的形体
private void initTriangle() {
int mTriangleHeight = mTriangleWidth / 10;
path = new Path();
path.moveTo(0,0);
path.lineTo(mTriangleWidth,0);
path.lineTo(mTriangleWidth,-mTriangleHeight);
path.lineTo(0,-mTriangleHeight);
path.close();
}
//进行移动
public void scroll(int position, float positionOffset) {
int tabWidth= getWidth() / COUNT;
changeX = (int) (tabWidth * positionOffset);
initX = position * tabWidth + (tabWidth - mTriangleWidth)/2;
if(position >= (COUNT -2) && positionOffset > 0 && getChildCount() >positionOffset){
if(COUNT != 1){
this.scrollTo((position - COUNT +2)*tabWidth + (int)(tabWidth * positionOffset),0);
}else{
this.scrollTo((position*tabWidth + (int)(tabWidth * positionOffset)),0);
}
}
invalidate();
}
/**
* 当xml的布局文件加载 完成的时候
* 调用这个方法
*/
@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.gravity = Gravity.CENTER;
lp.weight = 0;
lp.width = getScreenWidth()/COUNT;
view.setLayoutParams(lp);
}
setItemClickEvent();
}
//获得屏幕大小
private int getScreenWidth() {
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics out = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(out);
return out.widthPixels;
}
//动态设置标题
public void setTableItem(List<String> titles){
if(titles != null && titles.size() >0){
this.removeAllViews();;
this.mTitle = titles;
for(String title : mTitle){
addView(generateTextView(title));
}
}
setItemClickEvent();
}
private static final int COLOR_TEXT_NORMAL = 0x77ffffff;
private static final int COLOR_TEXT_LIGHT = 0xffffffff;
//设置标题的style
private View generateTextView(String title) {
TextView tv = new TextView(getContext());
LinearLayout.LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
System.out.println(getScreenWidth());
lp.width = getScreenWidth() /COUNT;
tv.setText(title);
tv.setGravity(Gravity.CENTER);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP,16);
tv.setTextColor(COLOR_TEXT_NORMAL);
tv.setLayoutParams(lp);
return tv;
}
private ViewPager mViewPage;
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;
}
public void setViewPage(ViewPager viewPage,int position){
mViewPage = viewPage;
mViewPage.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);
}
highLightTextViewColor(position);
}
@Override
public void onPageScrollStateChanged(int state) {
if(mListener != null){
mListener.onPageScrollStateChanged(state);
}
}
});
mViewPage.setCurrentItem(position);
highLightTextViewColor(position);
}
//设置高亮
private void highLightTextViewColor(int pos){
resetTextViewColor();
View view = getChildAt(pos);
if(view instanceof TextView){
((TextView)view).setTextColor(COLOR_TEXT_LIGHT);
}
}
private void resetTextViewColor(){
int count = getChildCount();
for (int i = 0; i < count ;i++){
View view = getChildAt(i);
if(view instanceof TextView){
((TextView)view).setTextColor(COLOR_TEXT_NORMAL);
}
}
}
//设置点击时间
private void setItemClickEvent(){
for (int i = 0 ; i < getChildCount();i++ ){
View v =getChildAt(i);
final int j = i;
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mViewPage.setCurrentItem(j);
}
});
}
}
}