首页 > 代码库 > Tab 滑动标签,综合ViewPager+Fragment+自定义Tab+ActionBar内容

Tab 滑动标签,综合ViewPager+Fragment+自定义Tab+ActionBar内容

1、效果图

第二个菜单TAB1,TAB2,TAB3是参照网上的例子,第一个菜单是在它的基础之上改变而来。

技术分享

2、菜单

这里的菜单是通过两种方式来实现,一种是通过布局文件,一种是通过自定义组件LinearLayout。自定义只需要传入菜单的名字即可,切换时需要监听事件。下面是一个viewpager+fragment实现,在滑动时改变tab的选中项。

自定义tab底部线是采用TranslateAnimation动画来实现滚动,布局文件采用viewpager的方法onPageScrolled和onPageScrollStateChanged来实现。

2.1 自定义LinearLayout

<span style="font-size:14px;">package com.example.actionbar;


import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TabView extends LinearLayout {

    private int screenWidth;
    private String[] tabNames;
    private int fontSize;
    private TextView[] mTextViews;

    private int lineHight;
    private View sliderLine;
    private int tabWidth;
    private int selectedPage;

    public TabView(Context context) {
        super(context);
        init(context);
    }

    public TabView(Context context, String[] tabNames, DisplayMetrics displayMetrics, int fontSize) {
        super(context);
        this.tabNames = tabNames;
        screenWidth = displayMetrics.widthPixels;
        this.fontSize = fontSize;

        init(context);
    }

    public TabView(Context context, List<String> names, DisplayMetrics displayMetrics, int fontSize) {
        super(context);
        if (names != null) {
            tabNames = new String[names.size()];
            for (int i = 0; i < tabNames.length; i++) {
                this.tabNames[i] = names.get(i);
            }
        }
        screenWidth = displayMetrics.widthPixels;
        this.fontSize = fontSize;
        init(context);
    }

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

    @SuppressLint("NewApi")
    public TabView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        if (tabNames==null || tabNames.length == 0) {
            return;
        }
        lineHight = (int) getResources().getDimension(R.dimen.cursor_height);
        tabWidth = screenWidth / tabNames.length;
        mTextViews = new TextView[tabNames.length];
        setOrientation(LinearLayout.VERTICAL);


        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                new LayoutParams(screenWidth / tabNames.length,
                        LayoutParams.MATCH_PARENT));
        LinearLayout linearLayout = new LinearLayout(context);
        int height = (int) getResources().getDimension(R.dimen.tab_height);
        linearLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,height));
        linearLayout.setOrientation(LinearLayout.HORIZONTAL);
        for (int i = 0; i < tabNames.length; i++) {
            TextView textView = new TextView(context);
            textView.setText(tabNames[i] + "");
            textView.setLayoutParams(layoutParams);
            textView.setTextSize(fontSize);
            textView.setTextColor(Color.BLACK);
            textView.setGravity(Gravity.CENTER);
            mTextViews[i] = textView;
            final int pos = i;
            textView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(selectedPage!=pos){
                    	isHidden(pos);
                    }
                    if (tabViewListener != null) {
                        tabViewListener.currentPos(pos);
                    }
                }
            });
            linearLayout.addView(textView);
        }
        addView(linearLayout);
        if (tabNames.length>1) {
        	LinearLayout.LayoutParams lineLayoutParams = new LinearLayout.LayoutParams(tabWidth, lineHight);
        	TextView textView = new TextView(context);
        	textView.setBackgroundColor(Color.parseColor("#FA8653"));
        	textView.setLayoutParams(lineLayoutParams);
        	sliderLine=textView;
        	addView(textView); 
		}
        isHidden(0);
    }
 

    private TabViewListener tabViewListener;

    public void setTabViewListener(TabViewListener linListener) {
        this.tabViewListener = linListener;
    }
    public TabViewListener getTabViewListener(){
    	return tabViewListener;
    }
    public interface TabViewListener {
        public void currentPos(int pos);
    }

    /*
     * 切换字体颜色
     */
    public void isHidden(int pos) {
        if (pos >= 0 || pos < tabNames.length) {
        	tabScroll(pos);
            mTextViews[selectedPage].setTextColor(Color.BLACK);
            mTextViews[pos].setTextColor(Color.parseColor("#FA8653"));
            selectedPage=pos;
        }
    }
    
    /*
     * 滚动动画
     */
    private void tabScroll(int index){
    	if (selectedPage==index) {
			return;
		}
    	sliderLine.setTranslationX(0);
		TranslateAnimation animation = new TranslateAnimation(selectedPage
				* tabWidth, index * tabWidth, 0, 0);
		animation.setInterpolator(new AccelerateInterpolator());
		animation.setDuration(100);
		animation.setFillEnabled(true);
		animation.setFillAfter(true);
		sliderLine.startAnimation(animation);
		animation.setAnimationListener(new AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
				 
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				sliderLine.clearAnimation();
				sliderLine.setTranslationX(selectedPage * tabWidth);
			}
		});

    }
}
</span>

