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>

源码下载

时间: 2024-10-10 04:58:45

Tab 滑动标签,综合ViewPager+Fragment+自定义Tab+ActionBar内容的相关文章

Android两种为ViewPager+Fragment添加Tab的方式

在Android开发中ViewPager的使用是非常广泛的,而它不仅仅能够实现简单的开始引导页,还可以结合Fragment并添加Tab作为选项卡或为显示大批量页面实现强大的顺畅滑动 下面介绍两种为ViewPager+Fragment添加Tab的方式: 第一种: 在MainActivity布局中定义一个ViewPager 在MainActivity中声明ViewPager并实现它的Adapter继承自FragmentPagerAdapter 首先需要通过重写有参的构造方法来获取FragmentMa

【Android界面实现】使用ScrollingTabsView实现有滑动标签的ViewPager效果

转载自:http://blog.csdn.net/zhaokaiqiang1992/article/details/40378285 在前面的文章中,我们使用支持包里面的PagerTabStrip实现了有滑动标签的viewPager效果,今天,再给大家介绍另外一种开源项目,来实现类似的效果. 在这篇文章中,我们将使用第三方开源项目ViewPagerExtensions实现. 先看效果 ViewPagerExtensions的github地址:https://github.com/astuetz/

ViewPager+Fragment实现Tab主界面

毕竟是第一次做项目,所以在每一点上都做得特别认真,接下来我来给大家大致讲述一下用ViewPager+Fragment来实现app Tab主界面,突然想起来LZ居然2天没去上课了......(>....<) 没办法,为了暑假的实习offer,只好拼了!!! package com.bob.tabui; import android.support.v4.app.*; import android.os.Bundle; import android.support.v4.view.ViewPage

【Android界面实现】使用PagerTabStrip实现有滑动标签的Viewpager

在ViewPager这样的能够滑动的控件上,总是有非常多的文章能够做.上次的文章,我们实现了一个自己定义的ViewPager的指示器,这篇文章,我们主要是想利用Android自带的控件,实现一个指示器,这个控件,就是support-v4包里面的PagerTabStrip控件. 首先,我们先看一下实现效果,大饱眼福. 能够看到,效果实现的也是非常棒,比之前自己定义的标签指示器更加的流畅.以下,简介一下PagerTabStrip和它的使用. PagerTabStrip是v4支持包里面的类,是View

viewPager+Fragment实现左右划屏

最近接触左右划屏,从网上搜了一些资料,学习了一下,觉得不错,总结一下. 效果图如下,可以实现左右划屏 先说一下思路: 1.创建一个.java文件,继承Fragment 2.创建onCreateView()方法 3.将主页面的布局放在onCreateView中 View view = inflater.inflate(R.layout.fragment_userinfo, null); return view; 4.初始化TextView,并且监听 textView1 = (TextView) v

Android ViewPager+Fragment滑动选项卡,tab点击选项卡

有一段时间一直再研究这个,自Android 3.0以后,很少开发者再用以前的TabWidget控件了.那种效果不是很好,也不能滑动.后来陆续出现了各种各样滑动选项卡,每种的出现都各有优势吧.但我还是推荐ViewPager+Fragment滑动选项卡,tab点击选项卡.因为横屏或者竖屏效果都还不错,针对这种效果,还有一种开源框架的出现.接下来会有所介绍. 转载请注明出处:http://blog.csdn.net/qq_16064871 本文demo下载:请点击 一.ViewPagerActivit

TabLayout+Fragment+ViewPager+FragmentStatePagerAdapter实现Tab标签

首先来看下实现的效果吧: 最近在项目中实现这个效果的时候.尽管自己磕磕绊绊的实现了,可是知识确实模模糊糊的,今天天气异常的冷,在加上这个知识不太熟练,实在是没有心情进行接下来的计划,干脆借着这个时间,好好的整理一下这个实现方式.也在次总结一下,记忆更加深刻. TabLayout简单介绍 在2015年的Google I/O大会上,Google公布的新的Android Support Design库,里面也包括了几个新的控件,那么TabLayout就是当中一个.使用该组件我们能够非常轻松的实现Tab

首页-底部Tab导航(菜单栏)的实现:FragmentTabHost+ViewPager+Fragment

前言 Android开发中使用底部菜单栏的频次非常高,主要的实现手段有以下: - TabWidget - 隐藏TabWidget,使用RadioGroup和RadioButton - FragmentTabHost - 5.0以后的TabLayout - 最近推出的 Bottom navigation 今天带大家来探索下如何用Fragment+FragmentTabHost++ViewPager 实现底部菜单栏 目录 总体设计思路 Fragment:存放不同选项的页面内容 FragmentTab

android开发步步为营之53:viewpager+fragment构造可左右滑动标签页效果

可滑动的标签页是很多应用的用来做外面框架的,比如微信,微博等等,我这里实现的效果是下面是主标签页,然后中间一个的标签页里面又可以继续左右滑动,等于是标签页内部再嵌套标签页,用到的组件主要有:用于滑动效果的viewpager,以及用于实现每个tab页功能的fragment,先看看效果图:  第一步:设计页面activity_learn_fragment.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/