Android实现带Tab页引导的ViewPager2.0 (增加对横竖转屏的支持)

  上一篇《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>

 

posted @ 2013-04-17 20:08  热气球  阅读(1463)  评论(0编辑  收藏  举报