2.2 使用布局文件

<span style="font-size:14px;">package com.example.actionbar;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
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 android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TabFragmentIndicator extends LinearLayout implements
		ViewPager.OnPageChangeListener, OnClickListener {

	OnTabClickListener onTabClickListener;
	Context mContext;
	ViewPager mViewPager;
	View container;
	private View slider;
	private int tabNum;
	private int selectedPage = 0;
	private int preSelectedPage = 0;
	private int scrollState;
	private final int SCROLL_STATE_PRESS = 1;
	private final int SCROLL_STATE_UP = 2;
	private float unitWidth;
	private float currentPositionPix;
	private boolean isClick = false;
	SectionsPagerAdapter mSectionsPagerAdapter;
	private ArrayList<Class<?>> fragmentList = new ArrayList<Class<?>>();

	public TabFragmentIndicator(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
	}

	public void setViewPager(ViewPager viewPager) {
		viewPager.setOffscreenPageLimit(3);
		mViewPager = viewPager;
		mViewPager.setOnPageChangeListener(this);
		mSectionsPagerAdapter = new SectionsPagerAdapter(
				((FragmentActivity) mContext).getSupportFragmentManager());
		mViewPager.setAdapter(mSectionsPagerAdapter);
	}

	/**
	 * 添加fragment
	 * 
	 * @param index
	 * @param claz
	 */
	public void addFragment(int index, Class<?> claz) {
		fragmentList.add(index, claz);
		if (mSectionsPagerAdapter != null)
			mSectionsPagerAdapter.notifyDataSetChanged();
	}

	/**
	 * 设置Tab布局
	 * 
	 * @param layoutId
	 */
	public void setTabContainerView(int layoutId) {

		container = LayoutInflater.from(mContext).inflate(layoutId, null);
		this.addView(container, 0);

		int height = (int) getResources().getDimension(R.dimen.tab_height);
		ViewGroup.LayoutParams params = container.getLayoutParams();
		params.height = height;
		container.setLayoutParams(params);

		if (container instanceof ViewGroup) {
			tabNum = ((ViewGroup) container).getChildCount();
			for (int i = 0; i < tabNum; i++) {
				((ViewGroup) container).getChildAt(i).setTag(i);
				((ViewGroup) container).getChildAt(i).setOnClickListener(this);
			}
		}

	}

	/**
	 * 设置下划线
	 * 
	 * @param layoutId
	 */
	public void setTabSliderView(int layoutId) {
		slider = LayoutInflater.from(mContext).inflate(layoutId, null);
		this.addView(slider, 1);
		setCursorWidth();
	}

	public View getIndicatorView() {
		return container;
	}

	public class SectionsPagerAdapter extends FragmentPagerAdapter {

		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		@Override
		public Fragment getItem(int index) {
			return Fragment.instantiate(mContext, fragmentList.get(index)
					.getName(), null);
		}

		@Override
		public int getCount() {
			return fragmentList.size();
		}
	}

	@Override
	public void onPageSelected(int position) {

		((TextView) ((ViewGroup) container).getChildAt(selectedPage))
				.setTextColor(this.getResources().getColor(
						android.R.color.black));
		((TextView) ((ViewGroup) container).getChildAt(position))
				.setTextColor(this.getResources().getColor(R.color.orange));

		selectedPage = position;
	}

	@Override
	public void onPageScrolled(int position, float positionOffset,
			int positionOffsetPixels) {
		//不是点击tab选项
		if (!isClick && positionOffsetPixels != 0) {
			if (scrollState == SCROLL_STATE_PRESS) {// 手指按下的状态
				if (selectedPage == position) {// 表示往左拉,相应的tab往右走
					slider.setTranslationX(currentPositionPix
							+ positionOffsetPixels / tabNum);
				} else {// 表示往右拉
					slider.setTranslationX(currentPositionPix
							- (unitWidth - positionOffsetPixels / tabNum));
				}
			} else if (scrollState == SCROLL_STATE_UP) {// 手指抬起的状态
			 System.out.println("preSelectedPage---" + preSelectedPage +" position---" + position+" offset "+positionOffsetPixels);
				if (preSelectedPage == position) {// 往左拉
					slider.setTranslationX(currentPositionPix + positionOffsetPixels / tabNum);
				} else {// 表示往右拉
					slider.setTranslationX(currentPositionPix - (unitWidth - positionOffsetPixels / tabNum));
				}
			}
		}
	}

	// 其中state这个参数有三种状态(0,1,2)。state
	// ==1的时辰默示正在滑动,state==2的时辰默示滑动完毕了,state==0的时辰默示什么都没做。
	@Override
	public void onPageScrollStateChanged(int state) {
		System.out.println("onPageScrollStateChanged------state" + state);
		if (!isClick) {
			currentPositionPix = selectedPage * unitWidth;
			scrollState = state;
			preSelectedPage = selectedPage;
		}
	}

	
	/**
	 * 
	 * 点击tab页时移动下划线
	 */
	@Override
	public void onClick(View v) {
		final int index = (Integer) v.getTag();
		onTabClickListener.onTabClick(v);
		if (selectedPage == index) {
			return;
		}
		isClick = true;
		slider.setTranslationX(0);
		TranslateAnimation animation = new TranslateAnimation(selectedPage
				* unitWidth, index * unitWidth, 0, 0);
		animation.setInterpolator(new AccelerateInterpolator());
		animation.setDuration(100);
		animation.setFillEnabled(true);
		animation.setFillAfter(true);
		slider.startAnimation(animation);

		animation.setAnimationListener(new AnimationListener() {

			@Override
			public void onAnimationStart(Animation animation) {
				mViewPager.setCurrentItem(index, true);
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				slider.clearAnimation();
				slider.setTranslationX(selectedPage * unitWidth);
				isClick = false;
			}
		});

	}

	/** 设置cursor的宽度,并获取移动的单位长度float **/
	private void setCursorWidth() {
		int cursorWidth = getWindowWidth() / tabNum;
		unitWidth = (float) getWindowWidth() / tabNum;
		int cursorHeight = (int) getResources().getDimension(
				R.dimen.cursor_height);

		ViewGroup.LayoutParams params = slider.getLayoutParams();
		params.height = cursorHeight;
		params.width = cursorWidth;

		slider.setLayoutParams(params);
	}

	/** 获取屏幕宽度 **/
	private int getWindowWidth() {
		DisplayMetrics dm = new DisplayMetrics();
		((Activity) mContext).getWindowManager().getDefaultDisplay()
				.getMetrics(dm);
		return dm.widthPixels;
	}

	public void setOnTabClickListener(OnTabClickListener onTabClickListener) {
		this.onTabClickListener = onTabClickListener;
	}

	public interface OnTabClickListener {
		public void onTabClick(View v);
	}
}
</span>

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tab1_text"
        android:layout_width="0dp"
        android:layout_weight="1.0"
        android:gravity="center"
        android:layout_height="@dimen/tab_height"
        android:textColor="@color/orange"
        style="@style/Style.ActionBarTabTextStyle"
        android:text="tab1" />

    <TextView
        android:id="@+id/tab2_text"
        android:layout_width="0dp"
        android:layout_height="@dimen/tab_height"
        android:layout_weight="1.0"
        android:gravity="center"
        style="@style/Style.ActionBarTabTextStyle"
        android:text="tab2" />

    <TextView
        android:id="@+id/tab3_text"
        android:layout_width="0dp"
        android:layout_height="@dimen/tab_height"
        android:layout_weight="1.0"
        android:gravity="center"
        style="@style/Style.ActionBarTabTextStyle"
        android:text="tab3" />

