Android ViewPager实现Tabhost选项卡底部滑块动态滑动过渡



《Android ViewPager实现Tabhost选项卡底部滑块动态滑动过渡》

之前基于github上的第三方开源控件ViewPagerIndicator的UnderlinePageIndicator(原文链接:http://blog.csdn.net/zhangphil/article/details/44752213),自己写了一个底部带有滑块、且当ViewPager页面切换时候选项卡也随之相应切换,且滑块也随之相应动态滑动效果得控件。但写的太过于紧耦合,不利于复用,所以现在重构了代码,重写了代码,把这些效果做成了一个自定制的松耦合控件:TabLinearLayout,该控件可以在未来的项目中直接拿出使用。

控件效果图如图所示:

测试用的MainActivity.java:

package zhangphil.view;

import java.util.ArrayList;

import zhangphil.underline.R;

import com.viewpagerindicator.UnderlinePageIndicator;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;

/**
 * 基于第三方开源控件ViewPagerIndicator的UnderlinePageIndicator,自己写的一个在选项卡底部有衬线的滑动控件。
 * 控件效果图如图所示。 这里面有一个特别的效果是:头部的选项卡在ViewPager切换过程中,底部的滑块也随之动态渐渐滑动过渡。
 *
 * */

public class MainActivity extends ActionBarActivity {

	private TabLinearLayout mTabLinearLayout;
	private ArrayList<Fragment> mArryList;
	private ViewPager mPager;

	// 未被选中的选项卡字体颜色
	private int COLOR_NORMAL = Color.DKGRAY;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		mArryList = new ArrayList<Fragment>();
		// 初始化5个Fragment作为测试。
		for (int i = 0; i < 5; i++) {
			TestFragment f = (TestFragment) TestFragment.newInstance();
			f.id = i;
			mArryList.add(f);
		}

		PagerAdapter mAdapter = new MyFragmentAdapter(
				getSupportFragmentManager());

		mPager = (ViewPager) findViewById(R.id.pager);
		mPager.setAdapter(mAdapter);

		UnderlinePageIndicator mIndicator = (UnderlinePageIndicator) findViewById(R.id.indicator);
		mIndicator.setViewPager(mPager);
		mIndicator.setFades(false);
		mIndicator.setSelectedColor(0xff33B5E5);

		mTabLinearLayout = (TabLinearLayout) findViewById(R.id.tab_LinearLayout);

		ArrayAdapter mTabLinearLayoutAdapter = new MyTabLinearLayoutAdapter(
				this, -1);
		mTabLinearLayout.initialization(mPager, mTabLinearLayoutAdapter,
				mIndicator);
	}

	private class MyTabLinearLayoutAdapter extends ArrayAdapter {
		private Context context;

		public MyTabLinearLayoutAdapter(Context context, int resource) {
			super(context, resource);
			this.context = context;
		}

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

		// 在这里仅仅返回一个TextView作为选项卡的View。
		// 此处可以返回更丰富的View。
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			TextView v = new TextView(context);
			v.setGravity(Gravity.CENTER);
			v.setText("选项卡" + position);
			v.setTextColor(COLOR_NORMAL);

			return v;
		}
	}

	// 仅仅用于测试的Fragment,用一个id标识。
	private static class TestFragment extends Fragment {

		public int id;

		public static Fragment newInstance() {
			return new TestFragment();
		}

		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {

			TextView v = new TextView(getActivity());
			v.setGravity(Gravity.CENTER);
			v.setTextSize(50f);
			v.setText("Fragment: " + id);

			return v;
		}
	}

	private class MyFragmentAdapter extends FragmentPagerAdapter {

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

		@Override
		public Fragment getItem(int position) {
			return mArryList.get(position);
		}

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

MainActivity.java需要的activity_main.xml布局文件:

<?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="match_parent"
    android:orientation="vertical" >

    <zhangphil.view.TabLinearLayout
        android:id="@+id/tab_LinearLayout"
        android:layout_width="match_parent"
        android:layout_height="30dip"
        android:orientation="horizontal" />

    <com.viewpagerindicator.UnderlinePageIndicator
        android:id="@+id/indicator"
        android:layout_width="match_parent"
        android:layout_height="7px" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#33B5E5" />

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

</LinearLayout>

自己重写的TabLinearLayout.java:

package zhangphil.view;

import com.viewpagerindicator.PageIndicator;

import android.content.Context;
import android.graphics.Color;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TabLinearLayout extends LinearLayout {

	private int COLOR_NORMAL = Color.DKGRAY;
	private ArrayAdapter mAtapter;
	private ViewPager mPager;
	private TabLinearLayoutListener mTabLinearLayoutListener;

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

	public TabLinearLayout(Context context) {
		super(context);
	}

	public void initialization(ViewPager mPager, ArrayAdapter mAtapter,
			PageIndicator mPageIndicator) {
		this.mAtapter = mAtapter;
		this.mPager = mPager;

		mPageIndicator
				.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

					@Override
					public void onPageSelected(int pos) {
						setCurrentItem(pos);

						if (mTabLinearLayoutListener != null)
							mTabLinearLayoutListener.onTab(pos);
					}

					@Override
					public void onPageScrolled(int arg0, float arg1, int arg2) {

					}

					@Override
					public void onPageScrollStateChanged(int arg0) {

					}
				});

		// 添加选项卡
		addIndicators();

		// 初始化,第0项被选中
		setIndicatorViewSelected(0);
	}

	public void initialization(ViewPager mPager, ArrayAdapter mAtapter,
			PageIndicator mPageIndicator,
			TabLinearLayoutListener mTabLinearLayoutListener) {

		this.mTabLinearLayoutListener = mTabLinearLayoutListener;

		initialization(mPager, mAtapter, mPageIndicator);
	}

	// 添加Tab选项卡
	private void addIndicators() {
		for (int i = 0; i < mAtapter.getCount(); i++) {
			View v = mAtapter.getView(i, null, null);
			addIndicatorItem(v, i);
		}
	}

	// 在这里设置被选中时候选项卡变化的效果
	private void setIndicatorViewSelected(int pos) {
		for (int i = 0; i < super.getChildCount(); i++) {
			if (i == pos) {
				View v = super.getChildAt(i);
				TextView tv = (TextView) v;
				// Android Holo 样式的蓝色
				tv.setTextColor(0xff33B5E5);
			} else {
				View v = super.getChildAt(i);
				TextView tv = (TextView) v;
				tv.setTextColor(COLOR_NORMAL);
			}
		}
	}

	// 在线性布局里面依次添加一个View,为添加的View添加事件。
	private void addIndicatorItem(View view, final int index) {
		LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.MATCH_PARENT, 1);
		super.addView(view, index, params);
		view.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				// 当用户点击该View时候,设置ViewPager正确而Pager Item
				if (mTabLinearLayoutListener != null)
					mTabLinearLayoutListener.onTab(v, index);

				// 设置ViewPager的显示项。
				mPager.setCurrentItem(index, true);
				setCurrentItem(index);
			}
		});
	}

	// 设置当前LinearLayout的pos项子view被选中。
	public void setCurrentItem(int pos) {
		setIndicatorViewSelected(pos);
	}

	// 一个接口,当用户点击选项卡时候,方法被回调。
	public interface TabLinearLayoutListener {
		public void onTab(View v, int pos);

		public void onTab(int pos);
	}
}
时间: 2024-10-12 19:46:37

