上一篇《Android实现带Tab页引导的ViewPager》实现的自定义控件是仅在横屏或者竖屏下能正常使用的,详见:http://www.cnblogs.com/zealotrouge/archive/2013/04/09/3009927.html。
那么在发生横竖转屏时,上述控件存在的最大问题就是:动画已绘制完的”下划线影像“无法与转屏后的tab页对齐,只有点击tab页或者滑动viewpager之后才会重新执行动画,将之前的动画消除。原因有二,其一,动画绘制”下划线影像“无法改变长度,其二,下划线视图本身一直在最左边,与”下划线影像“的距离仍然保持之前动画的位移,故无法立即将下划线与tab页对齐,这样就丧失了引导的作用。所以对这个自定义控件做了一下升级,弃用动画方式,改用动态加载tab和underline,一个tab对应一个underline,控制每个underline的显示与隐藏就可以了,并且能自适应横竖转。
代码如下:
public class TabViewPager extends LinearLayout implements OnPageChangeListener { /* 数据段begin */ public final static String TAG = "TabViewPager"; private Context mContext; private LinearLayout mTabHost; private LinearLayout mUnderlineHost; private ViewPager mViewPager; //tab及underline宽度,也是underline的最小移动距离 private int mTabWidth; //记录横竖屏之前的位置 private int mLastPosition = 0; /* 数据段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); mUnderlineHost = (LinearLayout) findViewById(R.id.underline_host); mViewPager = (ViewPager) findViewById(R.id.view_pager); } public void initTabs(String[] tabTitles, int parentWidth) { if (tabTitles.length <= 0) { return; } LinearLayout.LayoutParams tabHostLayoutParams; LinearLayout.LayoutParams underlineHostLayoutParams; TextView tab; View underline; //计算宽度 mTabWidth = parentWidth / tabTitles.length; //动态添加tab mTabHost.removeAllViews(); tabHostLayoutParams = new LinearLayout.LayoutParams(mTabWidth, LinearLayout.LayoutParams.WRAP_CONTENT); for (int loopVal = 0; loopVal < tabTitles.length; loopVal++) { tab = new TextView(mContext); tab.setText(tabTitles[loopVal]); tab.setTextSize(18); tab.setTextColor(getResources().getColor(R.color.white)); tab.setLayoutParams(tabHostLayoutParams); tab.setGravity(Gravity.CENTER); tab.setOnClickListener(new TabOnClickListener(loopVal)); mTabHost.addView(tab); } //动态添加underline mUnderlineHost.removeAllViews(); underlineHostLayoutParams = new LinearLayout.LayoutParams(mTabWidth, 4); for (int loopVal = 0; loopVal < tabTitles.length; loopVal++) { underline = new View(mContext); underline.setBackgroundColor(getResources().getColor(R.color.lightblue)); underline.setLayoutParams(underlineHostLayoutParams); if (loopVal == mLastPosition) { underline.setVisibility(View.VISIBLE); } else { underline.setVisibility(View.INVISIBLE); } mUnderlineHost.addView(underline); } } public void setAdapter(PagerAdapter pagerAdapter) { mViewPager.setAdapter(pagerAdapter); //滑动监听器 mViewPager.setOnPageChangeListener(this); //设置缓存个数 mViewPager.setOffscreenPageLimit(3); } //当用户点击tab时,将ViewPager滑动到相应页 private void setCurrentItem(int position) { mViewPager.setCurrentItem(position); } @Override public void onPageSelected(int position) { //记录横竖屏之前的位置 mLastPosition = position; for (int loopVal = 0; loopVal < mUnderlineHost.getChildCount(); loopVal++) { if (loopVal != position) { mUnderlineHost.getChildAt(loopVal).setVisibility(View.INVISIBLE); } else { mUnderlineHost.getChildAt(position).setVisibility(View.VISIBLE); } } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageScrollStateChanged(int state) { } /* 函数段end */ /* 内部类begin */ //tab监听器 private class TabOnClickListener implements OnClickListener { private int viewPosition = -1; public TabOnClickListener(int position) { viewPosition = position; } @Override public void onClick(View v) { setCurrentItem(viewPosition); } } /* 内部类end */ }
布局如下:
<?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" > <RelativeLayout android:id="@+id/tab_parent" 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_centerVertical="true" android:orientation="horizontal" /> <LinearLayout android:id="@+id/underline_host" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:orientation="horizontal" /> </RelativeLayout> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="9" /> </LinearLayout>