你的位置:首页 > 操作系统

[操作系统]Fragment利用ViewPager实现左右滑动


MainActivity:

 1 package com.zzw.fragmentteb; 2  3 import java.util.ArrayList; 4  5 import android.graphics.Color; 6 import android.os.Bundle; 7 import android.support.v4.app.Fragment; 8 import android.support.v4.app.FragmentActivity; 9 import android.support.v4.app.FragmentManager;10 import android.support.v4.app.FragmentPagerAdapter;11 import android.support.v4.view.ViewPager;12 import android.view.WindowManager;13 14 public class MainActivity extends FragmentActivity {15 16   ArrayList<Fragment> list;17 18   @Override19   protected void onCreate(Bundle savedInstanceState) {20     super.onCreate(savedInstanceState);21     setContentView(R.layout.activity_main);22     toggleFullscreen(true);// 设置全屏23     list = new ArrayList<Fragment>();24     list.add(setFragmentData("我是第一个Fragment", Color.RED));25     list.add(setFragmentData("我是第二个Fragment", Color.GRAY));26     list.add(setFragmentData("我是第三个Fragment", Color.GREEN));27     list.add(setFragmentData("我是第四个Fragment", Color.BLUE));28     list.add(setFragmentData("我是第五个Fragment", Color.YELLOW));29 30     ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);31 32     viewPager.setAdapter(new MyAdapter(this.getSupportFragmentManager()));33 34     // 设置tab栏35     SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding);36     mSlidingTabLayout.setViewPager(viewPager);37   }38 39   // 设置全屏40   public void toggleFullscreen(boolean fullScreen) {41     // fullScreen为true时全屏,否则相反42 43     WindowManager.LayoutParams attrs = getWindow().getAttributes();44 45     if (fullScreen) {46       attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;47     } else {48       attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;49     }50 51     getWindow().setAttributes(attrs);52   }53 54   // 设置要传递给Fragment的参数55   private Fragment setFragmentData(String name, int color) {56     Fragment f = new MyFragment();57 58     Bundle b = new Bundle();59     b.putString("NAME", name);60     b.putInt("COLOR", color);61     f.setArguments(b);62     return f;63   }64 65   private class MyAdapter extends FragmentPagerAdapter {66 67     public MyAdapter(FragmentManager fm) {68       super(fm);69     }70 71     @Override72     public Fragment getItem(int position) {73       return list.get(position);74     }75 76     @Override77     public int getCount() {78       return list.size();79     }80 81     // tab标题82     @Override83     public CharSequence getPageTitle(int position) {84       return position + "";85     }86 87   }88 89 }

MyFragment:

 1 package com.zzw.fragmentteb; 2  3 import android.os.Bundle; 4 import android.support.v4.app.Fragment; 5 import android.view.LayoutInflater; 6 import android.view.View; 7 import android.view.ViewGroup; 8 import android.widget.TextView; 9 10 public class MyFragment extends Fragment {11   private static final String TAG = "TestFragment";12 13   String name;14   int color;15 16   @Override17   public void onCreate(Bundle savedInstanceState) {18     super.onCreate(savedInstanceState);19     Bundle b = this.getArguments();20     name = b.getString("NAME");21     color = b.getInt("COLOR");22   }23 24   @Override25   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {26     View view = inflater.inflate(android.R.layout.simple_list_item_1, null);27     view.setBackgroundColor(color);28     return view;29   }30 31   @Override32   public void onViewCreated(View view, Bundle savedInstanceState) {33 34     TextView text1 = (TextView) view.findViewById(android.R.id.text1);35 36     text1.setText(name);37   }38 }

SlidingTabLayout.java:

直接导入包里面:

 1 package com.zzw.fragmentteb; 2  3 import android.content.Context; 4 import android.graphics.Typeface; 5 import android.os.Build; 6 import android.support.v4.view.PagerAdapter; 7 import android.support.v4.view.ViewPager; 8 import android.util.AttributeSet; 9 import android.util.TypedValue; 10 import android.view.Gravity; 11 import android.view.LayoutInflater; 12 import android.view.View; 13 import android.widget.HorizontalScrollView; 14 import android.widget.LinearLayout; 15 import android.widget.TextView; 16  17 /** 18  * To be used with ViewPager to provide a tab indicator component which give 19  * constant feedback as to the user's scroll progress. 20  * <p> 21  * To use the component, simply add it to your view hierarchy. Then in your 22  * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call 23  * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is 24  * being used for. 25  * <p> 26  * The colors can be customized in two ways. The first and simplest is to 27  * provide an array of colors via {@link #setSelectedIndicatorColors(int...)} 28  * and {@link #setDividerColors(int...)}. The alternative is via the 29  * {@link TabColorizer} interface which provides you complete control over which 30  * color is used for any individual position. 31  * <p> 32  * The views used as tabs can be customized by calling 33  * {@link #setCustomTabView(int, int)}, providing the layout ID of your custom 34  * layout. 35 */ 36  37 public class SlidingTabLayout extends HorizontalScrollView { 38  39   /** 40    * Allows complete control over the colors drawn in the tab layout. Set with 41    * {@link #setCustomTabColorizer(TabColorizer)}. 42   */ 43   public interface TabColorizer { 44  45     /** 46      * @return return the color of the indicator used when {@code position} 47      *     is selected. 48     */ 49     int getIndicatorColor(int position); 50  51     /** 52      * @return return the color of the divider drawn to the right of 53      *     {@code position}. 54     */ 55     int getDividerColor(int position); 56  57   } 58  59   private static final int TITLE_OFFSET_DIPS = 24; 60   private static final int TAB_VIEW_PADDING_DIPS = 16; 61   private static final int TAB_VIEW_TEXT_SIZE_SP = 12; 62  63   private int mTitleOffset; 64  65   private int mTabViewLayoutId; 66   private int mTabViewTextViewId; 67  68   private ViewPager mViewPager; 69   private ViewPager.OnPageChangeListener mViewPagerPageChangeListener; 70  71   private final SlidingTabStrip mTabStrip; 72  73   public SlidingTabLayout(Context context) { 74     this(context, null); 75   } 76  77   public SlidingTabLayout(Context context, AttributeSet attrs) { 78     this(context, attrs, 0); 79   } 80  81   public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) { 82     super(context, attrs, defStyle); 83  84     // Disable the Scroll Bar 85     setHorizontalScrollBarEnabled(false); 86     // Make sure that the Tab Strips fills this View 87     setFillViewport(true); 88  89     mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density); 90  91     mTabStrip = new SlidingTabStrip(context); 92     addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); 93   } 94  95   /** 96    * Set the custom {@link TabColorizer} to be used. 97    * 98    * If you only require simple custmisation then you can use 99    * {@link #setSelectedIndicatorColors(int...)} and100    * {@link #setDividerColors(int...)} to achieve similar effects.101   */102   public void setCustomTabColorizer(TabColorizer tabColorizer) {103     mTabStrip.setCustomTabColorizer(tabColorizer);104   }105 106   /**107    * Sets the colors to be used for indicating the selected tab. These colors108    * are treated as a circular array. Providing one color will mean that all109    * tabs are indicated with the same color.110   */111   public void setSelectedIndicatorColors(int... colors) {112     mTabStrip.setSelectedIndicatorColors(colors);113   }114 115   /**116    * Sets the colors to be used for tab dividers. These colors are treated as117    * a circular array. Providing one color will mean that all tabs are118    * indicated with the same color.119   */120   public void setDividerColors(int... colors) {121     mTabStrip.setDividerColors(colors);122   }123 124   /**125    * Set the {@link ViewPager.OnPageChangeListener}. When using126    * {@link SlidingTabLayout} you are required to set any127    * {@link ViewPager.OnPageChangeListener} through this method. This is so128    * that the layout can update it's scroll position correctly.129    *130    * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)131   */132   public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {133     mViewPagerPageChangeListener = listener;134   }135 136   /**137    * Set the custom layout to be inflated for the tab views.138    *139    * @param layoutResId140    *      Layout id to be inflated141    * @param textViewId142    *      id of the {@link TextView} in the inflated view143   */144   public void setCustomTabView(int layoutResId, int textViewId) {145     mTabViewLayoutId = layoutResId;146     mTabViewTextViewId = textViewId;147   }148 149   /**150    * Sets the associated view pager. Note that the assumption here is that the151    * pager content (number of tabs and tab titles) does not change after this152    * call has been made.153   */154   public void setViewPager(ViewPager viewPager) {155     mTabStrip.removeAllViews();156 157     mViewPager = viewPager;158     if (viewPager != null) {159       viewPager.setOnPageChangeListener(new InternalViewPagerListener());160       populateTabStrip();161     }162   }163 164   /**165    * Create a default view to be used for tabs. This is called if a custom tab166    * view is not set via {@link #setCustomTabView(int, int)}.167   */168   protected TextView createDefaultTabView(Context context) {169     TextView textView = new TextView(context);170     textView.setGravity(Gravity.CENTER);171     textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);172     textView.setTypeface(Typeface.DEFAULT_BOLD);173 174     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {175       // If we're running on Honeycomb or newer, then we can use the176       // Theme's177       // selectableItemBackground to ensure that the View has a pressed178       // state179       TypedValue outValue = new TypedValue();180       getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, outValue, true);181       textView.setBackgroundResource(outValue.resourceId);182     }183 184     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {185       // If we're running on ICS or newer, enable all-caps to match the186       // Action Bar tab style187       textView.setAllCaps(true);188     }189 190     int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);191     textView.setPadding(padding, padding, padding, padding);192 193     return textView;194   }195 196   private void populateTabStrip() {197     final PagerAdapter adapter = mViewPager.getAdapter();198     final View.OnClickListener tabClickListener = new TabClickListener();199 200     for (int i = 0; i < adapter.getCount(); i++) {201       View tabView = null;202       TextView tabTitleView = null;203 204       if (mTabViewLayoutId != 0) {205         // If there is a custom tab view layout id set, try and inflate206         // it207         tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip, false);208         tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);209       }210 211       if (tabView == null) {212         tabView = createDefaultTabView(getContext());213       }214 215       if (tabTitleView == null && TextView.class.isInstance(tabView)) {216         tabTitleView = (TextView) tabView;217       }218 219       tabTitleView.setText(adapter.getPageTitle(i));220       tabView.setOnClickListener(tabClickListener);221       //将tab标题栏平均分配222       LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f);223       tabView.setLayoutParams(layoutParams);224 225       mTabStrip.addView(tabView);226     }227   }228 229   @Override230   protected void onAttachedToWindow() {231     super.onAttachedToWindow();232 233     if (mViewPager != null) {234       scrollToTab(mViewPager.getCurrentItem(), 0);235     }236   }237 238   private void scrollToTab(int tabIndex, int positionOffset) {239     final int tabStripChildCount = mTabStrip.getChildCount();240     if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {241       return;242     }243 244     View selectedChild = mTabStrip.getChildAt(tabIndex);245     if (selectedChild != null) {246       int targetScrollX = selectedChild.getLeft() + positionOffset;247 248       if (tabIndex > 0 || positionOffset > 0) {249         // If we're not at the first child and are mid-scroll, make sure250         // we obey the offset251         targetScrollX -= mTitleOffset;252       }253 254       scrollTo(targetScrollX, 0);255     }256   }257 258   private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {259     private int mScrollState;260 261     @Override262     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {263       int tabStripChildCount = mTabStrip.getChildCount();264       if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {265         return;266       }267 268       mTabStrip.onViewPagerPageChanged(position, positionOffset);269 270       View selectedTitle = mTabStrip.getChildAt(position);271       int extraOffset = (selectedTitle != null) ? (int) (positionOffset * selectedTitle.getWidth()) : 0;272       scrollToTab(position, extraOffset);273 274       if (mViewPagerPageChangeListener != null) {275         mViewPagerPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);276       }277     }278 279     @Override280     public void onPageScrollStateChanged(int state) {281       mScrollState = state;282 283       if (mViewPagerPageChangeListener != null) {284         mViewPagerPageChangeListener.onPageScrollStateChanged(state);285       }286     }287 288     @Override289     public void onPageSelected(int position) {290       if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {291         mTabStrip.onViewPagerPageChanged(position, 0f);292         scrollToTab(position, 0);293       }294 295       if (mViewPagerPageChangeListener != null) {296         mViewPagerPageChangeListener.onPageSelected(position);297       }298     }299   }300 301   private class TabClickListener implements View.OnClickListener {302     @Override303     public void onClick(View v) {304       for (int i = 0; i < mTabStrip.getChildCount(); i++) {305         if (v == mTabStrip.getChildAt(i)) {306           mViewPager.setCurrentItem(i);307           return;308         }309       }310     }311   }312 }

SlidingTabStrip.java

直接导入包里

 1 package com.zzw.fragmentteb; 2  3 import android.content.Context; 4 import android.graphics.Canvas; 5 import android.graphics.Color; 6 import android.graphics.Paint; 7 import android.util.AttributeSet; 8 import android.util.TypedValue; 9 import android.view.View; 10 import android.widget.LinearLayout; 11  12 class SlidingTabStrip extends LinearLayout { 13  14   private static final int DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS = 2; 15   private static final byte DEFAULT_BOTTOM_BORDER_COLOR_ALPHA = 0x26; 16   private static final int SELECTED_INDICATOR_THICKNESS_DIPS = 8; 17   private static final int DEFAULT_SELECTED_INDICATOR_COLOR = 0xFF33B5E5; 18  19   private static final int DEFAULT_DIVIDER_THICKNESS_DIPS = 1; 20   private static final byte DEFAULT_DIVIDER_COLOR_ALPHA = 0x20; 21   private static final float DEFAULT_DIVIDER_HEIGHT = 0.5f; 22  23   private final int mBottomBorderThickness; 24   private final Paint mBottomBorderPaint; 25  26   private final int mSelectedIndicatorThickness; 27   private final Paint mSelectedIndicatorPaint; 28  29   private final int mDefaultBottomBorderColor; 30  31   private final Paint mDividerPaint; 32   private final float mDividerHeight; 33  34   private int mSelectedPosition; 35   private float mSelectionOffset; 36  37   private SlidingTabLayout.TabColorizer mCustomTabColorizer; 38   private final SimpleTabColorizer mDefaultTabColorizer; 39  40   SlidingTabStrip(Context context) { 41     this(context, null); 42   } 43  44   SlidingTabStrip(Context context, AttributeSet attrs) { 45     super(context, attrs); 46     setWillNotDraw(false); 47  48     final float density = getResources().getDisplayMetrics().density; 49  50     TypedValue outValue = new TypedValue(); 51  52     // context.getTheme().resolveAttribute(R.attr.colorForeground, outValue, 53     // true); 54  55     final int themeForegroundColor = outValue.data; 56  57     mDefaultBottomBorderColor = setColorAlpha(themeForegroundColor, DEFAULT_BOTTOM_BORDER_COLOR_ALPHA); 58  59     mDefaultTabColorizer = new SimpleTabColorizer(); 60     mDefaultTabColorizer.setIndicatorColors(DEFAULT_SELECTED_INDICATOR_COLOR); 61     mDefaultTabColorizer.setDividerColors(setColorAlpha(themeForegroundColor, DEFAULT_DIVIDER_COLOR_ALPHA)); 62  63     mBottomBorderThickness = (int) (DEFAULT_BOTTOM_BORDER_THICKNESS_DIPS * density); 64     mBottomBorderPaint = new Paint(); 65     mBottomBorderPaint.setColor(mDefaultBottomBorderColor); 66  67     mSelectedIndicatorThickness = (int) (SELECTED_INDICATOR_THICKNESS_DIPS * density); 68     mSelectedIndicatorPaint = new Paint(); 69  70     mDividerHeight = DEFAULT_DIVIDER_HEIGHT; 71     mDividerPaint = new Paint(); 72     mDividerPaint.setStrokeWidth((int) (DEFAULT_DIVIDER_THICKNESS_DIPS * density)); 73   } 74  75   void setCustomTabColorizer(SlidingTabLayout.TabColorizer customTabColorizer) { 76     mCustomTabColorizer = customTabColorizer; 77     invalidate(); 78   } 79  80   void setSelectedIndicatorColors(int... colors) { 81     // Make sure that the custom colorizer is removed 82     mCustomTabColorizer = null; 83     mDefaultTabColorizer.setIndicatorColors(colors); 84     invalidate(); 85   } 86  87   void setDividerColors(int... colors) { 88     // Make sure that the custom colorizer is removed 89     mCustomTabColorizer = null; 90     mDefaultTabColorizer.setDividerColors(colors); 91     invalidate(); 92   } 93  94   void onViewPagerPageChanged(int position, float positionOffset) { 95     mSelectedPosition = position; 96     mSelectionOffset = positionOffset; 97     invalidate(); 98   } 99 100   @Override101   protected void onDraw(Canvas canvas) {102     final int height = getHeight();103     final int childCount = getChildCount();104     final int dividerHeightPx = (int) (Math.min(Math.max(0f, mDividerHeight), 1f) * height);105     final SlidingTabLayout.TabColorizer tabColorizer = mCustomTabColorizer != null ? mCustomTabColorizer106         : mDefaultTabColorizer;107 108     // Thick colored underline below the current selection109     if (childCount > 0) {110       View selectedTitle = getChildAt(mSelectedPosition);111       int left = selectedTitle.getLeft();112       int right = selectedTitle.getRight();113       int color = tabColorizer.getIndicatorColor(mSelectedPosition);114 115       if (mSelectionOffset > 0f && mSelectedPosition < (getChildCount() - 1)) {116         int nextColor = tabColorizer.getIndicatorColor(mSelectedPosition + 1);117         if (color != nextColor) {118           color = blendColors(nextColor, color, mSelectionOffset);119         }120 121         // Draw the selection partway between the tabs122         View nextTitle = getChildAt(mSelectedPosition + 1);123         left = (int) (mSelectionOffset * nextTitle.getLeft() + (1.0f - mSelectionOffset) * left);124         right = (int) (mSelectionOffset * nextTitle.getRight() + (1.0f - mSelectionOffset) * right);125       }126 127       mSelectedIndicatorPaint.setColor(color);128 129       canvas.drawRect(left, height - mSelectedIndicatorThickness, right, height, mSelectedIndicatorPaint);130     }131 132     // Thin underline along the entire bottom edge133     canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint);134 135     // Vertical separators between the titles136     int separatorTop = (height - dividerHeightPx) / 2;137     for (int i = 0; i < childCount - 1; i++) {138       View child = getChildAt(i);139       mDividerPaint.setColor(tabColorizer.getDividerColor(i));140       canvas.drawLine(child.getRight(), separatorTop, child.getRight(), separatorTop + dividerHeightPx,141           mDividerPaint);142     }143   }144 145   /**146    * Set the alpha value of the {@code color} to be the given {@code alpha}147    * value.148   */149   private static int setColorAlpha(int color, byte alpha) {150     return Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));151   }152 153   /**154    * Blend {@code color1} and {@code color2} using the given ratio.155    *156    * @param ratio157    *      of which to blend. 1.0 will return {@code color1}, 0.5 will158    *      give an even blend, 0.0 will return {@code color2}.159   */160   private static int blendColors(int color1, int color2, float ratio) {161     final float inverseRation = 1f - ratio;162     float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);163     float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);164     float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);165     return Color.rgb((int) r, (int) g, (int) b);166   }167 168   private static class SimpleTabColorizer implements SlidingTabLayout.TabColorizer {169     private int[] mIndicatorColors;170     private int[] mDividerColors;171 172     @Override173     public final int getIndicatorColor(int position) {174       return mIndicatorColors[position % mIndicatorColors.length];175     }176 177     @Override178     public final int getDividerColor(int position) {179       return mDividerColors[position % mDividerColors.length];180     }181 182     void setIndicatorColors(int... colors) {183       mIndicatorColors = colors;184     }185 186     void setDividerColors(int... colors) {187       mDividerColors = colors;188     }189   }190 }

activity_main.

 1 <RelativeLayout ="http://schemas.android.com/apk/res/android" 2   ="http://schemas.android.com/tools" 3   android:layout_width="match_parent" 4   android:layout_height="match_parent" 5   tools:context="com.zzw.fragmentteb.MainActivity" > 6   <!-- 在上方就在上面,在下方就在下面(tab栏) --> 7   <com.zzw.fragmentteb.SlidingTabLayout  8     android:id="@+id/sliding"  9     android:layout_width="match_parent" 10     android:layout_height="wrap_content" /> 11   12   <android.support.v4.view.ViewPager13     android:id="@+id/view_pager"14     android:layout_width="match_parent"15     android:layout_height="match_parent" />16 17 </RelativeLayout>