├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── AdvancedPagerSlidingTabStrip.iml ├── ChangLog.md ├── Library ├── AndroidManifest.xml ├── Library.iml ├── build.gradle ├── res │ ├── drawable │ │ ├── apsts_tips.xml │ │ └── psts_background_tab.xml │ └── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ └── ids.xml └── src │ └── com │ └── lhh │ └── apst │ └── library │ ├── AdvancedPagerSlidingTabStrip.java │ ├── CustomPagerSlidingTabStrip.java │ ├── Margins.java │ └── ViewHolder.java ├── Pic ├── Screen_20160216163404.png ├── Screen_20160216163428.png ├── Screen_20160216163452.png ├── Screen_20160411141706.png ├── categry_icon_n.png ├── categry_icon_p.png ├── classify_icon_n.png ├── classify_icon_p.png ├── mine_icon_n.png ├── mine_icon_p.png ├── update_dynamic_n.png └── update_dynamic_p.png ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── lhh │ │ └── apst │ │ └── advancedpagerslidingtabstrip │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── lhh │ │ └── apst │ │ ├── advancedpagerslidingtabstrip │ │ ├── APSTSViewPager.java │ │ ├── App.java │ │ ├── CustomTabActivity.java │ │ ├── IconTabActivity.java │ │ ├── MainActivity.java │ │ ├── NormalTabActivity.java │ │ ├── ViewTabActivity.java │ │ └── WeiboTabActivity.java │ │ └── fragments │ │ ├── FirstFragment.java │ │ ├── FourthFragment.java │ │ ├── SecondFragment.java │ │ └── ThirdFragment.java │ └── res │ ├── drawable │ ├── sub_background.xml │ ├── tab_bg_normal.xml │ ├── tab_bg_transparent.xml │ ├── tab_bg_white.xml │ ├── tab_color_select.xml │ └── weibo_tab_bg_normal.xml │ ├── layout │ ├── activity_custom_tab.xml │ ├── activity_icon_tab.xml │ ├── activity_main.xml │ ├── activity_normal_tab.xml │ ├── activity_weibo_tab.xml │ ├── custom_disselect_tab.xml │ ├── custom_select_tab.xml │ ├── first_fragment.xml │ ├── fourth_fragment.xml │ ├── second_fragment.xml │ └── third_fragment.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ ├── home_auther_icon_f_n.png │ ├── home_auther_icon_f_p.png │ ├── home_categry_icon_f_n.png │ ├── home_categry_icon_n.png │ ├── home_live_icon_f_n.png │ ├── home_live_icon_n.png │ ├── home_main_icon_f_n.png │ ├── home_main_icon_n.png │ ├── home_mine_icon_f_n.png │ ├── home_mine_icon_n.png │ ├── ic_launcher.png │ ├── tabbar_compose_icon_add_highlighted.png │ ├── tabbar_discover.png │ ├── tabbar_discover_highlighted.png │ ├── tabbar_home.png │ ├── tabbar_home_highlighted.png │ ├── tabbar_home_selected.png │ ├── tabbar_message_center.png │ ├── tabbar_message_center_highlighted.png │ ├── tabbar_profile.png │ └── tabbar_profile_highlighted.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /AdvancedPagerSlidingTabStrip.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ChangLog.md: -------------------------------------------------------------------------------- 1 | ##更新日志 2 | 3 | v1.4.0 4 | 5 | 添加新的provider以及tab等新的设置。 6 | 7 | v1.3.0 8 | 9 | 修改参数属性,将tab标签换为apTab开头标签,避免与support包冲突。 -------------------------------------------------------------------------------- /Library/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Library/Library.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Library/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | dependencies { 4 | compile 'com.android.support:appcompat-v7:23.1.0' 5 | } 6 | 7 | android { 8 | sourceSets { 9 | main { 10 | manifest.srcFile 'AndroidManifest.xml' 11 | java.srcDirs = ['src'] 12 | resources.srcDirs = ['src'] 13 | aidl.srcDirs = ['src'] 14 | renderscript.srcDirs = ['src'] 15 | res.srcDirs = ['res'] 16 | assets.srcDirs = ['assets'] 17 | } 18 | } 19 | 20 | defaultConfig { 21 | minSdkVersion 9 22 | compileSdkVersion 23 23 | buildToolsVersion "23.0.1" 24 | } 25 | } 26 | 27 | apply from: 'https://raw.githubusercontent.com/HomHomLin/Gradle-Publish/master/bintray.gradle' -------------------------------------------------------------------------------- /Library/res/drawable/apsts_tips.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Library/res/drawable/psts_background_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Library/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Library/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #6633B5E5 5 | #E43F3E 6 | -------------------------------------------------------------------------------- /Library/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10dp 5 | 4dp 6 | 9dp 7 | 8dp 8 | 7dp 9 | 23dp 10 | 10sp 11 | -------------------------------------------------------------------------------- /Library/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 888 5 | -------------------------------------------------------------------------------- /Library/src/com/lhh/apst/library/AdvancedPagerSlidingTabStrip.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.library; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Bitmap; 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.Paint; 10 | import android.graphics.Paint.Style; 11 | import android.graphics.Rect; 12 | import android.graphics.Typeface; 13 | import android.graphics.drawable.BitmapDrawable; 14 | import android.graphics.drawable.Drawable; 15 | import android.os.Build; 16 | import android.os.Parcel; 17 | import android.os.Parcelable; 18 | import android.support.v4.content.res.ResourcesCompat; 19 | import android.support.v4.view.ViewPager; 20 | import android.util.AttributeSet; 21 | import android.util.DisplayMetrics; 22 | import android.util.SparseArray; 23 | import android.util.TypedValue; 24 | import android.view.Gravity; 25 | import android.view.View; 26 | import android.view.ViewGroup; 27 | import android.view.ViewTreeObserver.OnGlobalLayoutListener; 28 | import android.widget.HorizontalScrollView; 29 | import android.widget.LinearLayout; 30 | import android.widget.RelativeLayout; 31 | import android.widget.TextView; 32 | 33 | import java.util.Locale; 34 | 35 | /** 36 | * Created by linhomhom on 2015/8/10. 37 | */ 38 | public class AdvancedPagerSlidingTabStrip extends HorizontalScrollView { 39 | 40 | public interface LayoutProvider { 41 | public float getPageWeight(int position); 42 | public int[] getPageRule(int position); 43 | public Margins getPageMargins(int position); 44 | } 45 | 46 | public interface TipsProvider { 47 | public int[] getTipsRule(int position); 48 | public Margins getTipsMargins(int position); 49 | public Drawable getTipsDrawable(int position); 50 | } 51 | 52 | public interface IconTabProvider { 53 | public T getPageIcon(int position); 54 | public T getPageSelectIcon(int position); 55 | public Rect getPageIconBounds(int position); 56 | } 57 | 58 | public interface ViewTabProvider{ 59 | // public View onCreateIconView(int position, View view, ViewGroup parent); 60 | public View onSelectIconView(int position, View view, ViewGroup parent); 61 | public View onIconView(int position, View view, ViewGroup parent); 62 | } 63 | 64 | // @formatter:off 65 | private static final int[] ATTRS = new int[]{ 66 | android.R.attr.textSize, 67 | android.R.attr.textColor 68 | }; 69 | // @formatter:on 70 | private LinearLayout.LayoutParams expandedTabLayoutParams; 71 | 72 | private final PageListener pageListener = new PageListener(); 73 | public ViewPager.OnPageChangeListener delegatePageListener; 74 | 75 | private LinearLayout tabsContainer; 76 | private ViewPager pager; 77 | 78 | private int tabCount; 79 | 80 | private int currentPosition = 0; 81 | private float currentPositionOffset = 0f; 82 | 83 | private Paint rectPaint; 84 | private Paint dividerPaint; 85 | 86 | private boolean checkedTabWidths = false; 87 | 88 | private int indicatorColor = 0xFF666666; 89 | private int underlineColor = 0x1A000000; 90 | private int dividerColor = 0x1A000000; 91 | 92 | private boolean shouldExpand = true; 93 | private boolean textAllCaps = true; 94 | 95 | private int scrollOffset = 52; 96 | private int indicatorHeight = 3; 97 | private int underlineHeight = 2; 98 | private int dividerPadding = 12; 99 | private int tabPadding = 24; 100 | private int tabPaddingTopBottom = 0; 101 | private int dividerWidth = 1; 102 | 103 | private int tabTextSize = 15; 104 | private int tabTextColor = 0xFF666666; 105 | private int tabTextSelectColor = 0xFF666666; 106 | private Typeface tabTypeface = null; 107 | private int tabTypefaceStyle = Typeface.NORMAL; 108 | private int tabDrawMode = DRAW_MODE_NORMAL; 109 | 110 | public static final int DRAW_MODE_NORMAL = 0; 111 | public static final int DRAW_MODE_TEXT = 1; 112 | 113 | private int lastScrollX = 0; 114 | 115 | private int tabBackgroundResId = R.drawable.psts_background_tab; 116 | // private int tabBackgroundResId; 117 | 118 | private Locale locale; 119 | private OnTabClickListener mOnTabClickListener; 120 | public interface OnTabClickListener{ 121 | public void onClick(int pos); 122 | } 123 | 124 | public AdvancedPagerSlidingTabStrip(Context context) { 125 | this(context, null); 126 | } 127 | 128 | public AdvancedPagerSlidingTabStrip(Context context, AttributeSet attrs) { 129 | this(context, attrs, 0); 130 | } 131 | 132 | public AdvancedPagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) { 133 | super(context, attrs, defStyle); 134 | 135 | setFillViewport(true); 136 | setWillNotDraw(false); 137 | 138 | tabsContainer = new LinearLayout(context); 139 | tabsContainer.setOrientation(LinearLayout.HORIZONTAL); 140 | tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 141 | addView(tabsContainer); 142 | 143 | DisplayMetrics dm = getResources().getDisplayMetrics(); 144 | 145 | scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm); 146 | indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm); 147 | underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm); 148 | dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm); 149 | tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm); 150 | dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm); 151 | tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm); 152 | 153 | // get system attrs (android:textSize and android:textColor) 154 | 155 | TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); 156 | 157 | tabTextSize = a.getDimensionPixelSize(0, tabTextSize); 158 | tabTextColor = a.getColor(1, tabTextColor); 159 | 160 | a.recycle(); 161 | 162 | // get custom attrs 163 | 164 | 165 | a = context.obtainStyledAttributes(attrs, R.styleable.AdvancedPagerSlidingTabStrip); 166 | 167 | indicatorColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabIndicatorColor, indicatorColor); 168 | underlineColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabUnderlineColor, underlineColor); 169 | dividerColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabDividerColor, dividerColor); 170 | indicatorHeight = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabIndicatorHeight, indicatorHeight); 171 | underlineHeight = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabUnderlineHeight, underlineHeight); 172 | dividerPadding = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabDividerPadding, dividerPadding); 173 | tabPadding = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabPaddingLeftRight, tabPadding); 174 | tabPaddingTopBottom = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabPaddingTopBottom, tabPaddingTopBottom); 175 | tabBackgroundResId = a.getResourceId(R.styleable.AdvancedPagerSlidingTabStrip_apTabBackground, tabBackgroundResId); 176 | shouldExpand = a.getBoolean(R.styleable.AdvancedPagerSlidingTabStrip_apTabShouldExpand, shouldExpand); 177 | scrollOffset = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabScrollOffset, scrollOffset); 178 | textAllCaps = a.getBoolean(R.styleable.AdvancedPagerSlidingTabStrip_apTabTextAllCaps, textAllCaps); 179 | tabTextSelectColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabTextSelectColor, dividerColor); 180 | tabDrawMode = a.getInteger(R.styleable.AdvancedPagerSlidingTabStrip_apTabDrawMode,DRAW_MODE_NORMAL); 181 | 182 | a.recycle(); 183 | 184 | rectPaint = new Paint(); 185 | rectPaint.setAntiAlias(true); 186 | rectPaint.setStyle(Style.FILL); 187 | 188 | dividerPaint = new Paint(); 189 | dividerPaint.setAntiAlias(true); 190 | dividerPaint.setStrokeWidth(dividerWidth); 191 | 192 | // defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 193 | expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f); 194 | 195 | if (locale == null) { 196 | locale = getResources().getConfiguration().locale; 197 | } 198 | 199 | if(mViewTabCache == null){ 200 | mViewTabCache = new SparseArray<>(); 201 | } 202 | } 203 | 204 | public void setOnTabClickListener(OnTabClickListener onTabClickListener){ 205 | mOnTabClickListener = onTabClickListener; 206 | } 207 | 208 | public void setViewPager(ViewPager pager) { 209 | this.pager = pager; 210 | 211 | if (pager.getAdapter() == null) { 212 | throw new IllegalStateException("ViewPager does not have adapter instance."); 213 | } 214 | 215 | pager.addOnPageChangeListener(pageListener); 216 | 217 | notifyDataSetChanged(); 218 | } 219 | 220 | public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { 221 | this.delegatePageListener = listener; 222 | } 223 | 224 | public void notifyDataSetChanged() { 225 | 226 | tabsContainer.removeAllViews(); 227 | 228 | tabCount = pager.getAdapter().getCount(); 229 | 230 | for (int i = 0; i < tabCount; i++) { 231 | 232 | if (pager.getAdapter() instanceof IconTabProvider) { 233 | addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIcon(i), pager.getAdapter().getPageTitle(i).toString()); 234 | } else if(pager.getAdapter() instanceof ViewTabProvider){ 235 | addViewTab(i, ((ViewTabProvider) pager.getAdapter()),pager.getAdapter().getPageTitle(i).toString()); 236 | } else { 237 | // addIconTab(i, R.drawable.home_categry_icon_n, pager.getAdapter().getPageTitle(i).toString()); 238 | 239 | addTextTab(i, pager.getAdapter().getPageTitle(i).toString()); 240 | } 241 | 242 | } 243 | 244 | updateTabStyles(); 245 | 246 | checkedTabWidths = false; 247 | 248 | getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 249 | 250 | @SuppressWarnings("deprecation") 251 | @SuppressLint("NewApi") 252 | @Override 253 | public void onGlobalLayout() { 254 | 255 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 256 | getViewTreeObserver().removeGlobalOnLayoutListener(this); 257 | } else { 258 | getViewTreeObserver().removeOnGlobalLayoutListener(this); 259 | } 260 | 261 | currentPosition = pager.getCurrentItem(); 262 | scrollToChild(currentPosition, 0); 263 | } 264 | }); 265 | 266 | pageListener.onPageSelected(0);//default 267 | 268 | } 269 | 270 | private void addTextTab(final int position, String title) { 271 | 272 | RelativeLayout tab = new RelativeLayout(getContext()); 273 | tab.setOnClickListener(new OnClickListener() { 274 | @Override 275 | public void onClick(View v) { 276 | if(mOnTabClickListener != null){ 277 | mOnTabClickListener.onClick(position); 278 | } 279 | scrollToChild(position, 0); 280 | pager.setCurrentItem(position); 281 | } 282 | }); 283 | 284 | TextView txt = new TextView(getContext()); 285 | txt.setText(title); 286 | txt.setFocusable(true); 287 | txt.setGravity(Gravity.CENTER); 288 | txt.setSingleLine(); 289 | txt.setId(R.id.id_tab_txt); 290 | RelativeLayout.LayoutParams txtParams = new RelativeLayout.LayoutParams( 291 | RelativeLayout.LayoutParams.WRAP_CONTENT, 292 | RelativeLayout.LayoutParams.WRAP_CONTENT); 293 | txtParams.addRule(RelativeLayout.CENTER_IN_PARENT); 294 | if(pager.getAdapter() instanceof LayoutProvider){ 295 | LayoutProvider layoutProvider = (LayoutProvider)pager.getAdapter(); 296 | for(Integer rule : layoutProvider.getPageRule(position)){ 297 | txtParams.addRule(rule); 298 | } 299 | Margins margins = layoutProvider.getPageMargins(position); 300 | if(margins != null) { 301 | txtParams.setMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom); 302 | } 303 | } 304 | // txtParams.addRule(RelativeLayout.CENTER_IN_PARENT); 305 | txt.setLayoutParams(txtParams); 306 | 307 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(getResources().getDimensionPixelSize(R.dimen.psts_dot_wh), getResources().getDimensionPixelSize(R.dimen.psts_dot_wh)); 308 | TextView dot = new TextView(getContext()); 309 | dot.setTextColor(Color.WHITE); 310 | dot.setBackgroundColor(Color.BLUE); 311 | dot.setGravity(Gravity.CENTER); 312 | dot.setSingleLine(); 313 | dot.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.psts_dot_txt_size)); 314 | //16 new 315 | Drawable dot_drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.apsts_tips, null); 316 | 317 | 318 | boolean hasRule = false; 319 | layoutParams.setMargins(0, 0, getResources().getDimensionPixelSize(R.dimen.psts_dot_m_right), 0); 320 | if(pager.getAdapter() instanceof TipsProvider){ 321 | TipsProvider tipsProvider = (TipsProvider)pager.getAdapter(); 322 | for(Integer rule : tipsProvider.getTipsRule(position)){ 323 | layoutParams.addRule(rule); 324 | hasRule = true; 325 | } 326 | Margins margins = tipsProvider.getTipsMargins(position); 327 | if(margins != null) { 328 | layoutParams.setMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom); 329 | } 330 | Drawable drawable = tipsProvider.getTipsDrawable(position); 331 | if(drawable != null){ 332 | dot_drawable = drawable; 333 | 334 | } 335 | } 336 | 337 | if(!hasRule){ 338 | // layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 339 | layoutParams.addRule(RelativeLayout.ALIGN_RIGHT, R.id.id_tab_txt); 340 | layoutParams.addRule(RelativeLayout.ALIGN_TOP, R.id.id_tab_txt); 341 | int halfSize = getResources().getDimensionPixelSize(R.dimen.psts_dot_m_tv_right); 342 | layoutParams.setMargins(0, 0, -halfSize, 0); 343 | } 344 | 345 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 346 | dot.setBackground(dot_drawable); 347 | }else{ 348 | dot.setBackgroundDrawable(dot_drawable); 349 | } 350 | dot.setLayoutParams(layoutParams); 351 | 352 | tab.addView(txt); 353 | tab.addView(dot); 354 | dot.setVisibility(View.GONE); 355 | tabsContainer.addView(tab); 356 | 357 | } 358 | 359 | public void showDot(int index) { 360 | RelativeLayout tab = (RelativeLayout) tabsContainer.getChildAt(index); 361 | TextView dot_layout = (TextView) tab.getChildAt(tab.getChildCount() - 1); 362 | dot_layout.setText(""); 363 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)dot_layout.getLayoutParams(); 364 | layoutParams.width = getResources().getDimensionPixelSize(R.dimen.psts_dot_wh); 365 | layoutParams.height = getResources().getDimensionPixelSize(R.dimen.psts_dot_wh); 366 | 367 | dot_layout.setVisibility(View.VISIBLE); 368 | } 369 | 370 | public void showDot(int index,String dotTxt) { 371 | RelativeLayout tab = (RelativeLayout) tabsContainer.getChildAt(index); 372 | TextView dot_layout = (TextView) tab.getChildAt(tab.getChildCount() - 1); 373 | RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)dot_layout.getLayoutParams(); 374 | layoutParams.width = RelativeLayout.LayoutParams.WRAP_CONTENT; 375 | layoutParams.height = RelativeLayout.LayoutParams.WRAP_CONTENT; 376 | dot_layout.setText(dotTxt); 377 | dot_layout.setVisibility(View.VISIBLE); 378 | } 379 | 380 | public void hideDot(int index) { 381 | RelativeLayout tab = (RelativeLayout) tabsContainer.getChildAt(index); 382 | TextView dot_layout = (TextView) tab.getChildAt(tab.getChildCount() - 1); 383 | dot_layout.setVisibility(View.GONE); 384 | } 385 | 386 | private SparseArray mViewTabCache;//缓存 387 | 388 | private View getTabView(int position){ 389 | return mViewTabCache.get(position); 390 | } 391 | 392 | private void setTabView( int position ,View view){ 393 | mViewTabCache.put(position, view); 394 | } 395 | 396 | private void addViewTab(final int position, ViewTabProvider provider, String title) { 397 | 398 | RelativeLayout tab = new RelativeLayout(getContext()); 399 | tab.setOnClickListener(new OnClickListener() { 400 | @Override 401 | public void onClick(View v) { 402 | if(mOnTabClickListener != null){ 403 | mOnTabClickListener.onClick(position); 404 | } 405 | scrollToChild(position, 0); 406 | pager.setCurrentItem(position); 407 | } 408 | }); 409 | 410 | //文本和图 411 | TextView txt = new TextView(getContext()); 412 | txt.setText(title); 413 | txt.setFocusable(true); 414 | txt.setGravity(Gravity.CENTER); 415 | txt.setSingleLine(); 416 | txt.setId(R.id.id_tab_txt); 417 | RelativeLayout.LayoutParams txtParams = new RelativeLayout.LayoutParams( 418 | RelativeLayout.LayoutParams.WRAP_CONTENT, 419 | RelativeLayout.LayoutParams.WRAP_CONTENT); 420 | txtParams.addRule(RelativeLayout.CENTER_HORIZONTAL); 421 | txtParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 422 | if(pager.getAdapter() instanceof LayoutProvider){ 423 | LayoutProvider layoutProvider = (LayoutProvider)pager.getAdapter(); 424 | for(Integer rule : layoutProvider.getPageRule(position)){ 425 | txtParams.addRule(rule); 426 | } 427 | Margins margins = layoutProvider.getPageMargins(position); 428 | if(margins != null) { 429 | txtParams.setMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom); 430 | } 431 | } 432 | txtParams.addRule(RelativeLayout.CENTER_HORIZONTAL); 433 | txtParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 434 | txt.setLayoutParams(txtParams); 435 | 436 | //使用缓存 437 | View view = provider.onIconView(position, getTabView(position), tab); 438 | setTabView(position, view);//保存view到缓存中 439 | RelativeLayout.LayoutParams viewLayoutParams 440 | = (RelativeLayout.LayoutParams)view.getLayoutParams(); 441 | viewLayoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); 442 | viewLayoutParams.addRule(RelativeLayout.ABOVE, R.id.id_tab_txt); 443 | 444 | 445 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(getResources().getDimensionPixelSize(R.dimen.psts_dot_wh), getResources().getDimensionPixelSize(R.dimen.psts_dot_wh)); 446 | TextView dot = new TextView(getContext()); 447 | dot.setTextColor(Color.WHITE); 448 | dot.setBackgroundColor(Color.BLUE); 449 | dot.setGravity(Gravity.CENTER); 450 | dot.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.psts_dot_txt_size)); 451 | dot.setSingleLine(); 452 | 453 | Drawable dot_drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.apsts_tips, null); 454 | 455 | boolean hasRule = false; 456 | layoutParams.setMargins(0, 0, getResources().getDimensionPixelSize(R.dimen.psts_dot_m_right), 0); 457 | if(pager.getAdapter() instanceof TipsProvider){ 458 | TipsProvider tipsProvider = (TipsProvider)pager.getAdapter(); 459 | for(Integer rule : tipsProvider.getTipsRule(position)){ 460 | layoutParams.addRule(rule); 461 | hasRule = true; 462 | } 463 | Margins margins = tipsProvider.getTipsMargins(position); 464 | if(margins != null) { 465 | layoutParams.setMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom); 466 | } 467 | Drawable drawable = tipsProvider.getTipsDrawable(position); 468 | if(drawable != null){ 469 | dot_drawable = drawable; 470 | 471 | } 472 | } 473 | 474 | if(!hasRule){ 475 | layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 476 | } 477 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 478 | dot.setBackground(dot_drawable); 479 | }else{ 480 | dot.setBackgroundDrawable(dot_drawable); 481 | } 482 | dot.setLayoutParams(layoutParams); 483 | 484 | tab.addView(txt); 485 | tab.addView(view); 486 | tab.addView(dot); 487 | dot.setVisibility(View.GONE); 488 | tabsContainer.addView(tab); 489 | 490 | } 491 | 492 | private void addIconTab(final int position, Object res, String text) { 493 | 494 | RelativeLayout tab = new RelativeLayout(getContext()); 495 | tab.setOnClickListener(new OnClickListener() { 496 | @Override 497 | public void onClick(View v) { 498 | if(mOnTabClickListener != null){ 499 | mOnTabClickListener.onClick(position); 500 | } 501 | scrollToChild(position, 0); 502 | pager.setCurrentItem(position); 503 | } 504 | }); 505 | 506 | //文本和图 507 | TextView txt = new TextView(getContext()); 508 | txt.setText(text); 509 | txt.setFocusable(true); 510 | txt.setGravity(Gravity.CENTER); 511 | txt.setSingleLine(); 512 | txt.setId(R.id.id_tab_txt); 513 | RelativeLayout.LayoutParams txtParams = new RelativeLayout.LayoutParams( 514 | RelativeLayout.LayoutParams.WRAP_CONTENT, 515 | RelativeLayout.LayoutParams.WRAP_CONTENT); 516 | txtParams.addRule(RelativeLayout.CENTER_IN_PARENT); 517 | if(pager.getAdapter() instanceof LayoutProvider){ 518 | LayoutProvider layoutProvider = (LayoutProvider)pager.getAdapter(); 519 | for(Integer rule : layoutProvider.getPageRule(position)){ 520 | txtParams.addRule(rule); 521 | 522 | } 523 | Margins margins = layoutProvider.getPageMargins(position); 524 | if(margins != null) { 525 | txtParams.setMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom); 526 | } 527 | } 528 | // txtParams.addRule(RelativeLayout.CENTER_IN_PARENT); 529 | txt.setLayoutParams(txtParams); 530 | 531 | setViewResource(position,res, txt); 532 | 533 | RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(getResources().getDimensionPixelSize(R.dimen.psts_dot_wh), getResources().getDimensionPixelSize(R.dimen.psts_dot_wh)); 534 | TextView dot = new TextView(getContext()); 535 | dot.setTextColor(Color.WHITE); 536 | dot.setBackgroundColor(Color.BLUE); 537 | dot.setGravity(Gravity.CENTER); 538 | dot.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.psts_dot_txt_size)); 539 | dot.setSingleLine(); 540 | Drawable dot_drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.apsts_tips, null); 541 | 542 | boolean hasRule = false; 543 | layoutParams.setMargins(0, 0, getResources().getDimensionPixelSize(R.dimen.psts_dot_m_right), 0); 544 | if(pager.getAdapter() instanceof TipsProvider){ 545 | TipsProvider tipsProvider = (TipsProvider)pager.getAdapter(); 546 | for(Integer rule : tipsProvider.getTipsRule(position)){ 547 | layoutParams.addRule(rule); 548 | hasRule = true; 549 | } 550 | Margins margins = tipsProvider.getTipsMargins(position); 551 | if(margins != null) { 552 | layoutParams.setMargins(margins.mLeft, margins.mTop, margins.mRight, margins.mBottom); 553 | } 554 | Drawable drawable = tipsProvider.getTipsDrawable(position); 555 | if(drawable != null){ 556 | dot_drawable = drawable; 557 | 558 | } 559 | } 560 | 561 | if(!hasRule){ 562 | layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); 563 | } 564 | 565 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 566 | dot.setBackground(dot_drawable); 567 | }else{ 568 | dot.setBackgroundDrawable(dot_drawable); 569 | } 570 | dot.setLayoutParams(layoutParams); 571 | 572 | tab.addView(txt); 573 | tab.addView(dot); 574 | dot.setVisibility(View.GONE); 575 | tabsContainer.addView(tab); 576 | 577 | } 578 | 579 | public View getTabAt(int pos) { 580 | if (pos >= tabsContainer.getChildCount()) { 581 | throw new IllegalStateException("pos is too big."); 582 | } 583 | return tabsContainer.getChildAt(pos); 584 | } 585 | 586 | private void updateTabStyles() { 587 | 588 | for (int i = 0; i < tabCount; i++) { 589 | 590 | View v = tabsContainer.getChildAt(i); 591 | 592 | //v.setLayoutParams(defaultTabLayoutParams); 593 | //my modify 594 | v.setLayoutParams(expandedTabLayoutParams); 595 | v.setBackgroundResource(tabBackgroundResId); 596 | if (shouldExpand) { 597 | v.setPadding(0, 0, 0, 0); 598 | } else { 599 | v.setPadding(tabPadding, tabPaddingTopBottom, tabPadding, tabPaddingTopBottom); 600 | } 601 | 602 | if (v instanceof RelativeLayout) { 603 | 604 | RelativeLayout tab = (RelativeLayout) v; 605 | TextView tv = (TextView)tab.getChildAt(0); 606 | tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); 607 | tv.setTypeface(tabTypeface, tabTypefaceStyle); 608 | tv.setTextColor(tabTextColor); 609 | 610 | // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a 611 | // pre-ICS-build 612 | if (textAllCaps) { 613 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 614 | tv.setAllCaps(true); 615 | } else { 616 | tv.setText(tv.getText().toString().toUpperCase(locale)); 617 | } 618 | } 619 | } 620 | } 621 | 622 | } 623 | 624 | public boolean setTabLayoutParams(){ 625 | if(pager.getAdapter() instanceof LayoutProvider){ 626 | LayoutProvider weightProvider = (LayoutProvider)pager.getAdapter(); 627 | if(weightProvider == null){ 628 | return false; 629 | } 630 | for (int i = 0; i < tabCount; i++) { 631 | float weight = weightProvider.getPageWeight(i); 632 | if(weight != 0.0f){ 633 | LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, weight == 0.0f ? 1.0f : weight); 634 | tabsContainer.getChildAt(i).setLayoutParams(layoutParams); 635 | }else{ 636 | tabsContainer.getChildAt(i).setLayoutParams(expandedTabLayoutParams); 637 | } 638 | 639 | } 640 | } 641 | return false; 642 | } 643 | 644 | @Override 645 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 646 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 647 | 648 | if (!shouldExpand || MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED) { 649 | setTabLayoutParams(); 650 | return; 651 | } 652 | 653 | int myWidth = getMeasuredWidth(); 654 | int childWidth = 0; 655 | for (int i = 0; i < tabCount; i++) { 656 | childWidth += tabsContainer.getChildAt(i).getMeasuredWidth(); 657 | } 658 | 659 | if (!checkedTabWidths && childWidth > 0 && myWidth > 0) { 660 | 661 | if (childWidth <= myWidth) { 662 | if(!setTabLayoutParams()){ 663 | for (int i = 0; i < tabCount; i++) { 664 | tabsContainer.getChildAt(i).setLayoutParams(expandedTabLayoutParams); 665 | } 666 | } 667 | } 668 | 669 | checkedTabWidths = true; 670 | } 671 | } 672 | 673 | private void scrollToChild(int position, int offset) { 674 | 675 | if (tabCount == 0) { 676 | return; 677 | } 678 | 679 | int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; 680 | 681 | if (position > 0 || offset > 0) { 682 | newScrollX -= scrollOffset; 683 | } 684 | 685 | if (newScrollX != lastScrollX) { 686 | lastScrollX = newScrollX; 687 | scrollTo(newScrollX, 0); 688 | } 689 | 690 | } 691 | 692 | @Override 693 | protected void onDraw(Canvas canvas) { 694 | super.onDraw(canvas); 695 | 696 | if (isInEditMode() || tabCount == 0) { 697 | return; 698 | } 699 | 700 | if(tabDrawMode == DRAW_MODE_NORMAL) { 701 | drawTabNormalMode(canvas); 702 | }else { 703 | drawTabTextMode(canvas); 704 | } 705 | } 706 | 707 | private void drawTabNormalMode(Canvas canvas){ 708 | final int height = getHeight(); 709 | 710 | // 设置提示下划线的颜色 711 | 712 | rectPaint.setColor(indicatorColor); 713 | 714 | View currentTab = tabsContainer.getChildAt(currentPosition); 715 | float lineLeft = currentTab.getLeft(); 716 | float lineRight = currentTab.getRight(); 717 | 718 | if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { 719 | 720 | View nextTab = tabsContainer.getChildAt(currentPosition + 1); 721 | final float nextTabLeft = nextTab.getLeft(); 722 | final float nextTabRight = nextTab.getRight(); 723 | 724 | lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); 725 | lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); 726 | 727 | } 728 | 729 | //绘制提示下划线 730 | canvas.drawRect(lineLeft , height - indicatorHeight, lineRight , height, rectPaint); 731 | 732 | // 绘制下划线 733 | 734 | rectPaint.setColor(underlineColor); 735 | canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); 736 | 737 | // 绘制分割线 738 | 739 | dividerPaint.setColor(dividerColor); 740 | for (int i = 0; i < tabCount - 1; i++) { 741 | View tab = tabsContainer.getChildAt(i); 742 | canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); 743 | } 744 | } 745 | 746 | private void drawTabTextMode(Canvas canvas){ 747 | 748 | final int height = getHeight(); 749 | 750 | // 设置提示下划线的颜色 751 | 752 | rectPaint.setColor(indicatorColor); 753 | 754 | View currentTab = tabsContainer.getChildAt(currentPosition); 755 | float lineLeft = currentTab.getLeft(); 756 | 757 | View currentTextView = ((RelativeLayout)currentTab).getChildAt(0); 758 | float currentTextViewLeft = currentTextView.getLeft(); 759 | float currentTextViewRight = currentTextView.getRight(); 760 | 761 | // if there is an offset, start interpolating left and right coordinates between current and next tab 762 | if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { 763 | 764 | View nextTab = tabsContainer.getChildAt(currentPosition + 1); 765 | final float nextTabLeft = nextTab.getLeft(); 766 | 767 | lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); 768 | 769 | View nextTextView = ((RelativeLayout)nextTab).getChildAt(0); 770 | float nextTextViewLeft = nextTextView.getLeft(); 771 | float nextTextViewRight = nextTextView.getRight(); 772 | 773 | currentTextViewLeft = (currentPositionOffset * nextTextViewLeft + (1f - currentPositionOffset) * currentTextViewLeft); 774 | currentTextViewRight = (currentPositionOffset * nextTextViewRight + (1f - currentPositionOffset) * currentTextViewRight); 775 | } 776 | 777 | //绘制提示下划线 778 | float r = ((float)indicatorHeight) / 2; 779 | canvas.drawCircle(lineLeft + currentTextViewLeft + r,height - indicatorHeight + r,r,rectPaint); 780 | canvas.drawCircle(lineLeft + currentTextViewRight - r,height - indicatorHeight + r,r,rectPaint); 781 | 782 | canvas.drawRect(lineLeft + currentTextViewLeft + r, height - indicatorHeight, lineLeft + currentTextViewRight-r , height, rectPaint); 783 | 784 | // 分割线paint 785 | 786 | dividerPaint.setColor(dividerColor); 787 | 788 | // 下划线paint 789 | rectPaint.setColor(underlineColor); 790 | 791 | for (int i = 0; i < tabCount; i++) { 792 | View tab = tabsContainer.getChildAt(i); 793 | //绘制分割线 794 | if(i < tabCount - 1) { 795 | canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); 796 | } 797 | View tabTextView = ((RelativeLayout)tab).getChildAt(0); 798 | canvas.drawRect(tab.getLeft() + tabTextView.getLeft(), height - underlineHeight, tab.getLeft() + tabTextView.getRight(), height, rectPaint); 799 | } 800 | } 801 | 802 | private class PageListener implements ViewPager.OnPageChangeListener { 803 | 804 | @Override 805 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 806 | 807 | currentPosition = position; 808 | currentPositionOffset = positionOffset; 809 | 810 | if (tabsContainer != null && tabsContainer.getChildAt(position) != null) { 811 | scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth())); 812 | } 813 | 814 | invalidate(); 815 | 816 | if (delegatePageListener != null) { 817 | delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 818 | } 819 | } 820 | 821 | @Override 822 | public void onPageScrollStateChanged(int state) { 823 | if (state == ViewPager.SCROLL_STATE_IDLE) { 824 | scrollToChild(pager.getCurrentItem(), 0); 825 | } 826 | 827 | if (delegatePageListener != null) { 828 | delegatePageListener.onPageScrollStateChanged(state); 829 | } 830 | } 831 | 832 | @Override 833 | public void onPageSelected(int position) { 834 | 835 | setSelectItem(position); 836 | 837 | if (delegatePageListener != null) { 838 | delegatePageListener.onPageSelected(position); 839 | } 840 | } 841 | 842 | } 843 | 844 | private void setViewResource(int position ,Object obj , TextView view){ 845 | IconTabProvider iconTabProvider = (IconTabProvider)pager.getAdapter(); 846 | Rect rect = iconTabProvider.getPageIconBounds(position); 847 | Drawable drawable = null; 848 | if(obj instanceof Integer) { 849 | int resId = (int) obj; 850 | if (resId != 0) { 851 | drawable = ResourcesCompat.getDrawable(getResources(),resId,null); 852 | } 853 | }else if(obj instanceof Bitmap){ 854 | Bitmap bitmap = (Bitmap) obj; 855 | if (bitmap != null) { 856 | drawable = new BitmapDrawable(getResources(),bitmap); 857 | } 858 | }else if(obj instanceof Drawable){ 859 | drawable = (Drawable) obj; 860 | 861 | } 862 | 863 | if (drawable != null) { 864 | if(rect != null){ 865 | drawable.setBounds(rect); 866 | view.setCompoundDrawables(null, drawable, null, null); 867 | }else{ 868 | view.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null); 869 | } 870 | } 871 | } 872 | 873 | public void setSelectItem(int position){ 874 | for (int i = 0; i < tabsContainer.getChildCount(); i++) { 875 | RelativeLayout linearLayout = ((RelativeLayout) tabsContainer.getChildAt(i)); 876 | if (i == position) { 877 | ((TextView) linearLayout.getChildAt(0)).setTextColor(tabTextSelectColor); 878 | if (pager.getAdapter() instanceof IconTabProvider) { 879 | Object obj = ((IconTabProvider) pager.getAdapter()).getPageSelectIcon(i); 880 | setViewResource(position, obj, (TextView) linearLayout.getChildAt(0)); 881 | // ().setCompoundDrawablesWithIntrinsicBounds(0, ((IconTabProvider) pager.getAdapter()).getPageIconSelectResId(i), 0, 0); 882 | }else if(pager.getAdapter() instanceof ViewTabProvider){ 883 | View view = ((ViewTabProvider) pager.getAdapter()).onSelectIconView(i,getTabView(i),linearLayout); 884 | setTabView(i,view); 885 | } 886 | // ((TextView) linearLayout.getChildAt(0)).setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.home_categry_icon_f_n, 0, 0); 887 | } else { 888 | ((TextView) linearLayout.getChildAt(0)).setTextColor(tabTextColor); 889 | if (pager.getAdapter() instanceof IconTabProvider) { 890 | Object obj = ((IconTabProvider) pager.getAdapter()).getPageIcon(i); 891 | setViewResource(position, obj, (TextView) linearLayout.getChildAt(0)); 892 | // ((TextView) linearLayout.getChildAt(0)).setCompoundDrawablesWithIntrinsicBounds(0, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i), 0, 0); 893 | }else if(pager.getAdapter() instanceof ViewTabProvider){ 894 | View view = ((ViewTabProvider) pager.getAdapter()).onIconView(i, getTabView(i), linearLayout); 895 | setTabView(i,view); 896 | } 897 | // ((TextView) linearLayout.getChildAt(0)).setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.home_categry_icon_n, 0, 0); 898 | 899 | } 900 | } 901 | } 902 | 903 | public void setIndicatorColor(int indicatorColor) { 904 | this.indicatorColor = indicatorColor; 905 | invalidate(); 906 | } 907 | 908 | public void setIndicatorColorResource(int resId) { 909 | this.indicatorColor = getResources().getColor(resId); 910 | invalidate(); 911 | } 912 | 913 | public int getIndicatorColor() { 914 | return this.indicatorColor; 915 | } 916 | 917 | public void setIndicatorHeight(int indicatorLineHeightPx) { 918 | this.indicatorHeight = indicatorLineHeightPx; 919 | invalidate(); 920 | } 921 | 922 | public int getIndicatorHeight() { 923 | return indicatorHeight; 924 | } 925 | 926 | public void setUnderlineColor(int underlineColor) { 927 | this.underlineColor = underlineColor; 928 | invalidate(); 929 | } 930 | 931 | public void setUnderlineColorResource(int resId) { 932 | this.underlineColor = getResources().getColor(resId); 933 | invalidate(); 934 | } 935 | 936 | public int getUnderlineColor() { 937 | return underlineColor; 938 | } 939 | 940 | public void setDividerColor(int dividerColor) { 941 | this.dividerColor = dividerColor; 942 | invalidate(); 943 | } 944 | 945 | public void setDividerColorResource(int resId) { 946 | this.dividerColor = getResources().getColor(resId); 947 | invalidate(); 948 | } 949 | 950 | public int getDividerColor() { 951 | return dividerColor; 952 | } 953 | 954 | public void setUnderlineHeight(int underlineHeightPx) { 955 | this.underlineHeight = underlineHeightPx; 956 | invalidate(); 957 | } 958 | 959 | public int getUnderlineHeight() { 960 | return underlineHeight; 961 | } 962 | 963 | public void setDividerPadding(int dividerPaddingPx) { 964 | this.dividerPadding = dividerPaddingPx; 965 | invalidate(); 966 | } 967 | 968 | public int getDividerPadding() { 969 | return dividerPadding; 970 | } 971 | 972 | public void setScrollOffset(int scrollOffsetPx) { 973 | this.scrollOffset = scrollOffsetPx; 974 | invalidate(); 975 | } 976 | 977 | public int getScrollOffset() { 978 | return scrollOffset; 979 | } 980 | 981 | public void setShouldExpand(boolean shouldExpand) { 982 | this.shouldExpand = shouldExpand; 983 | requestLayout(); 984 | } 985 | 986 | public boolean getShouldExpand() { 987 | return shouldExpand; 988 | } 989 | 990 | public boolean isTextAllCaps() { 991 | return textAllCaps; 992 | } 993 | 994 | public void setAllCaps(boolean textAllCaps) { 995 | this.textAllCaps = textAllCaps; 996 | } 997 | 998 | public void setTextSize(int textSizePx) { 999 | this.tabTextSize = textSizePx; 1000 | updateTabStyles(); 1001 | } 1002 | 1003 | public int getTextSize() { 1004 | return tabTextSize; 1005 | } 1006 | 1007 | public void setTextColor(int textColor) { 1008 | this.tabTextColor = textColor; 1009 | updateTabStyles(); 1010 | } 1011 | 1012 | public void setTextColorResource(int resId) { 1013 | this.tabTextColor = getResources().getColor(resId); 1014 | updateTabStyles(); 1015 | } 1016 | 1017 | public int getTextColor() { 1018 | return tabTextColor; 1019 | } 1020 | 1021 | public void setTypeface(Typeface typeface, int style) { 1022 | this.tabTypeface = typeface; 1023 | this.tabTypefaceStyle = style; 1024 | updateTabStyles(); 1025 | } 1026 | 1027 | public void setTabBackground(int resId) { 1028 | this.tabBackgroundResId = resId; 1029 | } 1030 | 1031 | public int getTabBackground() { 1032 | return tabBackgroundResId; 1033 | } 1034 | 1035 | public void setTabPaddingLeftRight(int paddingPx) { 1036 | this.tabPadding = paddingPx; 1037 | updateTabStyles(); 1038 | } 1039 | 1040 | public int getTabPaddingLeftRight() { 1041 | return tabPadding; 1042 | } 1043 | 1044 | @Override 1045 | public void onRestoreInstanceState(Parcelable state) { 1046 | SavedState savedState = (SavedState) state; 1047 | super.onRestoreInstanceState(savedState.getSuperState()); 1048 | currentPosition = savedState.currentPosition; 1049 | requestLayout(); 1050 | } 1051 | 1052 | @Override 1053 | public Parcelable onSaveInstanceState() { 1054 | Parcelable superState = super.onSaveInstanceState(); 1055 | SavedState savedState = new SavedState(superState); 1056 | savedState.currentPosition = currentPosition; 1057 | return savedState; 1058 | } 1059 | 1060 | static class SavedState extends BaseSavedState { 1061 | int currentPosition; 1062 | 1063 | public SavedState(Parcelable superState) { 1064 | super(superState); 1065 | } 1066 | 1067 | private SavedState(Parcel in) { 1068 | super(in); 1069 | currentPosition = in.readInt(); 1070 | } 1071 | 1072 | @Override 1073 | public void writeToParcel(Parcel dest, int flags) { 1074 | super.writeToParcel(dest, flags); 1075 | dest.writeInt(currentPosition); 1076 | } 1077 | 1078 | public static final Creator CREATOR = new Creator() { 1079 | @Override 1080 | public SavedState createFromParcel(Parcel in) { 1081 | return new SavedState(in); 1082 | } 1083 | 1084 | @Override 1085 | public SavedState[] newArray(int size) { 1086 | return new SavedState[size]; 1087 | } 1088 | }; 1089 | } 1090 | 1091 | } 1092 | -------------------------------------------------------------------------------- /Library/src/com/lhh/apst/library/CustomPagerSlidingTabStrip.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.library; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.graphics.Canvas; 7 | import android.graphics.Paint; 8 | import android.graphics.Paint.Style; 9 | import android.os.Build; 10 | import android.os.Parcel; 11 | import android.os.Parcelable; 12 | import android.support.v4.view.ViewPager; 13 | import android.util.AttributeSet; 14 | import android.util.DisplayMetrics; 15 | import android.util.SparseArray; 16 | import android.util.TypedValue; 17 | import android.view.View; 18 | import android.view.ViewTreeObserver.OnGlobalLayoutListener; 19 | import android.widget.HorizontalScrollView; 20 | import android.widget.LinearLayout; 21 | 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.Locale; 25 | 26 | /** 27 | * Created by linhomhom on 2015/9/22. 28 | */ 29 | public class CustomPagerSlidingTabStrip extends HorizontalScrollView { 30 | 31 | public interface CustomTabProvider{ 32 | public View getSelectTabView(int position, View convertView); 33 | public View getDisSelectTabView(int position, View convertView); 34 | } 35 | // @formatter:on 36 | 37 | private LinearLayout.LayoutParams defaultTabLayoutParams; 38 | private LinearLayout.LayoutParams expandedTabLayoutParams; 39 | 40 | private final PageListener pageListener = new PageListener(); 41 | public ViewPager.OnPageChangeListener delegatePageListener; 42 | 43 | private LinearLayout tabsContainer; 44 | private ViewPager pager; 45 | 46 | private int tabCount; 47 | 48 | private int currentPosition = 0; 49 | private float currentPositionOffset = 0f; 50 | 51 | private Paint rectPaint; 52 | private Paint dividerPaint; 53 | 54 | private boolean checkedTabWidths = false; 55 | 56 | private int indicatorColor = 0xFF666666; 57 | private int underlineColor = 0x1A000000; 58 | private int dividerColor = 0x1A000000; 59 | 60 | private boolean shouldExpand = true; 61 | 62 | private int scrollOffset = 52; 63 | private int indicatorHeight = 3; 64 | private int underlineHeight = 2; 65 | private int dividerPadding = 12; 66 | private int tabPadding = 24; 67 | private int tabPaddingTopBottom = 0; 68 | private int dividerWidth = 1; 69 | 70 | private int lastScrollX = 0; 71 | 72 | private int tabBackgroundResId = R.drawable.psts_background_tab; 73 | // private int tabBackgroundResId; 74 | 75 | private Locale locale; 76 | private OnTabClickListener mOnTabClickListener; 77 | public interface OnTabClickListener{ 78 | public void onClick(int pos); 79 | } 80 | 81 | public CustomPagerSlidingTabStrip(Context context) { 82 | this(context, null); 83 | } 84 | 85 | public CustomPagerSlidingTabStrip(Context context, AttributeSet attrs) { 86 | this(context, attrs, 0); 87 | } 88 | 89 | public CustomPagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) { 90 | super(context, attrs, defStyle); 91 | 92 | setFillViewport(true); 93 | setWillNotDraw(false); 94 | 95 | tabsContainer = new LinearLayout(context); 96 | tabsContainer.setOrientation(LinearLayout.HORIZONTAL); 97 | tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 98 | addView(tabsContainer); 99 | 100 | DisplayMetrics dm = getResources().getDisplayMetrics(); 101 | 102 | scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm); 103 | indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm); 104 | underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm); 105 | dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm); 106 | tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm); 107 | dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm); 108 | 109 | // get system attrs (android:textSize and android:textColor) 110 | 111 | TypedArray a = null; 112 | 113 | // get custom attrs 114 | 115 | 116 | a = context.obtainStyledAttributes(attrs, R.styleable.AdvancedPagerSlidingTabStrip); 117 | 118 | indicatorColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabIndicatorColor, indicatorColor); 119 | underlineColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabUnderlineColor, underlineColor); 120 | dividerColor = a.getColor(R.styleable.AdvancedPagerSlidingTabStrip_apTabDividerColor, dividerColor); 121 | indicatorHeight = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabIndicatorHeight, indicatorHeight); 122 | underlineHeight = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabUnderlineHeight, underlineHeight); 123 | dividerPadding = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabDividerPadding, dividerPadding); 124 | tabPadding = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabPaddingLeftRight, tabPadding); 125 | tabPaddingTopBottom = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabPaddingTopBottom, tabPaddingTopBottom); 126 | tabBackgroundResId = a.getResourceId(R.styleable.AdvancedPagerSlidingTabStrip_apTabBackground, tabBackgroundResId); 127 | shouldExpand = a.getBoolean(R.styleable.AdvancedPagerSlidingTabStrip_apTabShouldExpand, shouldExpand); 128 | scrollOffset = a.getDimensionPixelSize(R.styleable.AdvancedPagerSlidingTabStrip_apTabScrollOffset, scrollOffset); 129 | 130 | a.recycle(); 131 | 132 | rectPaint = new Paint(); 133 | rectPaint.setAntiAlias(true); 134 | rectPaint.setStyle(Style.FILL); 135 | 136 | dividerPaint = new Paint(); 137 | dividerPaint.setAntiAlias(true); 138 | dividerPaint.setStrokeWidth(dividerWidth); 139 | 140 | defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); 141 | expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f); 142 | 143 | if (locale == null) { 144 | locale = getResources().getConfiguration().locale; 145 | } 146 | 147 | if(mDisSelectTabViewCache == null){ 148 | mDisSelectTabViewCache = new SparseArray<>(); 149 | } 150 | if(mSelectTabViewCache == null){ 151 | mSelectTabViewCache = new SparseArray<>(); 152 | } 153 | } 154 | 155 | public void setOnTabClickListener(OnTabClickListener onTabClickListener){ 156 | mOnTabClickListener = onTabClickListener; 157 | } 158 | 159 | public void setViewPager(ViewPager pager) { 160 | this.pager = pager; 161 | 162 | if (pager.getAdapter() == null) { 163 | throw new IllegalStateException("ViewPager does not have adapter instance."); 164 | } 165 | 166 | pager.addOnPageChangeListener(pageListener); 167 | 168 | notifyDataSetChanged(); 169 | } 170 | 171 | public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { 172 | this.delegatePageListener = listener; 173 | } 174 | 175 | public void notifyDataSetChanged() { 176 | 177 | tabsContainer.removeAllViews(); 178 | 179 | tabCount = pager.getAdapter().getCount(); 180 | 181 | for (int i = 0; i < tabCount; i++) { 182 | 183 | if (pager.getAdapter() instanceof CustomTabProvider) { 184 | View view = ((CustomTabProvider) pager.getAdapter()).getSelectTabView(i, getSelectTabView(i)); 185 | setSelectTabView(i, view); 186 | updateViewStyle(view); 187 | addTab(i, view); 188 | } 189 | 190 | } 191 | 192 | // updateTabStyles(); 193 | 194 | checkedTabWidths = false; 195 | 196 | getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 197 | 198 | @SuppressWarnings("deprecation") 199 | @SuppressLint("NewApi") 200 | @Override 201 | public void onGlobalLayout() { 202 | 203 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 204 | getViewTreeObserver().removeGlobalOnLayoutListener(this); 205 | } else { 206 | getViewTreeObserver().removeOnGlobalLayoutListener(this); 207 | } 208 | 209 | currentPosition = pager.getCurrentItem(); 210 | scrollToChild(currentPosition, 0); 211 | } 212 | }); 213 | 214 | pageListener.onPageSelected(0);//default 215 | 216 | } 217 | 218 | private PageOnClickListener mPageOnClickListener; 219 | 220 | private void addTab(final int position, View view){ 221 | if(mPageOnClickListener == null){ 222 | mPageOnClickListener = new PageOnClickListener(); 223 | } 224 | view.setTag(R.id.tag_position, position); 225 | view.setOnClickListener(mPageOnClickListener); 226 | tabsContainer.addView(view); 227 | } 228 | 229 | public View getTabAt(int pos) { 230 | if (pos >= tabsContainer.getChildCount()) { 231 | throw new IllegalStateException("pos is too big."); 232 | } 233 | return tabsContainer.getChildAt(pos); 234 | } 235 | 236 | private void updateTabStyles() { 237 | 238 | for (int i = 0; i < tabCount; i++) { 239 | 240 | View v = tabsContainer.getChildAt(i); 241 | 242 | //v.setLayoutParams(defaultTabLayoutParams); 243 | //my modify 244 | updateViewStyle(v); 245 | } 246 | 247 | } 248 | 249 | public void updateViewStyle(View v){ 250 | v.setLayoutParams(expandedTabLayoutParams); 251 | v.setBackgroundResource(tabBackgroundResId); 252 | if (shouldExpand) { 253 | v.setPadding(0, 0, 0, 0); 254 | } else { 255 | v.setPadding(tabPadding, tabPaddingTopBottom, tabPadding, tabPaddingTopBottom); 256 | } 257 | } 258 | 259 | @Override 260 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 261 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 262 | 263 | if (!shouldExpand || MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED) { 264 | return; 265 | } 266 | 267 | int myWidth = getMeasuredWidth(); 268 | int childWidth = 0; 269 | for (int i = 0; i < tabCount; i++) { 270 | childWidth += tabsContainer.getChildAt(i).getMeasuredWidth(); 271 | } 272 | 273 | if (!checkedTabWidths && childWidth > 0 && myWidth > 0) { 274 | 275 | if (childWidth <= myWidth) { 276 | for (int i = 0; i < tabCount; i++) { 277 | tabsContainer.getChildAt(i).setLayoutParams(expandedTabLayoutParams); 278 | } 279 | } 280 | 281 | checkedTabWidths = true; 282 | } 283 | } 284 | 285 | private void scrollToChild(int position, int offset) { 286 | 287 | if (tabCount == 0) { 288 | return; 289 | } 290 | 291 | int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; 292 | 293 | if (position > 0 || offset > 0) { 294 | newScrollX -= scrollOffset; 295 | } 296 | 297 | if (newScrollX != lastScrollX) { 298 | lastScrollX = newScrollX; 299 | scrollTo(newScrollX, 0); 300 | } 301 | 302 | } 303 | 304 | @Override 305 | protected void onDraw(Canvas canvas) { 306 | super.onDraw(canvas); 307 | 308 | if (isInEditMode() || tabCount == 0) { 309 | return; 310 | } 311 | 312 | drawTabNormalMode(canvas); 313 | } 314 | 315 | private void drawTabNormalMode(Canvas canvas){ 316 | final int height = getHeight(); 317 | 318 | // 设置提示下划线的颜色 319 | 320 | rectPaint.setColor(indicatorColor); 321 | 322 | // default: line below current tab 323 | View currentTab = tabsContainer.getChildAt(currentPosition); 324 | float lineLeft = currentTab.getLeft(); 325 | float lineRight = currentTab.getRight(); 326 | 327 | // if there is an offset, start interpolating left and right coordinates between current and next tab 328 | if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { 329 | 330 | View nextTab = tabsContainer.getChildAt(currentPosition + 1); 331 | final float nextTabLeft = nextTab.getLeft(); 332 | final float nextTabRight = nextTab.getRight(); 333 | 334 | lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); 335 | lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); 336 | 337 | } 338 | 339 | //绘制提示下划线 340 | canvas.drawRect(lineLeft , height - indicatorHeight, lineRight , height, rectPaint); 341 | 342 | // 绘制下划线 343 | 344 | rectPaint.setColor(underlineColor); 345 | canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); 346 | 347 | // 绘制分割线 348 | 349 | dividerPaint.setColor(dividerColor); 350 | 351 | for (int i = 0; i < tabCount - 1; i++) { 352 | View tab = tabsContainer.getChildAt(i); 353 | canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint); 354 | } 355 | } 356 | 357 | private class PageListener implements ViewPager.OnPageChangeListener { 358 | 359 | @Override 360 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 361 | 362 | currentPosition = position; 363 | currentPositionOffset = positionOffset; 364 | 365 | scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth())); 366 | 367 | invalidate(); 368 | 369 | if (delegatePageListener != null) { 370 | delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 371 | } 372 | } 373 | 374 | @Override 375 | public void onPageScrollStateChanged(int state) { 376 | if (state == ViewPager.SCROLL_STATE_IDLE) { 377 | scrollToChild(pager.getCurrentItem(), 0); 378 | } 379 | 380 | if (delegatePageListener != null) { 381 | delegatePageListener.onPageScrollStateChanged(state); 382 | } 383 | } 384 | 385 | @Override 386 | public void onPageSelected(int position) { 387 | 388 | setSelectItem(position); 389 | 390 | if (delegatePageListener != null) { 391 | delegatePageListener.onPageSelected(position); 392 | } 393 | } 394 | 395 | } 396 | 397 | private SparseArray mDisSelectTabViewCache;//缓存 398 | 399 | private View getDisSelectTabView(int position){ 400 | return mDisSelectTabViewCache.get(position); 401 | } 402 | 403 | private void setDisSelectTabView(int position , View view){ 404 | mDisSelectTabViewCache.put(position,view); 405 | } 406 | 407 | private SparseArray mSelectTabViewCache;//缓存 408 | 409 | private View getSelectTabView(int position){ 410 | return mSelectTabViewCache.get(position); 411 | } 412 | 413 | private void setSelectTabView( int position ,View view){ 414 | mSelectTabViewCache.put(position,view); 415 | } 416 | 417 | class PageOnClickListener implements View.OnClickListener{ 418 | 419 | @Override 420 | public void onClick(View view) { 421 | int tag = (int)view.getTag(R.id.tag_position); 422 | if(mOnTabClickListener != null){ 423 | mOnTabClickListener.onClick(tag); 424 | } 425 | scrollToChild(tag, 0); 426 | pager.setCurrentItem(tag); 427 | } 428 | } 429 | 430 | public void setSelectItem(int position){ 431 | if (!(pager.getAdapter() instanceof CustomTabProvider)) { 432 | return; 433 | } 434 | for (int i = 0; i < tabsContainer.getChildCount(); i++) { 435 | 436 | tabsContainer.removeViewAt(i); 437 | 438 | View view = null; 439 | 440 | if (i == position) { 441 | view = ((CustomTabProvider) pager.getAdapter()).getSelectTabView(i, getSelectTabView(i)); 442 | setSelectTabView(i, view); 443 | 444 | } else { 445 | view = ((CustomTabProvider) pager.getAdapter()).getDisSelectTabView(i, getDisSelectTabView(i)); 446 | setDisSelectTabView(i, view); 447 | } 448 | 449 | view.setTag(R.id.tag_position, i); 450 | 451 | if(mPageOnClickListener == null){ 452 | mPageOnClickListener = new PageOnClickListener(); 453 | } 454 | 455 | view.setOnClickListener(mPageOnClickListener); 456 | 457 | tabsContainer.addView(view, i); 458 | 459 | updateViewStyle(view); 460 | } 461 | } 462 | 463 | public void setIndicatorColor(int indicatorColor) { 464 | this.indicatorColor = indicatorColor; 465 | invalidate(); 466 | } 467 | 468 | public void setIndicatorColorResource(int resId) { 469 | this.indicatorColor = getResources().getColor(resId); 470 | invalidate(); 471 | } 472 | 473 | public int getIndicatorColor() { 474 | return this.indicatorColor; 475 | } 476 | 477 | public void setIndicatorHeight(int indicatorLineHeightPx) { 478 | this.indicatorHeight = indicatorLineHeightPx; 479 | invalidate(); 480 | } 481 | 482 | public int getIndicatorHeight() { 483 | return indicatorHeight; 484 | } 485 | 486 | public void setUnderlineColor(int underlineColor) { 487 | this.underlineColor = underlineColor; 488 | invalidate(); 489 | } 490 | 491 | public void setUnderlineColorResource(int resId) { 492 | this.underlineColor = getResources().getColor(resId); 493 | invalidate(); 494 | } 495 | 496 | public int getUnderlineColor() { 497 | return underlineColor; 498 | } 499 | 500 | public void setDividerColor(int dividerColor) { 501 | this.dividerColor = dividerColor; 502 | invalidate(); 503 | } 504 | 505 | public void setDividerColorResource(int resId) { 506 | this.dividerColor = getResources().getColor(resId); 507 | invalidate(); 508 | } 509 | 510 | public int getDividerColor() { 511 | return dividerColor; 512 | } 513 | 514 | public void setUnderlineHeight(int underlineHeightPx) { 515 | this.underlineHeight = underlineHeightPx; 516 | invalidate(); 517 | } 518 | 519 | public int getUnderlineHeight() { 520 | return underlineHeight; 521 | } 522 | 523 | public void setDividerPadding(int dividerPaddingPx) { 524 | this.dividerPadding = dividerPaddingPx; 525 | invalidate(); 526 | } 527 | 528 | public int getDividerPadding() { 529 | return dividerPadding; 530 | } 531 | 532 | public void setScrollOffset(int scrollOffsetPx) { 533 | this.scrollOffset = scrollOffsetPx; 534 | invalidate(); 535 | } 536 | 537 | public int getScrollOffset() { 538 | return scrollOffset; 539 | } 540 | 541 | public void setShouldExpand(boolean shouldExpand) { 542 | this.shouldExpand = shouldExpand; 543 | requestLayout(); 544 | } 545 | 546 | public boolean getShouldExpand() { 547 | return shouldExpand; 548 | } 549 | 550 | public void setTabBackground(int resId) { 551 | this.tabBackgroundResId = resId; 552 | } 553 | 554 | public int getTabBackground() { 555 | return tabBackgroundResId; 556 | } 557 | 558 | public void setTabPaddingLeftRight(int paddingPx) { 559 | this.tabPadding = paddingPx; 560 | updateTabStyles(); 561 | } 562 | 563 | public int getTabPaddingLeftRight() { 564 | return tabPadding; 565 | } 566 | 567 | @Override 568 | public void onRestoreInstanceState(Parcelable state) { 569 | SavedState savedState = (SavedState) state; 570 | super.onRestoreInstanceState(savedState.getSuperState()); 571 | currentPosition = savedState.currentPosition; 572 | requestLayout(); 573 | } 574 | 575 | @Override 576 | public Parcelable onSaveInstanceState() { 577 | Parcelable superState = super.onSaveInstanceState(); 578 | SavedState savedState = new SavedState(superState); 579 | savedState.currentPosition = currentPosition; 580 | return savedState; 581 | } 582 | 583 | static class SavedState extends BaseSavedState { 584 | int currentPosition; 585 | 586 | public SavedState(Parcelable superState) { 587 | super(superState); 588 | } 589 | 590 | private SavedState(Parcel in) { 591 | super(in); 592 | currentPosition = in.readInt(); 593 | } 594 | 595 | @Override 596 | public void writeToParcel(Parcel dest, int flags) { 597 | super.writeToParcel(dest, flags); 598 | dest.writeInt(currentPosition); 599 | } 600 | 601 | public static final Creator CREATOR = new Creator() { 602 | @Override 603 | public SavedState createFromParcel(Parcel in) { 604 | return new SavedState(in); 605 | } 606 | 607 | @Override 608 | public SavedState[] newArray(int size) { 609 | return new SavedState[size]; 610 | } 611 | }; 612 | } 613 | 614 | } 615 | -------------------------------------------------------------------------------- /Library/src/com/lhh/apst/library/Margins.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.library; 2 | 3 | /** 4 | * Created by Linhh on 16/3/8. 5 | */ 6 | public class Margins{ 7 | public int mLeft; 8 | public int mRight; 9 | public int mTop; 10 | public int mBottom; 11 | public Margins(int left, int top, int right, int bottom){ 12 | mLeft = left; 13 | mRight = right; 14 | mTop = top; 15 | mBottom = bottom; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Library/src/com/lhh/apst/library/ViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.library; 2 | 3 | import android.util.SparseArray; 4 | import android.view.View; 5 | 6 | /** 7 | * Created by linhongong on 2015/9/22. 8 | */ 9 | public class ViewHolder { 10 | 11 | public static T get(View view, int id) { 12 | @SuppressWarnings("unchecked") 13 | SparseArray viewHolder = (SparseArray) view.getTag(); 14 | if (viewHolder == null) { 15 | viewHolder = new SparseArray(); 16 | view.setTag(viewHolder); 17 | } 18 | View childView = viewHolder.get(id); 19 | if (childView == null) { 20 | childView = view.findViewById(id); 21 | viewHolder.put(id, childView); 22 | } 23 | return (T) childView; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pic/Screen_20160216163404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/Screen_20160216163404.png -------------------------------------------------------------------------------- /Pic/Screen_20160216163428.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/Screen_20160216163428.png -------------------------------------------------------------------------------- /Pic/Screen_20160216163452.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/Screen_20160216163452.png -------------------------------------------------------------------------------- /Pic/Screen_20160411141706.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/Screen_20160411141706.png -------------------------------------------------------------------------------- /Pic/categry_icon_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/categry_icon_n.png -------------------------------------------------------------------------------- /Pic/categry_icon_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/categry_icon_p.png -------------------------------------------------------------------------------- /Pic/classify_icon_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/classify_icon_n.png -------------------------------------------------------------------------------- /Pic/classify_icon_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/classify_icon_p.png -------------------------------------------------------------------------------- /Pic/mine_icon_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/mine_icon_n.png -------------------------------------------------------------------------------- /Pic/mine_icon_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/mine_icon_p.png -------------------------------------------------------------------------------- /Pic/update_dynamic_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/update_dynamic_n.png -------------------------------------------------------------------------------- /Pic/update_dynamic_p.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/58f9e598d3248a9d44293ddde4213e2f3e996091/Pic/update_dynamic_p.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android AdvancedPagerSlidingTabStrip 2 | 3 | Android AdvancedPagerSlidingTabStrip是一种Android平台的导航控件,完美兼容Android自带库和兼容库的`ViewPager`组件,最低支持Android api v9。 4 | 5 | ## Feature 6 | * 支持Tab小圆点以及数量显示和隐藏 7 | * 支持自定义Tab View 8 | * 支持使用Bitmap、Drawable和本地resId来显示Tab图标 9 | * 支持对Tab图标替换成自定义View来加载网络图片 10 | * 支持自由设置小圆点、tab大小和位置等设置 11 | * 支持实现如:微博等不均匀Tab的APP风格,并支持滑动 12 | 13 | Project site: . 14 | 15 | 最新版本:v1.8.0 16 | 17 | 效果图: 18 | 19 | ![p1](https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/Screen_20160216163404.png) 20 | 21 | ![p2](https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/Screen_20160216163428.png) 22 | 23 | ![p3](https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/Screen_20160216163452.png) 24 | 25 | ![p4](https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/Screen_20160411141706.png) 26 | 27 | ##导入项目 28 | 29 | **Gradle dependency:** 30 | ``` groovy 31 | compile 'homhomlin.lib:apsts:1.8.0' 32 | ``` 33 | 34 | or 35 | 36 | **Maven dependency:** 37 | ``` xml 38 | 39 | homhomlin.lib 40 | apsts 41 | 1.8.0 42 | 43 | ``` 44 | 45 | 46 | ##用法 47 | 48 | 基本AdvancedPagerPagerSlidingTabStrip: 49 | 50 | 在需要添加的界面xml中添加组件和ViewPager 51 | ``` xml 52 | 59 | 60 | 74 | ``` 75 | 在代码中find该组件,并且设置adapter和ViewPager。 76 | ``` java 77 | ViewPager pager = (ViewPager) findViewById(R.id.pager); 78 | pager.setAdapter(new TestAdapter(getSupportFragmentManager())); 79 | 80 | 81 | AdvancedPagerSlidingTabStrip tabs = (AdvancedPagerSlidingTabStrip) findViewById(R.id.tabs); 82 | tabs.setViewPager(pager); 83 | ``` 84 | 85 | AdvancedPagerSlidingTabStrip支持绑定OnPageChangeListener,并且不影响使用效果。 86 | 87 | ``` java 88 | tabs.setOnPageChangeListener(mPageChangeListener); 89 | ``` 90 | 91 | 通过调用AdvancedPagerSlidingTabStrip的showDot(int index)和hideDot(int index)来显示或者隐藏Tab上的小圆点,index代表需要显示和隐藏的tab序列位置(0 ~ N)。 92 | 93 | 通过调用showDot(int index,String txt)方法可以显示小圆点文字,并同样通过hideDot来隐藏。如: 94 | 95 | ``` java 96 | tabs.showDot(0, “99+”); 97 | ``` 98 | 99 | ## Tab显示模式 100 | 101 | * 基本Adapter显示 102 | 103 | 1.纯文本显示 104 | 105 | 通过实现Adapter内的getPageTitle()接口即可显示纯文本情况的效果。 106 | 107 | 2.图文显示 108 | 109 | 通过将Adapter实现AdvancedPagerSlidingTabStrip.IconTabProvider接口,并实现其中的getPageIcon(展示未选中的图片)、getPageSelectIcon(展示选中的图片)和getPageIconText(展示的文本)方法即可显示图文效果。 110 | 111 | 其中getPageIcon(展示未选中的图片)和getPageSelectIcon方法可以通过改变方法返回值来显示不同类型的图片,可以选择的返回值为Bitmap、Drawable和ResId。 112 | 113 | 3.自定义图片View显示 114 | 115 | 通过将Adapter实现AdvancedPagerSlidingTabStrip.ViewTabProvider接口,并实现其中的onSelectIconView(选中的自定义图片View)、onIconView(未选中的自定义图片View)和getPageIconText(文本)方法即可。 116 | 117 | 需要注意的是,onSelectIconView和onIconView两个方法的返回值均为View,并会回调回上一次使用的View缓存对象,你可以通过判断返回的View是否为null来决定是否新建View对象。(PS:不判断缓存将导致你每次调用都会创建新的View对象。) 118 | 119 | 你可以直接创建并返回ImageView对象,也可以返回其他View子类,该模式可以用于显示网络图片,需要注意的是你需要手动给View添加LayoutParams来控制其大小,并只能使用RelativeLayout.LayoutParams,具体实现方式可以查看[Demo](https://github.com/HomHomLin/AdvancedPagerSlidingTabStrip/blob/master/app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/ViewTabActivity.java)。 120 | 121 | * 自定义Tab 122 | 123 | 我知道以上模式可能并不能完全满足需求,有时候可能我们需要的是更复杂的Tab,所以添加自定义tab来满足各种各样的需求。 124 | 125 | 当前自定义tab被封装到另一个tab类中,通过使用CustomPagerSlidingTabStrip控件来实现,该控件的所有使用方法和AdvancedPagerSlidingTabStrip一致。 126 | 127 | 通过将Adapter实现CustomPagerSlidingTabStrip.CustomTabProvider并实现其中getSelectTabView(选中的View)和getDisSelectTabView(未选中的View)方法来实现自定义Tab,两个方法同样会回调上一次使用的View缓存对象。具体实现方式可以查看[Demo](https://github.com/HomHomLin/AdvancedPagerSlidingTabStrip/blob/master/app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/CustomTabActivity.java)。 128 | 129 | ## 拓展的Provider显示设置 130 | 131 | 有时候我们不使用自定义View显示模式又想调整现有的Tab,比如设置小圆点位置、tab大小和间距等来满足原有就可以实现的需求。 132 | 133 | AdvancedPagerSlidingTabStrip提供了几个Provider来实现这些功能,你可以通过将你的Adapter实现定制的接口方法来实现,具体可以查看demo中的WeiboTabActivity.java。 134 | 135 | * AdvancedPagerSlidingTabStrip.LayoutProvider 136 | 137 | 通过将Adapter实现AdvancedPagerSlidingTabStrip.LayoutProvider可以实现对Tab以及内容icon的Layout设置。 138 | 139 | ``` java 140 | public float getPageWeight(int position); 141 | ``` 142 | 143 | 该方法用于设置每个pageTab在整个tabs中的权重。 144 | 145 | ``` java 146 | public int[] getPageRule(int position); 147 | ``` 148 | 149 | 该方法用于设置每个tab的相对位置,如将tab设置为靠左:return new int[]{ 150 | RelativeLayout.ALIGN_PARENT_LEFT};。 151 | 152 | ``` java 153 | public Margins getPageMargins(int position); 154 | ``` 155 | 156 | 该方法用于设置每个tab的间距大小,如将tab设置为距离左边距30px:return new Margins(30,0,0,0);。 157 | 158 | * AdvancedPagerSlidingTabStrip.TipsProvider 159 | 160 | 通过将Adapter实现AdvancedPagerSlidingTabStrip.TipsProvider可以实现对小圆点的设置。 161 | 162 | ``` java 163 | public int[] getTipsRule(int position); 164 | ``` 165 | 166 | 该方法用于设置小圆点的相对位置。 167 | 168 | 169 | ``` java 170 | public Margins getTipsMargins(int position); 171 | ``` 172 | 173 | 该方法用于设置小圆点在tab中的间距大小。 174 | 175 | ``` java 176 | public Drawable getTipsDrawable(int position); 177 | ``` 178 | 该方法用于设置小圆点的背景,默认为红色圆角图。 179 | 180 | ## XML样式参数 181 | 182 | * `apTabIndicatorColor` 导航条的颜色 183 | * `apTabUnderlineColor` Tab底部下划线的颜色 184 | * `apTabDividerColor` 每个Tab之间的分割线颜色 185 | * `apTabstabTextSelectColor` 被选中的Tab的文本字体颜色 186 | * `apTabIndicatorHeight` 导航条的高度 187 | * `apTabUnderlineHeight` Tab底部下划线的高度 188 | * `apTabDividerPadding` Tab分割线的padding 189 | * `apTabPaddingLeftRight` 每个Tab的左右padding 190 | * `apTabPaddingTopBottom` 每个Tab的上下padding 191 | * `apTabScrollOffset` 选中tab的滑动offset 192 | * `apTabBackground` tab的背景 193 | * `apTabShouldExpand` 伸缩情况,如果为真,每个tab都是相同的weight,默认是false 194 | * `apTabTextAllCaps` Tab的文字是否为全部大写,如果是true就全部大写,默认为true 195 | * `apTabTextSelectColor` 你所选择的那个tab的颜色 196 | * `apTabDrawMode` 绘制模式,text或者normal,用于是否将下划线绘制为跟随TextView 197 | 198 | ## Developed By 199 | 200 | * Linhonghong - 201 | 202 | ##License 203 | Copyright 2016 LinHongHong 204 | 205 | Licensed under the Apache License, Version 2.0 (the "License"); 206 | you may not use this file except in compliance with the License. 207 | You may obtain a copy of the License at 208 | 209 | http://www.apache.org/licenses/LICENSE-2.0 210 | 211 | Unless required by applicable law or agreed to in writing, software 212 | distributed under the License is distributed on an "AS IS" BASIS, 213 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 214 | See the License for the specific language governing permissions and 215 | limitations under the License. -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.lhh.apst.advancedpagerslidingtabstrip" 9 | minSdkVersion 9 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:23.1.1' 25 | compile 'com.android.support:support-v4:23.1.1' 26 | compile 'com.android.support:design:23.1.1' 27 | 28 | compile project(':Library') 29 | 30 | compile 'homhomlin.lib:frescoimageview:1.2.0' 31 | 32 | compile 'com.facebook.fresco:fresco:0.9.0' 33 | compile 'com.facebook.fresco:imagepipeline-okhttp:0.9.0' 34 | // compile 'homhomlin.lib:apsts:1.4.0' 35 | } 36 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in F:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/lhh/apst/advancedpagerslidingtabstrip/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 31 | 32 | 33 | 36 | 37 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/APSTSViewPager.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.content.Context; 4 | import android.support.v4.view.ViewPager; 5 | import android.util.AttributeSet; 6 | import android.view.MotionEvent; 7 | 8 | /** 9 | * Created by linhonghong on 2015/8/10. 10 | */ 11 | public class APSTSViewPager extends ViewPager { 12 | private boolean mNoFocus = false; //if true, keep View don't move 13 | public APSTSViewPager(Context context, AttributeSet attrs) { 14 | super(context, attrs); 15 | } 16 | public APSTSViewPager(Context context){ 17 | this(context,null); 18 | } 19 | 20 | public boolean onInterceptTouchEvent(MotionEvent event) { 21 | if (mNoFocus) { 22 | return false; 23 | } 24 | return super.onInterceptTouchEvent(event); 25 | } 26 | 27 | public void setNoFocus(boolean b){ 28 | mNoFocus = b; 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/App.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.app.Application; 4 | 5 | import com.facebook.drawee.backends.pipeline.Fresco; 6 | import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory; 7 | import com.facebook.imagepipeline.core.ImagePipelineConfig; 8 | import com.squareup.okhttp.OkHttpClient; 9 | 10 | /** 11 | * Created by Linhh on 16/2/16. 12 | */ 13 | public class App extends Application{ 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | ImagePipelineConfig frescoConfig = OkHttpImagePipelineConfigFactory 18 | .newBuilder(this, new OkHttpClient()) 19 | .build(); 20 | Fresco.initialize(this,frescoConfig); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/CustomTabActivity.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentActivity; 8 | import android.support.v4.app.FragmentManager; 9 | import android.support.v4.app.FragmentStatePagerAdapter; 10 | import android.support.v4.view.ViewPager; 11 | import android.support.v7.app.ActionBarActivity; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.BaseAdapter; 16 | import android.widget.TextView; 17 | 18 | import com.lhh.apst.fragments.FirstFragment; 19 | import com.lhh.apst.fragments.FourthFragment; 20 | import com.lhh.apst.fragments.SecondFragment; 21 | import com.lhh.apst.fragments.ThirdFragment; 22 | import com.lhh.apst.library.AdvancedPagerSlidingTabStrip; 23 | import com.lhh.apst.library.CustomPagerSlidingTabStrip; 24 | import com.lhh.apst.library.ViewHolder; 25 | 26 | /** 27 | * Created by linhonghong on 2015/8/10. 28 | */ 29 | public class CustomTabActivity extends ActionBarActivity implements ViewPager.OnPageChangeListener{ 30 | 31 | public CustomPagerSlidingTabStrip mAPSTS; 32 | public APSTSViewPager mVP; 33 | 34 | private static final int VIEW_FIRST = 0; 35 | private static final int VIEW_SECOND = 1; 36 | private static final int VIEW_THIRD = 2; 37 | private static final int VIEW_FOURTH = 3; 38 | 39 | private static final int VIEW_SIZE = 4; 40 | 41 | private Context mContext; 42 | 43 | private FirstFragment mFirstFragment = null; 44 | private SecondFragment mSecondFragment = null; 45 | private ThirdFragment mThirdFragment = null; 46 | private FourthFragment mFourthFragment = null; 47 | 48 | @Override 49 | protected void onCreate(Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | mContext = this; 52 | setContentView(R.layout.activity_custom_tab); 53 | findViews(); 54 | init(); 55 | } 56 | 57 | private void findViews(){ 58 | mAPSTS = (CustomPagerSlidingTabStrip)findViewById(R.id.tabs); 59 | mVP = (APSTSViewPager)findViewById(R.id.vp_main); 60 | } 61 | 62 | private void init(){ 63 | mVP.setOffscreenPageLimit(VIEW_SIZE); 64 | FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager()); 65 | 66 | mVP.setAdapter(new FragmentAdapter(getSupportFragmentManager())); 67 | 68 | adapter.notifyDataSetChanged(); 69 | mAPSTS.setViewPager(mVP); 70 | mAPSTS.setOnPageChangeListener(this); 71 | } 72 | 73 | @Override 74 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 75 | 76 | } 77 | 78 | @Override 79 | public void onPageSelected(int position) { 80 | 81 | } 82 | 83 | @Override 84 | public void onPageScrollStateChanged(int state) { 85 | 86 | } 87 | 88 | public class FragmentAdapter extends FragmentStatePagerAdapter implements CustomPagerSlidingTabStrip.CustomTabProvider{ 89 | 90 | protected LayoutInflater mInflater; 91 | 92 | public FragmentAdapter(FragmentManager fm) { 93 | super(fm); 94 | mInflater = LayoutInflater.from(mContext); 95 | } 96 | 97 | @Override 98 | public Fragment getItem(int position) { 99 | if(position >= 0 && position < VIEW_SIZE){ 100 | switch (position){ 101 | case VIEW_FIRST: 102 | if(null == mFirstFragment) 103 | mFirstFragment = FirstFragment.instance(); 104 | return mFirstFragment; 105 | 106 | case VIEW_SECOND: 107 | if(null == mSecondFragment) 108 | mSecondFragment = SecondFragment.instance(); 109 | return mSecondFragment; 110 | 111 | case VIEW_THIRD: 112 | if(null == mThirdFragment) 113 | mThirdFragment = ThirdFragment.instance(); 114 | return mThirdFragment; 115 | 116 | case VIEW_FOURTH: 117 | if(null == mFourthFragment) 118 | mFourthFragment = FourthFragment.instance(); 119 | return mFourthFragment; 120 | default: 121 | break; 122 | } 123 | } 124 | return null; 125 | } 126 | 127 | @Override 128 | public int getCount() { 129 | return VIEW_SIZE; 130 | } 131 | 132 | @Override 133 | public CharSequence getPageTitle(int position) { 134 | if(position >= 0 && position < VIEW_SIZE){ 135 | switch (position){ 136 | case VIEW_FIRST: 137 | return "FIRST"; 138 | case VIEW_SECOND: 139 | return "SECOND"; 140 | case VIEW_THIRD: 141 | return "THIRD"; 142 | case VIEW_FOURTH: 143 | return "FOURTH"; 144 | default: 145 | break; 146 | } 147 | } 148 | return null; 149 | } 150 | 151 | @Override 152 | public View getSelectTabView(int position, View convertView) { 153 | if (convertView == null){ 154 | convertView = mInflater.inflate(R.layout.custom_select_tab, null); 155 | } 156 | 157 | TextView tv = ViewHolder.get(convertView, R.id.tvTab); 158 | 159 | tv.setText(getPageTitle(position)); 160 | 161 | return convertView; 162 | } 163 | 164 | @Override 165 | public View getDisSelectTabView(int position, View convertView) { 166 | if (convertView == null){ 167 | convertView = mInflater.inflate(R.layout.custom_disselect_tab, null); 168 | } 169 | 170 | TextView tv = ViewHolder.get(convertView, R.id.tvTab); 171 | 172 | tv.setText(getPageTitle(position)); 173 | 174 | return convertView; 175 | } 176 | } 177 | } 178 | 179 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/IconTabActivity.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.graphics.Rect; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentActivity; 7 | import android.support.v4.app.FragmentManager; 8 | import android.support.v4.app.FragmentStatePagerAdapter; 9 | import android.support.v4.view.ViewPager; 10 | import android.support.v7.app.ActionBarActivity; 11 | import android.widget.RelativeLayout; 12 | 13 | import com.lhh.apst.fragments.FirstFragment; 14 | import com.lhh.apst.fragments.FourthFragment; 15 | import com.lhh.apst.fragments.SecondFragment; 16 | import com.lhh.apst.fragments.ThirdFragment; 17 | import com.lhh.apst.library.AdvancedPagerSlidingTabStrip; 18 | 19 | /** 20 | * Created by linhonghong on 2015/8/11. 21 | */ 22 | public class IconTabActivity extends ActionBarActivity implements ViewPager.OnPageChangeListener{ 23 | 24 | public AdvancedPagerSlidingTabStrip mAPSTS; 25 | public APSTSViewPager mVP; 26 | 27 | private static final int VIEW_FIRST = 0; 28 | private static final int VIEW_SECOND = 1; 29 | private static final int VIEW_THIRD = 2; 30 | private static final int VIEW_FOURTH = 3; 31 | 32 | private static final int VIEW_SIZE = 4; 33 | 34 | private FirstFragment mFirstFragment = null; 35 | private SecondFragment mSecondFragment = null; 36 | private ThirdFragment mThirdFragment = null; 37 | private FourthFragment mFourthFragment = null; 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_icon_tab); 43 | findViews(); 44 | init(); 45 | } 46 | 47 | private void findViews(){ 48 | mAPSTS = (AdvancedPagerSlidingTabStrip)findViewById(R.id.tabs); 49 | mVP = (APSTSViewPager)findViewById(R.id.vp_main); 50 | } 51 | 52 | private void init(){ 53 | mVP.setOffscreenPageLimit(VIEW_SIZE); 54 | FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager()); 55 | 56 | mVP.setAdapter(new FragmentAdapter(getSupportFragmentManager())); 57 | 58 | adapter.notifyDataSetChanged(); 59 | mAPSTS.setViewPager(mVP); 60 | mAPSTS.setOnPageChangeListener(this); 61 | mVP.setCurrentItem(VIEW_FIRST); 62 | mAPSTS.showDot(VIEW_FIRST,"99+"); 63 | } 64 | 65 | @Override 66 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 67 | 68 | } 69 | 70 | @Override 71 | public void onPageSelected(int position) { 72 | 73 | } 74 | 75 | @Override 76 | public void onPageScrollStateChanged(int state) { 77 | 78 | } 79 | 80 | public class FragmentAdapter extends FragmentStatePagerAdapter implements AdvancedPagerSlidingTabStrip.IconTabProvider{ 81 | 82 | public FragmentAdapter(FragmentManager fm) { 83 | super(fm); 84 | } 85 | 86 | @Override 87 | public Fragment getItem(int position) { 88 | if(position >= 0 && position < VIEW_SIZE){ 89 | switch (position){ 90 | case VIEW_FIRST: 91 | if(null == mFirstFragment) 92 | mFirstFragment = FirstFragment.instance(); 93 | return mFirstFragment; 94 | 95 | case VIEW_SECOND: 96 | if(null == mSecondFragment) 97 | mSecondFragment = SecondFragment.instance(); 98 | return mSecondFragment; 99 | 100 | case VIEW_THIRD: 101 | if(null == mThirdFragment) 102 | mThirdFragment = ThirdFragment.instance(); 103 | return mThirdFragment; 104 | 105 | case VIEW_FOURTH: 106 | if(null == mFourthFragment) 107 | mFourthFragment = FourthFragment.instance(); 108 | return mFourthFragment; 109 | default: 110 | break; 111 | } 112 | } 113 | return null; 114 | } 115 | 116 | @Override 117 | public int getCount() { 118 | return VIEW_SIZE; 119 | } 120 | 121 | @Override 122 | public CharSequence getPageTitle(int position) { 123 | if(position >= 0 && position < VIEW_SIZE){ 124 | switch (position){ 125 | case VIEW_FIRST: 126 | return "first"; 127 | case VIEW_SECOND: 128 | return "second"; 129 | case VIEW_THIRD: 130 | return "third"; 131 | case VIEW_FOURTH: 132 | return "fourth"; 133 | default: 134 | break; 135 | } 136 | } 137 | return null; 138 | } 139 | 140 | @Override 141 | public Integer getPageIcon(int index) { 142 | if(index >= 0 && index < VIEW_SIZE){ 143 | switch (index){ 144 | case VIEW_FIRST: 145 | return R.mipmap.home_main_icon_n; 146 | case VIEW_SECOND: 147 | return R.mipmap.home_categry_icon_n; 148 | case VIEW_THIRD: 149 | return R.mipmap.home_live_icon_n; 150 | case VIEW_FOURTH: 151 | return R.mipmap.home_mine_icon_n; 152 | default: 153 | break; 154 | } 155 | } 156 | return 0; 157 | } 158 | 159 | @Override 160 | public Integer getPageSelectIcon(int index) { 161 | if(index >= 0 && index < VIEW_SIZE){ 162 | switch (index){ 163 | case VIEW_FIRST: 164 | return R.mipmap.home_main_icon_f_n; 165 | case VIEW_SECOND: 166 | return R.mipmap.home_categry_icon_f_n; 167 | case VIEW_THIRD: 168 | return R.mipmap.home_live_icon_f_n; 169 | case VIEW_FOURTH: 170 | return R.mipmap.home_mine_icon_f_n; 171 | default: 172 | break; 173 | } 174 | } 175 | return 0; 176 | } 177 | 178 | @Override 179 | public Rect getPageIconBounds(int position) { 180 | return null; 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.support.v7.app.ActionBarActivity; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | import android.widget.Button; 11 | 12 | 13 | public class MainActivity extends ActionBarActivity { 14 | 15 | private Button mNormalTab; 16 | private Button mIconTab; 17 | private Button mCustomTab; 18 | private Button mViewTab; 19 | private Button mWeiboTab; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main); 25 | findViews(); 26 | setButton(); 27 | } 28 | 29 | private void findViews(){ 30 | mIconTab = (Button)findViewById(R.id.icontab); 31 | mNormalTab = (Button)findViewById(R.id.noramltab); 32 | mCustomTab = (Button)findViewById(R.id.customtab); 33 | mViewTab = (Button)findViewById(R.id.viewtab); 34 | mWeiboTab = (Button)findViewById(R.id.weibotab); 35 | } 36 | 37 | private void setButton(){ 38 | mIconTab.setOnClickListener(new View.OnClickListener() { 39 | @Override 40 | public void onClick(View view) { 41 | MainActivity.this.startActivity(new Intent(MainActivity.this,IconTabActivity.class)); 42 | } 43 | }); 44 | mNormalTab.setOnClickListener(new View.OnClickListener() { 45 | @Override 46 | public void onClick(View view) { 47 | MainActivity.this.startActivity(new Intent(MainActivity.this,NormalTabActivity.class)); 48 | } 49 | }); 50 | mCustomTab.setOnClickListener(new View.OnClickListener() { 51 | @Override 52 | public void onClick(View view) { 53 | MainActivity.this.startActivity(new Intent(MainActivity.this,CustomTabActivity.class)); 54 | } 55 | }); 56 | mViewTab.setOnClickListener(new View.OnClickListener() { 57 | @Override 58 | public void onClick(View v) { 59 | MainActivity.this.startActivity(new Intent(MainActivity.this,ViewTabActivity.class)); 60 | 61 | } 62 | }); 63 | mWeiboTab.setOnClickListener(new View.OnClickListener() { 64 | @Override 65 | public void onClick(View v) { 66 | MainActivity.this.startActivity(new Intent(MainActivity.this,WeiboTabActivity.class)); 67 | } 68 | }); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/NormalTabActivity.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.app.FragmentActivity; 7 | import android.support.v4.app.FragmentManager; 8 | import android.support.v4.app.FragmentStatePagerAdapter; 9 | import android.support.v4.view.ViewPager; 10 | import android.support.v7.app.ActionBarActivity; 11 | import android.view.View; 12 | import android.view.ViewGroup; 13 | import android.widget.BaseAdapter; 14 | 15 | import com.lhh.apst.fragments.FirstFragment; 16 | import com.lhh.apst.fragments.FourthFragment; 17 | import com.lhh.apst.fragments.SecondFragment; 18 | import com.lhh.apst.fragments.ThirdFragment; 19 | import com.lhh.apst.library.AdvancedPagerSlidingTabStrip; 20 | 21 | /** 22 | * Created by linhonghong on 2015/8/10. 23 | */ 24 | public class NormalTabActivity extends ActionBarActivity implements ViewPager.OnPageChangeListener{ 25 | 26 | public AdvancedPagerSlidingTabStrip mAPSTS; 27 | public APSTSViewPager mVP; 28 | 29 | private static final int VIEW_FIRST = 0; 30 | private static final int VIEW_SECOND = 1; 31 | private static final int VIEW_THIRD = 2; 32 | private static final int VIEW_FOURTH = 3; 33 | 34 | private static final int VIEW_SIZE = 4; 35 | 36 | private FirstFragment mFirstFragment = null; 37 | private SecondFragment mSecondFragment = null; 38 | private ThirdFragment mThirdFragment = null; 39 | private FourthFragment mFourthFragment = null; 40 | 41 | @Override 42 | protected void onCreate(Bundle savedInstanceState) { 43 | super.onCreate(savedInstanceState); 44 | setContentView(R.layout.activity_normal_tab); 45 | findViews(); 46 | init(); 47 | } 48 | 49 | private void findViews(){ 50 | mAPSTS = (AdvancedPagerSlidingTabStrip)findViewById(R.id.tabs); 51 | mVP = (APSTSViewPager)findViewById(R.id.vp_main); 52 | } 53 | 54 | private void init(){ 55 | mVP.setOffscreenPageLimit(VIEW_SIZE); 56 | FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager()); 57 | 58 | mVP.setAdapter(new FragmentAdapter(getSupportFragmentManager())); 59 | 60 | adapter.notifyDataSetChanged(); 61 | mAPSTS.setViewPager(mVP); 62 | mAPSTS.setOnPageChangeListener(this); 63 | mAPSTS.showDot(VIEW_FIRST); 64 | } 65 | 66 | @Override 67 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 68 | 69 | } 70 | 71 | @Override 72 | public void onPageSelected(int position) { 73 | 74 | } 75 | 76 | @Override 77 | public void onPageScrollStateChanged(int state) { 78 | 79 | } 80 | 81 | public class FragmentAdapter extends FragmentStatePagerAdapter{ 82 | 83 | public FragmentAdapter(FragmentManager fm) { 84 | super(fm); 85 | } 86 | 87 | @Override 88 | public Fragment getItem(int position) { 89 | if(position >= 0 && position < VIEW_SIZE){ 90 | switch (position){ 91 | case VIEW_FIRST: 92 | if(null == mFirstFragment) 93 | mFirstFragment = FirstFragment.instance(); 94 | return mFirstFragment; 95 | 96 | case VIEW_SECOND: 97 | if(null == mSecondFragment) 98 | mSecondFragment = SecondFragment.instance(); 99 | return mSecondFragment; 100 | 101 | case VIEW_THIRD: 102 | if(null == mThirdFragment) 103 | mThirdFragment = ThirdFragment.instance(); 104 | return mThirdFragment; 105 | 106 | case VIEW_FOURTH: 107 | if(null == mFourthFragment) 108 | mFourthFragment = FourthFragment.instance(); 109 | return mFourthFragment; 110 | default: 111 | break; 112 | } 113 | } 114 | return null; 115 | } 116 | 117 | @Override 118 | public int getCount() { 119 | return VIEW_SIZE; 120 | } 121 | 122 | @Override 123 | public CharSequence getPageTitle(int position) { 124 | if(position >= 0 && position < VIEW_SIZE){ 125 | switch (position){ 126 | case VIEW_FIRST: 127 | return "FIRST"; 128 | case VIEW_SECOND: 129 | return "SECOND"; 130 | case VIEW_THIRD: 131 | return "THIRD"; 132 | case VIEW_FOURTH: 133 | return "FOURTH"; 134 | default: 135 | break; 136 | } 137 | } 138 | return null; 139 | } 140 | // 141 | // @Override 142 | // public float getPageWeight(int position) { 143 | // if(position >= 0 && position < VIEW_SIZE){ 144 | // switch (position){ 145 | // case VIEW_FIRST: 146 | // return 1.0f; 147 | // case VIEW_SECOND: 148 | // return 2.0f; 149 | // case VIEW_THIRD: 150 | // return 2.0f; 151 | // case VIEW_FOURTH: 152 | // return 1.0f; 153 | // default: 154 | // break; 155 | // } 156 | // } 157 | // return 1.0f; 158 | // } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/ViewTabActivity.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | import android.support.v4.app.FragmentStatePagerAdapter; 7 | import android.support.v4.view.ViewPager; 8 | import android.support.v7.app.ActionBarActivity; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.RelativeLayout; 12 | 13 | import com.lhh.apst.fragments.FirstFragment; 14 | import com.lhh.apst.fragments.FourthFragment; 15 | import com.lhh.apst.fragments.SecondFragment; 16 | import com.lhh.apst.fragments.ThirdFragment; 17 | import com.lhh.apst.library.AdvancedPagerSlidingTabStrip; 18 | 19 | import lib.lhh.fiv.library.FrescoImageView; 20 | 21 | /** 22 | * Created by Linhh on 16/2/16. 23 | */ 24 | public class ViewTabActivity extends ActionBarActivity implements ViewPager.OnPageChangeListener{ 25 | 26 | public AdvancedPagerSlidingTabStrip mAPSTS; 27 | public APSTSViewPager mVP; 28 | 29 | private static final int VIEW_FIRST = 0; 30 | private static final int VIEW_SECOND = 1; 31 | private static final int VIEW_THIRD = 2; 32 | private static final int VIEW_FOURTH = 3; 33 | 34 | private static final int VIEW_SIZE = 4; 35 | 36 | private FirstFragment mFirstFragment = null; 37 | private SecondFragment mSecondFragment = null; 38 | private ThirdFragment mThirdFragment = null; 39 | private FourthFragment mFourthFragment = null; 40 | 41 | @Override 42 | protected void onCreate(Bundle savedInstanceState) { 43 | super.onCreate(savedInstanceState); 44 | setContentView(R.layout.activity_icon_tab); 45 | findViews(); 46 | init(); 47 | } 48 | 49 | private void findViews(){ 50 | mAPSTS = (AdvancedPagerSlidingTabStrip)findViewById(R.id.tabs); 51 | mVP = (APSTSViewPager)findViewById(R.id.vp_main); 52 | } 53 | 54 | private void init(){ 55 | mVP.setOffscreenPageLimit(VIEW_SIZE); 56 | FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager()); 57 | 58 | mVP.setAdapter(new FragmentAdapter(getSupportFragmentManager())); 59 | 60 | adapter.notifyDataSetChanged(); 61 | mAPSTS.setViewPager(mVP); 62 | mAPSTS.setOnPageChangeListener(this); 63 | mVP.setCurrentItem(VIEW_FIRST); 64 | mAPSTS.showDot(VIEW_FIRST,"99+"); 65 | } 66 | 67 | @Override 68 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 69 | 70 | } 71 | 72 | @Override 73 | public void onPageSelected(int position) { 74 | 75 | } 76 | 77 | @Override 78 | public void onPageScrollStateChanged(int state) { 79 | 80 | } 81 | 82 | public class FragmentAdapter extends FragmentStatePagerAdapter implements AdvancedPagerSlidingTabStrip.ViewTabProvider{ 83 | 84 | public FragmentAdapter(FragmentManager fm) { 85 | super(fm); 86 | } 87 | 88 | @Override 89 | public Fragment getItem(int position) { 90 | if(position >= 0 && position < VIEW_SIZE){ 91 | switch (position){ 92 | case VIEW_FIRST: 93 | if(null == mFirstFragment) 94 | mFirstFragment = FirstFragment.instance(); 95 | return mFirstFragment; 96 | 97 | case VIEW_SECOND: 98 | if(null == mSecondFragment) 99 | mSecondFragment = SecondFragment.instance(); 100 | return mSecondFragment; 101 | 102 | case VIEW_THIRD: 103 | if(null == mThirdFragment) 104 | mThirdFragment = ThirdFragment.instance(); 105 | return mThirdFragment; 106 | 107 | case VIEW_FOURTH: 108 | if(null == mFourthFragment) 109 | mFourthFragment = FourthFragment.instance(); 110 | return mFourthFragment; 111 | default: 112 | break; 113 | } 114 | } 115 | return null; 116 | } 117 | 118 | @Override 119 | public int getCount() { 120 | return VIEW_SIZE; 121 | } 122 | 123 | @Override 124 | public View onSelectIconView(int position, View view, ViewGroup parent) { 125 | FrescoImageView draweeView; 126 | if(view == null){ 127 | draweeView = new FrescoImageView(ViewTabActivity.this); 128 | draweeView.setLayoutParams(new RelativeLayout.LayoutParams(50,50)); 129 | view = draweeView; 130 | } 131 | draweeView = (FrescoImageView)view; 132 | switch (position){ 133 | case VIEW_FIRST: 134 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/categry_icon_p.png",R.mipmap.home_categry_icon_f_n); 135 | break; 136 | case VIEW_SECOND: 137 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/classify_icon_p.png",R.mipmap.home_auther_icon_f_p); 138 | break; 139 | case VIEW_THIRD: 140 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/mine_icon_p.png",R.mipmap.home_live_icon_f_n); 141 | break; 142 | case VIEW_FOURTH: 143 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/update_dynamic_p.png",R.mipmap.home_main_icon_f_n); 144 | break; 145 | default: 146 | break; 147 | } 148 | return draweeView; 149 | } 150 | 151 | @Override 152 | public View onIconView(int position, View view, ViewGroup parent) { 153 | FrescoImageView draweeView; 154 | if(view == null){ 155 | draweeView = new FrescoImageView(ViewTabActivity.this); 156 | draweeView.setLayoutParams(new RelativeLayout.LayoutParams(50,50)); 157 | view = draweeView; 158 | } 159 | draweeView = (FrescoImageView)view; 160 | switch (position){ 161 | case VIEW_FIRST: 162 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/categry_icon_n.png",R.mipmap.home_categry_icon_n); 163 | break; 164 | case VIEW_SECOND: 165 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/classify_icon_n.png",R.mipmap.home_auther_icon_f_n); 166 | break; 167 | case VIEW_THIRD: 168 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/mine_icon_n.png",R.mipmap.home_live_icon_n); 169 | break; 170 | case VIEW_FOURTH: 171 | draweeView.loadView("https://raw.githubusercontent.com/HomHomLin/AdvancedPagerSlidingTabStrip/master/Pic/update_dynamic_n.png",R.mipmap.home_main_icon_n); 172 | break; 173 | default: 174 | break; 175 | } 176 | return draweeView; 177 | } 178 | 179 | @Override 180 | public CharSequence getPageTitle(int position) { 181 | if(position >= 0 && position < VIEW_SIZE){ 182 | switch (position){ 183 | case VIEW_FIRST: 184 | return "first"; 185 | case VIEW_SECOND: 186 | return "second"; 187 | case VIEW_THIRD: 188 | return "third"; 189 | case VIEW_FOURTH: 190 | return "fourth"; 191 | default: 192 | break; 193 | } 194 | } 195 | return null; 196 | } 197 | 198 | } 199 | } 200 | 201 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/advancedpagerslidingtabstrip/WeiboTabActivity.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.advancedpagerslidingtabstrip; 2 | 3 | import android.graphics.Rect; 4 | import android.graphics.drawable.Drawable; 5 | import android.os.Bundle; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentManager; 8 | import android.support.v4.app.FragmentStatePagerAdapter; 9 | import android.support.v4.view.ViewPager; 10 | import android.support.v7.app.ActionBarActivity; 11 | import android.view.View; 12 | import android.widget.ImageView; 13 | import android.widget.RelativeLayout; 14 | import android.widget.Toast; 15 | 16 | import com.lhh.apst.fragments.FirstFragment; 17 | import com.lhh.apst.fragments.FourthFragment; 18 | import com.lhh.apst.fragments.SecondFragment; 19 | import com.lhh.apst.fragments.ThirdFragment; 20 | import com.lhh.apst.library.AdvancedPagerSlidingTabStrip; 21 | import com.lhh.apst.library.Margins; 22 | 23 | /** 24 | * Created by Linhh on 16/3/8. 25 | */ 26 | public class WeiboTabActivity extends ActionBarActivity implements ViewPager.OnPageChangeListener{ 27 | 28 | public AdvancedPagerSlidingTabStrip mAPSTS; 29 | public APSTSViewPager mVP; 30 | 31 | private static final int VIEW_FIRST = 0; 32 | private static final int VIEW_SECOND = 1; 33 | private static final int VIEW_THIRD = 2; 34 | private static final int VIEW_FOURTH = 3; 35 | 36 | private static final int VIEW_SIZE = 4; 37 | 38 | private FirstFragment mFirstFragment = null; 39 | private SecondFragment mSecondFragment = null; 40 | private ThirdFragment mThirdFragment = null; 41 | private FourthFragment mFourthFragment = null; 42 | private ImageView mIvCenterBtn = null; 43 | 44 | private int mSize = 0; 45 | 46 | @Override 47 | protected void onCreate(Bundle savedInstanceState) { 48 | super.onCreate(savedInstanceState); 49 | setContentView(R.layout.activity_weibo_tab); 50 | findViews(); 51 | init(); 52 | } 53 | 54 | private void findViews(){ 55 | mAPSTS = (AdvancedPagerSlidingTabStrip)findViewById(R.id.tabs); 56 | mVP = (APSTSViewPager)findViewById(R.id.vp_main); 57 | mIvCenterBtn = (ImageView)findViewById(R.id.ivCenterBtn); 58 | } 59 | 60 | private void init(){ 61 | mIvCenterBtn.setOnClickListener(new View.OnClickListener() { 62 | @Override 63 | public void onClick(View v) { 64 | Toast.makeText(WeiboTabActivity.this, "Center Btn is Clicked.",Toast.LENGTH_SHORT).show(); 65 | } 66 | }); 67 | mSize = getResources().getDimensionPixelSize(R.dimen.weibo_tab_size); 68 | mVP.setOffscreenPageLimit(VIEW_SIZE); 69 | FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager()); 70 | 71 | mVP.setAdapter(new FragmentAdapter(getSupportFragmentManager())); 72 | 73 | adapter.notifyDataSetChanged(); 74 | mAPSTS.setViewPager(mVP); 75 | mAPSTS.setOnPageChangeListener(this); 76 | mVP.setCurrentItem(VIEW_FIRST); 77 | mAPSTS.showDot(VIEW_FIRST,"99+"); 78 | } 79 | 80 | @Override 81 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 82 | 83 | } 84 | 85 | @Override 86 | public void onPageSelected(int position) { 87 | 88 | } 89 | 90 | @Override 91 | public void onPageScrollStateChanged(int state) { 92 | 93 | } 94 | 95 | public class FragmentAdapter extends FragmentStatePagerAdapter implements 96 | AdvancedPagerSlidingTabStrip.IconTabProvider, 97 | AdvancedPagerSlidingTabStrip.LayoutProvider, 98 | AdvancedPagerSlidingTabStrip.TipsProvider{ 99 | 100 | public FragmentAdapter(FragmentManager fm) { 101 | super(fm); 102 | } 103 | 104 | @Override 105 | public Fragment getItem(int position) { 106 | if(position >= 0 && position < VIEW_SIZE){ 107 | switch (position){ 108 | case VIEW_FIRST: 109 | if(null == mFirstFragment) 110 | mFirstFragment = FirstFragment.instance(); 111 | return mFirstFragment; 112 | 113 | case VIEW_SECOND: 114 | if(null == mSecondFragment) 115 | mSecondFragment = SecondFragment.instance(); 116 | return mSecondFragment; 117 | 118 | case VIEW_THIRD: 119 | if(null == mThirdFragment) 120 | mThirdFragment = ThirdFragment.instance(); 121 | return mThirdFragment; 122 | 123 | case VIEW_FOURTH: 124 | if(null == mFourthFragment) 125 | mFourthFragment = FourthFragment.instance(); 126 | return mFourthFragment; 127 | default: 128 | break; 129 | } 130 | } 131 | return null; 132 | } 133 | 134 | @Override 135 | public int getCount() { 136 | return VIEW_SIZE; 137 | } 138 | 139 | @Override 140 | public CharSequence getPageTitle(int position) { 141 | if(position >= 0 && position < VIEW_SIZE){ 142 | switch (position){ 143 | case VIEW_FIRST: 144 | return "first"; 145 | case VIEW_SECOND: 146 | return "second"; 147 | case VIEW_THIRD: 148 | return "third"; 149 | case VIEW_FOURTH: 150 | return "fourth"; 151 | default: 152 | break; 153 | } 154 | } 155 | return null; 156 | } 157 | 158 | @Override 159 | public float getPageWeight(int position) { 160 | if(position >= 0 && position < VIEW_SIZE){ 161 | switch (position){ 162 | case VIEW_FIRST: 163 | return 0.92f; 164 | case VIEW_SECOND: 165 | return 1.0f; 166 | case VIEW_THIRD: 167 | return 1.0f; 168 | case VIEW_FOURTH: 169 | return 0.92f; 170 | default: 171 | break; 172 | } 173 | } 174 | return 1.0f; 175 | } 176 | 177 | @Override 178 | public int[] getPageRule(int position) { 179 | if(position >= 0 && position < VIEW_SIZE){ 180 | switch (position){ 181 | case VIEW_FIRST: 182 | return new int[]{ 183 | RelativeLayout.ALIGN_PARENT_LEFT}; 184 | case VIEW_SECOND: 185 | return new int[]{ 186 | RelativeLayout.ALIGN_PARENT_LEFT}; 187 | case VIEW_THIRD: 188 | return new int[]{ 189 | RelativeLayout.ALIGN_PARENT_RIGHT}; 190 | case VIEW_FOURTH: 191 | return new int[]{ 192 | RelativeLayout.ALIGN_PARENT_RIGHT}; 193 | default: 194 | break; 195 | } 196 | } 197 | return new int[0]; 198 | } 199 | 200 | @Override 201 | public Margins getPageMargins(int position) { 202 | if(position >= 0 && position < VIEW_SIZE){ 203 | switch (position){ 204 | case VIEW_FIRST: 205 | return new Margins(getResources().getDimensionPixelSize(R.dimen.home_bar_icon_margins),0,0,0); 206 | case VIEW_SECOND: 207 | return null; 208 | case VIEW_THIRD: 209 | return null; 210 | case VIEW_FOURTH: 211 | return new Margins(0,0,getResources().getDimensionPixelSize(R.dimen.home_bar_icon_margins),0); 212 | default: 213 | break; 214 | } 215 | } 216 | return null; 217 | } 218 | 219 | @Override 220 | public Integer getPageIcon(int index) { 221 | if(index >= 0 && index < VIEW_SIZE){ 222 | switch (index){ 223 | case VIEW_FIRST: 224 | return R.mipmap.tabbar_home; 225 | case VIEW_SECOND: 226 | return R.mipmap.tabbar_message_center; 227 | case VIEW_THIRD: 228 | return R.mipmap.tabbar_discover; 229 | case VIEW_FOURTH: 230 | return R.mipmap.tabbar_profile; 231 | default: 232 | break; 233 | } 234 | } 235 | return 0; 236 | } 237 | 238 | @Override 239 | public Integer getPageSelectIcon(int index) { 240 | if(index >= 0 && index < VIEW_SIZE){ 241 | switch (index){ 242 | case VIEW_FIRST: 243 | return R.mipmap.tabbar_home_selected; 244 | case VIEW_SECOND: 245 | return R.mipmap.tabbar_message_center_highlighted; 246 | case VIEW_THIRD: 247 | return R.mipmap.tabbar_discover_highlighted; 248 | case VIEW_FOURTH: 249 | return R.mipmap.tabbar_profile_highlighted; 250 | default: 251 | break; 252 | } 253 | } 254 | return 0; 255 | } 256 | 257 | @Override 258 | public Rect getPageIconBounds(int position) { 259 | return new Rect(0, 0, mSize, mSize); 260 | } 261 | 262 | @Override 263 | public int[] getTipsRule(int position) { 264 | if(position >= 0 && position < VIEW_SIZE){ 265 | switch (position){ 266 | case VIEW_FIRST: 267 | return new int[]{ 268 | RelativeLayout.ALIGN_PARENT_LEFT}; 269 | case VIEW_SECOND: 270 | return new int[]{ 271 | RelativeLayout.ALIGN_PARENT_LEFT}; 272 | case VIEW_THIRD: 273 | return new int[]{ 274 | RelativeLayout.ALIGN_PARENT_RIGHT}; 275 | case VIEW_FOURTH: 276 | return new int[]{ 277 | RelativeLayout.ALIGN_PARENT_RIGHT}; 278 | default: 279 | break; 280 | } 281 | } 282 | return new int[0]; 283 | } 284 | 285 | @Override 286 | public Margins getTipsMargins(int position) { 287 | if(position >= 0 && position < VIEW_SIZE){ 288 | switch (position){ 289 | case VIEW_FIRST: 290 | return new Margins(4 *getResources().getDimensionPixelSize(R.dimen.psts_dot_m_right), 0, 0, 0); 291 | default: 292 | break; 293 | } 294 | } 295 | return null; 296 | } 297 | 298 | @Override 299 | public Drawable getTipsDrawable(int position) { 300 | return null; 301 | } 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/fragments/FirstFragment.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.lhh.apst.advancedpagerslidingtabstrip.R; 11 | 12 | /** 13 | * Created by linhonghong on 2015/8/11. 14 | */ 15 | public class FirstFragment extends Fragment{ 16 | 17 | public static FirstFragment instance() { 18 | FirstFragment view = new FirstFragment(); 19 | return view; 20 | } 21 | 22 | @Nullable 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 25 | View view = inflater.inflate(R.layout.first_fragment, null); 26 | return view; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/fragments/FourthFragment.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.lhh.apst.advancedpagerslidingtabstrip.R; 11 | 12 | /** 13 | * Created by linhonghong on 2015/8/11. 14 | */ 15 | public class FourthFragment extends Fragment { 16 | 17 | public static FourthFragment instance() { 18 | FourthFragment view = new FourthFragment(); 19 | return view; 20 | } 21 | 22 | @Nullable 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 25 | View view = inflater.inflate(R.layout.fourth_fragment, null); 26 | return view; 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/fragments/SecondFragment.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.lhh.apst.advancedpagerslidingtabstrip.R; 11 | 12 | /** 13 | * Created by linhonghong on 2015/8/11. 14 | */ 15 | public class SecondFragment extends Fragment { 16 | 17 | public static SecondFragment instance() { 18 | SecondFragment view = new SecondFragment(); 19 | return view; 20 | } 21 | 22 | @Nullable 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 25 | View view = inflater.inflate(R.layout.second_fragment, null); 26 | return view; 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/lhh/apst/fragments/ThirdFragment.java: -------------------------------------------------------------------------------- 1 | package com.lhh.apst.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v4.app.Fragment; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import com.lhh.apst.advancedpagerslidingtabstrip.R; 11 | 12 | /** 13 | * Created by linhonghong on 2015/8/11. 14 | */ 15 | public class ThirdFragment extends Fragment { 16 | 17 | public static ThirdFragment instance() { 18 | ThirdFragment view = new ThirdFragment(); 19 | return view; 20 | } 21 | 22 | @Nullable 23 | @Override 24 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 25 | View view = inflater.inflate(R.layout.third_fragment, null); 26 | return view; 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/sub_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_bg_transparent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_bg_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_color_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/weibo_tab_bg_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_custom_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 11 | 12 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_icon_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 9 |