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); } }