注意:有关Fragment的方法和ViewPager的全部是android.support.v4包的,否则会报很多的错误
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.Window; 13 import android.view.WindowManager; 14 15 public class MainActivity extends FragmentActivity { 16 17 ArrayList<Fragment> list; 18 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_main); 23 24 list = new ArrayList<Fragment>(); 25 list.add(setFragmentData("我是第一个Fragment", Color.RED)); 26 list.add(setFragmentData("我是第二个Fragment", Color.GRAY)); 27 list.add(setFragmentData("我是第三个Fragment", Color.GREEN)); 28 list.add(setFragmentData("我是第四个Fragment", Color.BLUE)); 29 list.add(setFragmentData("我是第五个Fragment", Color.YELLOW)); 30 31 ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager); 32 33 viewPager.setAdapter(new MyAdapter(this.getSupportFragmentManager())); 34 35 // 设置tab栏 36 SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.sliding); 37 mSlidingTabLayout.setViewPager(viewPager); 38 } 39 40 41 // 设置要传递给Fragment的参数 42 private Fragment setFragmentData(String name, int color) { 43 Fragment f = new MyFragment(); 44 45 Bundle b = new Bundle(); 46 b.putString("NAME", name); 47 b.putInt("COLOR", color); 48 f.setArguments(b); 49 return f; 50 } 51 52 private class MyAdapter extends FragmentPagerAdapter { 53 54 public MyAdapter(FragmentManager fm) { 55 super(fm); 56 } 57 58 @Override 59 public Fragment getItem(int position) { 60 return list.get(position); 61 } 62 63 @Override 64 public int getCount() { 65 return list.size(); 66 } 67 68 // tab标题 69 @Override 70 public CharSequence getPageTitle(int position) { 71 return position + ""; 72 } 73 74 } 75 76 }
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 private String name; 14 private int color; 15 16 @Override 17 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 @Override 25 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 @Override 32 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...)} and 100 * {@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 colors 108 * are treated as a circular array. Providing one color will mean that all 109 * 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 as 117 * a circular array. Providing one color will mean that all tabs are 118 * 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 using 126 * {@link SlidingTabLayout} you are required to set any 127 * {@link ViewPager.OnPageChangeListener} through this method. This is so 128 * 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 layoutResId 140 * Layout id to be inflated 141 * @param textViewId 142 * id of the {@link TextView} in the inflated view 143 */ 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 the 151 * pager content (number of tabs and tab titles) does not change after this 152 * 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 tab 166 * 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 the 176 // Theme's 177 // selectableItemBackground to ensure that the View has a pressed 178 // state 179 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 the 186 // Action Bar tab style 187 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 inflate 206 // it 207 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 @Override 230 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 sure 250 // we obey the offset 251 targetScrollX -= mTitleOffset; 252 } 253 254 scrollTo(targetScrollX, 0); 255 } 256 } 257 258 private class InternalViewPagerListener implements ViewPager.OnPageChangeListener { 259 private int mScrollState; 260 261 @Override 262 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 @Override 280 public void onPageScrollStateChanged(int state) { 281 mScrollState = state; 282 283 if (mViewPagerPageChangeListener != null) { 284 mViewPagerPageChangeListener.onPageScrollStateChanged(state); 285 } 286 } 287 288 @Override 289 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 @Override 303 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 @Override 101 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 ? mCustomTabColorizer 106 : mDefaultTabColorizer; 107 108 // Thick colored underline below the current selection 109 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 tabs 122 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 edge 133 canvas.drawRect(0, height - mBottomBorderThickness, getWidth(), height, mBottomBorderPaint); 134 135 // Vertical separators between the titles 136 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 ratio 157 * of which to blend. 1.0 will return {@code color1}, 0.5 will 158 * 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 @Override 173 public final int getIndicatorColor(int position) { 174 return mIndicatorColors[position % mIndicatorColors.length]; 175 } 176 177 @Override 178 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.xml:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context="com.zzw.fragmentteb.MainActivity" > 7 <!-- 在上方就在上面,在下方就在下面(tab栏)要确定位置 --> 8 <com.zzw.fragmentteb.SlidingTabLayout 9 android:id="@+id/sliding" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" /> 12 13 <android.support.v4.view.ViewPager 14 android:id="@+id/view_pager" 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" /> 17 18 </LinearLayout>