Tab页很适合用来做平行功能之间的引导,而各功能页面用ViewPager来展示会显得比较平滑、过渡自然,所以自然就有了许多软件将二者结合,用于展示主功能界面,比如网易新闻和360优化大师的主界面,那么下面就来做一个这样的带Tab页的ViewPager吧~
基本需求:1,点击Tab页,ViewPager做出相应滑动,且Tab页中有表示切换的动画
2,滑动ViewPager,Tab页中有表示切换的动画
3,Tab页可以动态添加并自行计算所占宽度
基本思路是:用一个横向LinearLayout管理动态加载的Tab页,下方是ViewPager,再用代码将二者关联起来就可以了,代码如下
public class TabViewPager extends LinearLayout
{
/* 数据段begin */
public final static String TAG = "TabViewPager";
private Context mContext;
private LinearLayout mTabHost;
private ImageView mUnderline;
private ViewPager mViewPager;
//tab及underline宽度,也是underline的最小移动距离
private int mTabWidth;
/* 数据段end */
/* 函数段begin */
public TabViewPager(Context context, AttributeSet attrs)
{
super(context, attrs);
mContext = context;
inflate(mContext, R.layout.tab_view_pager, this);
initViews();
}
private void initViews()
{
mTabHost = (LinearLayout) findViewById(R.id.tab_host);
mUnderline = (ImageView) findViewById(R.id.tab_underline);
mViewPager = (ViewPager) findViewById(R.id.view_pager);
}
public void initTabs(String[] tabTitles, int parentWidth)
{
LinearLayout.LayoutParams tabHostLayoutParams;
TextView tab;
mTabWidth = parentWidth / tabTitles.length;
//设置宽度
if (tabTitles.length > 0)
{
tabHostLayoutParams = new LinearLayout.LayoutParams(mTabWidth, LinearLayout.LayoutParams.WRAP_CONTENT);
}
else
{
return;
}
//动态添加tab
for (int loopVal = 0; loopVal < tabTitles.length; loopVal++)
{
tab = new TextView(mContext);
tab.setText(tabTitles[loopVal]);
tab.setTextSize(22);
tab.setTextColor(getResources().getColor(R.color.white));
tabHostLayoutParams.weight = 1;
tabHostLayoutParams.gravity = Gravity.CENTER_VERTICAL;
tab.setLayoutParams(tabHostLayoutParams);
tab.setGravity(Gravity.CENTER);
tab.setOnClickListener(new TabOnClickListener(loopVal));
mTabHost.addView(tab);
}
//设置underline宽度,使得下划线与tab宽度保持一致
FrameLayout.LayoutParams frameLayoutParams = new FrameLayout.LayoutParams(mTabWidth, FrameLayout.LayoutParams.WRAP_CONTENT);
frameLayoutParams.gravity = Gravity.BOTTOM;
mUnderline.setLayoutParams(frameLayoutParams);
mUnderline.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_view_pager_underline));
}
public void setAdapter(PagerAdapter pagerAdapter)
{
mViewPager.setAdapter(pagerAdapter);
//滑动viewPager时也要执行mUnderline的移动动画
mViewPager.setOnPageChangeListener(new OnPageChangeListener()
{
private int currentPosition = -1;
private int nextPosition = -1;
@Override
public void onPageSelected(int position)
{
nextPosition = position;
//mUnderline的移动动画
mUnderline.startAnimation(new UnderlineTranslateAnimation(currentPosition * mTabWidth, nextPosition * mTabWidth, 0, 0));
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
currentPosition = position;
}
@Override
public void onPageScrollStateChanged(int state)
{
}
});
}
public void setCurrentItem(int position)
{
//记录当前的位置后再设置选中位置
int currentPosition = mViewPager.getCurrentItem();
mViewPager.setCurrentItem(position);
int nextPosition = mViewPager.getCurrentItem();
//mUnderline的移动动画
mUnderline.startAnimation(new UnderlineTranslateAnimation(currentPosition * mTabWidth, nextPosition * mTabWidth, 0, 0));
}
/* 函数段end */
/* 内部类begin */
private class TabOnClickListener implements OnClickListener
{
private int viewPosition = -1;
public TabOnClickListener(int position)
{
viewPosition = position;
}
@Override
public void onClick(View v)
{
if (AppEnv.bAppdebug)
{
Log.d(TAG, "tab onClick --> " + ((TextView) v).getText());
}
setCurrentItem(viewPosition);
}
}
private class UnderlineTranslateAnimation extends TranslateAnimation
{
public UnderlineTranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
{
super(fromXDelta, toXDelta, fromYDelta, toYDelta);
setFillAfter(true);
}
}
/* 内部类end */
}
这样,只需调用initTabs()来设置Tab页,和setAdapter()来设置适配器即可使用。
相应布局代码
<?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="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:ignore="ContentDescription" >
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/tab_host"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:orientation="horizontal" >
</LinearLayout>
<ImageView
android:id="@+id/tab_underline"
android:layout_width="0dp"
android:layout_height="0dp" />
</FrameLayout>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="7" />
</LinearLayout>