Android ViewPager实现Tabhost选项卡底部滑块动态滑动过渡的相关文章

基于ViewPagerIndicator的UnderlinePageIndicator,ViewPager选项卡底部滑块衬线滑动控件

<基于ViewPagerIndicator的UnderlinePageIndicator,ViewPager选项卡底部滑块衬线滑动控件> 基于github上的第三方开源的ViewPagerIndicator的UnderlinePageIndicator( 附:地址),自己写的一个在选项卡底部有衬线的滑动控件. 控件效果图如图所示. 有一个特别的效果是:头部的选项卡在ViewPager切换过程中,底部的滑块也随之动态渐渐滑动过渡. 代码: MainActivity.java package zh

Android ViewPager和Fragment实现顶部导航界面滑动效果

在项目中,我们常常需要实现界面滑动切换的效果.例如,微信界面的左右滑动切换效果.那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果. 一. ViewPager 官方API 首先我们来看一下ViewPager官方给出的解释,如图: 具体意思如下: Layout 管理器允许用户可以在页面上,左右滑动来翻动页面.你可以考虑实现PagerAdapter接口来显示该效果. ViewPager很多时候会结合Fragment一块使用,这种方法使得管理每个页面的生命周期变得

【Android基础篇】TabHost实现底部导航栏

在App应用中,导航栏往往是用于解决功能分块的最佳控件,而底部导航栏更是导航栏中最常用的,因为它位于屏幕底部,用户操作起来会很方便. 下面介绍一下使用Android控件TabHost实现底部导航栏的方法. TabHost可以在控件库里直接拖到页面上,非常方便,但拖出来的是顶部导航栏,如下图所示: 到这里就可以开始实现底部导航栏了,我们首先转到它的XML布局代码里,然后修改成下面这样: <FrameLayout xmlns:android="http://schemas.android.co