</LinearLayout></span>

3、测试调用

<span style="font-family: 'Comic Sans MS';"><span style="font-size:14px;">public class HomeActivity extends FragmentActivity implements
		OnTabClickListener, OnCategorySelectedListener {
	private ViewPager mViewPager;
	private TabFragmentIndicator tabFragmentIndicator;
	private View categoryTab;
	private CategoryWindow categoryWindow;
	private SettingMenuWindow menuWindow;
	private LinearLayout ll_tab;
	private TabView tabView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_home);
		menuWindow = new SettingMenuWindow(this);
		mViewPager = (ViewPager) findViewById(R.id.viewPager);
		ll_tab = (LinearLayout) findViewById(R.id.ll_tab);
		tabFragmentIndicator = (TabFragmentIndicator) findViewById(R.id.tabFragmentIndicator);
		tabFragmentIndicator.addFragment(0, CountingFragment.class);
		tabFragmentIndicator.addFragment(1, CountingFragment.class);
		tabFragmentIndicator.addFragment(2, CountingFragment.class);
		tabFragmentIndicator
				.setTabContainerView(R.layout.layout_home_tabindicator);
		tabFragmentIndicator.setTabSliderView(R.layout.layout_home_tab_slider);
		tabFragmentIndicator.setOnTabClickListener(this);
		tabFragmentIndicator.setViewPager(mViewPager);
		categoryWindow = new CategoryWindow(this, this);

		DisplayMetrics dm = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(dm);
		tabView = new TabView(this, new String[] { "菜单", "发现", "设置" },
				dm, 20);
		ll_tab.addView(tabView);

		tabView.setTabViewListener(new TabViewListener() {
			@Override
			public void currentPos(int pos) {
				 tabView.isHidden(pos);
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		case R.id.menu_more:

			menuWindow.showAsDropDown(findViewById(R.id.anchorView), 1800, -25);
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void onTabClick(View v) {
		int pos = (Integer) v.getTag();
		if (pos == 0) {
			categoryWindow.showAsDropDown(tabFragmentIndicator, -20, 0);
		}
		tabView.getTabViewListener().currentPos(pos);
	}

	@Override
	public void onCategorySelected(String name, String id) {
		((TextView) categoryTab).setText(name);
		categoryWindow.dismiss();
	}

}</span></span>

源码下载


Tab 滑动标签,综合ViewPager+Fragment+自定义Tab+ActionBar内容