Android用TabLayout实现类似网易选项卡动态滑动效果

此前我们用HorizontalScrollView也实现了类似网易选项卡动态滑动效果,详见 Android选项卡动态滑动效果这篇文章 这里我们用TabLayout来实现这一效果.TabLayout是Android Design Support Library库中的控件. Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给

Android学习笔记(30):选项卡TabHost

TabHost组件是可以在界面中存放多个选项卡的容器,选项卡大小与外部容器相同. TabWidget 组件就是TabHost的标题条,单击可以切换选项卡. TabSpec组件就是一个选项卡(Tab页面). TabHost的使用步骤如下: 1.在XML文件中定义一个TabHost组件,并在其中定义一个FrameLayout.在其中添加内容. 2.Activity应该继承自TabActivity. 3.调用TabActivity的getTabHost()方法获取TabHost对象. 4.通过TabH

android学习--TabHost选项卡组件

TabHost是一种非常实用的组件,TabHost可以很方便地在窗口上放置多个标签页,每个标签页获得了一个与外部容器相同大小的组件摆放区域.在手机系统的应用类似"未接电话"."已接电话"."呼出电话"等. 1 . TabHost提供了两个方法来创建选项卡.添加选项卡 newTabSpec(String tag)  : 创建选项卡 addTab(TabHost.TabSpec  tabSpec) : 添加选项卡 2.TabHost 切换选项卡触发的

Android开发——实现TabHost 随手滑动切换选项卡功能(绝对实用)

以前用TabHost只是点击导航栏选项卡才进行切换,今天试了下手势滑动进行切换,搜了好多资料感觉特别乱,花了好长时间整理了一下终于有效果了,自己写了一个Demo. 程序清单1:布局文件 说明:和我们写Tabhost布局文件一样 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout  xmlns:android="http://schemas.andro

TabTopAutoLayout【自定义顶部选项卡区域(带下划线)(动态选项卡数据且可滑动)】

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 自定义顶部选项卡布局LinearLayout类,实现带下划线且可滑动效果.[实际情况中建议使用RecyclerView] 备注:如果配合Fragment的话,MainActivity中的写法需要灵活处理. 效果图 代码分析 TabTopAutoLayout:底部选项卡布局类——自定义的LinearLayout子类:实现了各个选项卡的布局.状态切换.点击事件的回调. 需要注意:注释掉params.weight = 1; //设置要添加的子

Android ViewPager使用详解

转载自博客:http://blog.csdn.net/alangdangjia/article/details/9054921/ 这是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等.那如何使用它呢,与LisstView类似,我们也需要一个适配器,他就是PagerAdapter.看一下api的图片, ViewPager的功能就是可以使视图滑动,就像Lanu