项目来源: https://github.com/xuwj/ToolbarDemo#userconsent#
一、V7包升级问题
折腾好久,终于解决 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 的错误问题。。。
解决策略:翻墙,然后在sdkManager里面下载最新的support包,一定要是最新的。
然后引入到工程中来。
结构如下:
还有一点一定要注意,appcompat所需要的sdk也必须是最新的,不然不支持。最少21,刚刚我用19,里面的一些属性直接报错。切记。。。。
二、全局主题、样式
在application当中声明主题,表明是全局的概念,所有的activity都可以具有此属性。
Eclipse当中,在manifest中有版本控制,最小,目标版本等。
As当中,现在在build.gradle当中,如下图所示。而且,dependencies依赖于上面的compileSdkVersion buildToolsVersion (搭配相同)。
三、一些概念的理解
Widget 我们可以认为是一个部件。
PagerSlidingTabStrip :它是一个ViewPager 指示器,比ViewPageIndicator要好用的多,tab直接的过渡更加自然。
Toolbar是一种可定制的标题栏,actionbar比较死板,没多少人用。
Viewpager 和listview类似,一般我们将viewPager + fragmentPagerAdapter联合起来使用。
参考资料: Android中Styles、Themes、attrs介绍 http://www.open-open.com/lib/view/open1392260685837.html
Sytles 类似于css,把功能实现与外观分离开。Theme可由style来定义,放在application当中有全局的作用。
Attrs 是自定义参数,我们可以用它来对自定义属性进行定义。
一些控件假如不在xml中进行定义,我们就需要自己实例化,比如ImageButton tab = new ImageButton(getContext());
V7包的属性与android本身的属性不一样:
比如: android:colorPrimary ,这个是错误的,因为这个属性必须sdk21以上才支持,所以有了v7包。我们需要把android去掉才可以。
四、toolBarSytle无法找到解决方案
as出现这个问题,如何解决
错误竟然是我多定义了styles,原以为的适配用的,看来是理解错误。
必须是这样,我个人觉得同时有styles21 和 sytles 同时存在的时候,先适配sytles21,而我在sytles里面定义的东西在toolbar里面检索不到,所以出错。
所以解决方案:要么两个都定义,要么删掉一个。
五.Current min is xxxx ,call requires API xxx ?
所有这些问题都是因为兼容包的问题,因为我们默认导入的包都是低版本的包,但是随着版本的提高,我们需要适配的机型
比如说minSdk = 8,而上面需要的最小SDK版本是11.这个时候,我们必须引入v4包来解决问题。当然,有些高版本API可能还需要v7或者v13来做适配。
将刚刚的Fragmeng改为下面的 版本即可。
六、在fagment里面如何获取activity
必须要强转 MainActivity main = (MainActivity)getActivity(); //必须强转
最好是在onttach里面。
七、params 其实有多个,每一种布局里面有一套操作,都有相应的布局参数。Params
八、不同的IDE可能带来的问题:
解决方案:http://jingyan.baidu.com/article/7082dc1c77f979e40a89bddb.html
可能性:端口被占用
九、只有在toolbar上面设置的菜单才会有图标。
Toolbar说白了就是标题栏,导航栏一般用 PagerSlidingTabStrip (导航栏) + viewPage(类似listview的控件)做
覆盖与不覆盖的区别:
添加视图:
app:actionViewClass="android.support.v7.widget.SearchView"
menu菜单详解: http://www.open-open.com/lib/view/open1373981182669.html Android UI开发详解之ActionBar
其他资料: http://blog.csdn.net/lmj623565791/article/details/45303349 Android 5.x Theme 与 ToolBar 实战
http://blog.csdn.net/lmj623565791/article/details/42160391 Android 教你打造炫酷的ViewPagerIndicator 不仅仅是高仿MIUI
http://doc.okbase.net/HarryWeasley/archive/121430.html PagerSlidingTabStrip介绍及使用,让ViewPager更绚丽
程序代码:
参考资料: http://blog.csdn.net/codeeer/article/details/26447659 解决 Actionbar 溢出菜单不显示的问题
菜单溢出指的是 标题栏 右边的三点问题,有些手机不显示,按menu键才显示,这些都是实体键惹得祸,所以我们可以利用程序解决这个问题。
第一步:建立xml文件
Activity_main.xml文件
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity"> 7 8 <include layout="@layout/tool_bar" /> 9 10 <android.support.v4.widget.DrawerLayout 11 android:id="@+id/drawer" 12 android:layout_width="match_parent" 13 android:layout_height="match_parent"> 14 15 <!-- 内容界面 --> 16 17 <LinearLayout 18 android:layout_width="match_parent" 19 android:layout_height="match_parent" 20 android:orientation="vertical"> 21 22 <com.example.zhuxuekui.tool_bar.widget.PagerSlidingTabStrip 23 android:id="@+id/tabs" 24 android:layout_width="match_parent" 25 android:layout_height="48dip" 26 android:fillViewport="false"> 27 </com.example.zhuxuekui.tool_bar.widget.PagerSlidingTabStrip> 28 29 <RelativeLayout 30 android:layout_width="match_parent" 31 android:layout_height="match_parent"> 32 33 <android.support.v4.view.ViewPager 34 android:id="@+id/pager" 35 android:layout_width="match_parent" 36 android:layout_height="match_parent"></android.support.v4.view.ViewPager> 37 38 <EditText 39 android:layout_width="match_parent" 40 android:layout_height="wrap_content" /> 41 </RelativeLayout> 42 43 </LinearLayout> 44 45 <!-- 侧滑菜单内容 --> 46 47 <LinearLayout 48 android:id="@+id/drawer_view" 49 android:layout_width="match_parent" 50 android:layout_height="match_parent" 51 android:layout_gravity="start" 52 android:background="@color/material_pink_A200" 53 android:orientation="vertical" 54 android:padding="8dp"> 55 56 <TextView 57 android:layout_width="match_parent" 58 android:layout_height="match_parent" /> 59 </LinearLayout> 60 </android.support.v4.widget.DrawerLayout> 61 62 </LinearLayout>
menu-main.xml
1 <menu xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:tools="http://schemas.android.com/tools" 4 tools:context=".MainActivity" > 5 6 <item 7 android:id="@+id/ab_search" 8 android:orderInCategory="80" 9 android:title="action_search" 10 app:actionViewClass="android.support.v7.widget.SearchView" 11 app:showAsAction="ifRoom"/> 12 13 <!--<item--> 14 <!--android:id="@+id/ab_search"--> 15 <!--android:orderInCategory="80"--> 16 <!--android:title="action_search"--> 17 <!--android:icon="@mipmap/ab_search"--> 18 <!--app:actionViewClass="android.support.v7.widget.SearchView"--> 19 <!--app:showAsAction="ifRoom|collapseActionView"/>--> 20 21 <!--在toolbar上面设置才会有图标,且程序自动调用已经编辑好的程序--> 22 <item 23 android:id="@+id/action_share" 24 android:orderInCategory="90" 25 android:title="action_share" 26 app:actionProviderClass="android.support.v7.widget.ShareActionProvider" 27 app:showAsAction="ifRoom"/> 28 <item 29 android:id="@+id/action_settings" 30 android:orderInCategory="100" 31 android:title="action_settings" 32 app:showAsAction="never"/> 33 34 </menu>
sytle.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <!-- Base application theme. --> 4 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> 5 <!-- Customize your theme here. --> 6 7 <!-- toolbar(actionbar)颜色 --> 8 <item name="colorPrimary">#4876FF</item> 9 <!-- 状态栏颜色 --> 10 <item name="colorPrimaryDark">#3A5FCD</item> 11 <!-- 窗口的背景颜色 --> 12 <item name="android:windowBackground">@android:color/white</item> 13 <!-- SearchView --> 14 <item name="searchViewStyle">@style/MySearchViewStyle</item> 15 <!-- 颜色强调,设置界面控件按钮的强调颜色 --> 16 <item name="colorAccent">@color/material_pink_A200</item> 17 18 </style> 19 20 21 <style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView"> 22 <!-- 23 Background for the search query section (e.g. EditText) 24 <item name="queryBackground">...</item> 25 Background for the actions section (e.g. voice, submit) 26 <item name="submitBackground">...</item> 27 Close button icon 28 <item name="closeIcon">...</item> 29 Search button icon 30 <item name="searchIcon">...</item> 31 Go/commit button icon 32 <item name="goIcon">...</item> 33 Voice search button icon 34 <item name="voiceIcon">...</item> 35 Commit icon shown in the query suggestion row 36 <item name="commitIcon">...</item> 37 Layout for query suggestion rows 38 <item name="suggestionRowLayout">...</item> 39 --> 40 41 </style> 42 </resources>
第二步:
引入部件: PagerSlingTabStrip
1 package com.example.zhuxuekui.tool_bar.widget; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Canvas; 6 import android.graphics.Paint; 7 import android.graphics.Typeface; 8 import android.os.Build; 9 import android.os.Parcel; 10 import android.os.Parcelable; 11 import android.support.v4.view.ViewPager; 12 import android.util.AttributeSet; 13 import android.util.DisplayMetrics; 14 import android.util.TypedValue; 15 import android.view.Gravity; 16 import android.view.View; 17 import android.view.ViewTreeObserver; 18 import android.widget.HorizontalScrollView; 19 import android.widget.ImageButton; 20 import android.widget.LinearLayout; 21 import android.widget.TextView; 22 23 import com.example.zhuxuekui.tool_bar.R; 24 25 import java.util.Locale; 26 27 /** 28 * Created by zhuxuekui on 2015/6/3. 29 */ 30 public class PagerSlidingTabStrip extends HorizontalScrollView{ 31 32 public interface IconTabProvider { 33 public int getPageIconResId(int position); 34 } 35 36 // @formatter:off 37 private static final int[] ATTRS = new int[]{android.R.attr.textSize, android.R.attr.textColor}; 38 // @formatter:on 39 40 private LinearLayout.LayoutParams defaultTabLayoutParams; 41 private LinearLayout.LayoutParams expandedTabLayoutParams; 42 43 private final PageListener pageListener = new PageListener(); 44 public ViewPager.OnPageChangeListener delegatePageListener; 45 46 private LinearLayout tabsContainer; 47 private ViewPager pager; 48 49 private int tabCount; 50 51 private int currentPosition = 0; 52 private int selectedPosition = 0; 53 private float currentPositionOffset = 0f; 54 55 private Paint rectPaint; 56 private Paint dividerPaint; 57 58 private int indicatorColor = 0xFF666666; 59 private int underlineColor = 0x1A000000; 60 private int dividerColor = 0x1A000000; 61 62 private boolean shouldExpand = false; 63 private boolean textAllCaps = true; 64 65 private int scrollOffset = 52; 66 private int indicatorHeight = 8; 67 private int underlineHeight = 2; 68 private int dividerPadding = 12; 69 private int tabPadding = 24; 70 private int dividerWidth = 1; 71 72 private int tabTextSize = 12; 73 private int tabTextColor = 0xFF666666; 74 private int selectedTabTextColor = 0xFF666666; 75 private Typeface tabTypeface = null; 76 private int tabTypefaceStyle = Typeface.NORMAL; 77 78 private int lastScrollX = 0; 79 80 private int tabBackgroundResId = R.drawable.background_tab; 81 82 private Locale locale; 83 84 public PagerSlidingTabStrip(Context context) { 85 this(context, null); 86 } 87 88 public PagerSlidingTabStrip(Context context, AttributeSet attrs) { 89 this(context, attrs, 0); 90 } 91 92 public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) { 93 super(context, attrs, defStyle); 94 95 setFillViewport(true); 96 setWillNotDraw(false); 97 98 tabsContainer = new LinearLayout(context); 99 tabsContainer.setOrientation(LinearLayout.HORIZONTAL); 100 tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); 101 addView(tabsContainer); 102 103 DisplayMetrics dm = getResources().getDisplayMetrics(); 104 105 scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm); 106 indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm); 107 underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm); 108 dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm); 109 tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm); 110 dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm); 111 tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm); 112 113 // get system attrs (android:textSize and android:textColor) 114 115 TypedArray a = context.obtainStyledAttributes(attrs, ATTRS); 116 117 tabTextSize = a.getDimensionPixelSize(0, tabTextSize); 118 tabTextColor = a.getColor(1, tabTextColor); 119 120 a.recycle(); 121 122 // get custom attrs 123 124 a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip); 125 126 indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor); 127 underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor); 128 dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor); 129 indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, 130 indicatorHeight); 131 underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, 132 underlineHeight); 133 dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, 134 dividerPadding); 135 tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, 136 tabPadding); 137 tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, 138 tabBackgroundResId); 139 shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand); 140 scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, 141 scrollOffset); 142 textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps); 143 144 a.recycle(); 145 146 rectPaint = new Paint(); 147 rectPaint.setAntiAlias(true); 148 rectPaint.setStyle(Paint.Style.FILL); 149 150 dividerPaint = new Paint(); 151 dividerPaint.setAntiAlias(true); 152 dividerPaint.setStrokeWidth(dividerWidth); 153 154 defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, 155 LayoutParams.MATCH_PARENT); 156 expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f); 157 158 if (locale == null) { 159 locale = getResources().getConfiguration().locale; 160 } 161 } 162 163 public void setViewPager(ViewPager pager) { 164 this.pager = pager; 165 166 if (pager.getAdapter() == null) { 167 throw new IllegalStateException("ViewPager does not have adapter instance."); 168 } 169 170 pager.setOnPageChangeListener(pageListener); 171 172 notifyDataSetChanged(); 173 } 174 175 public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) { 176 this.delegatePageListener = listener; 177 } 178 179 public void notifyDataSetChanged() { 180 181 tabsContainer.removeAllViews(); 182 183 tabCount = pager.getAdapter().getCount(); 184 185 for (int i = 0; i < tabCount; i++) { 186 187 if (pager.getAdapter() instanceof IconTabProvider) { 188 addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i)); 189 } else { 190 addTextTab(i, pager.getAdapter().getPageTitle(i).toString()); 191 } 192 193 } 194 195 updateTabStyles(); 196 197 getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 198 199 @Override 200 public void onGlobalLayout() { 201 getViewTreeObserver().removeGlobalOnLayoutListener(this); 202 currentPosition = pager.getCurrentItem(); 203 scrollToChild(currentPosition, 0); 204 } 205 }); 206 207 } 208 209 private void addTextTab(final int position, String title) { 210 211 TextView tab = new TextView(getContext()); 212 tab.setText(title); 213 tab.setGravity(Gravity.CENTER); 214 tab.setSingleLine(); 215 addTab(position, tab); 216 } 217 218 private void addIconTab(final int position, int resId) { 219 220 ImageButton tab = new ImageButton(getContext()); 221 tab.setImageResource(resId); 222 223 addTab(position, tab); 224 225 } 226 227 private void addTab(final int position, View tab) { 228 tab.setFocusable(true); 229 tab.setOnClickListener(new OnClickListener() { 230 @Override 231 public void onClick(View v) { 232 pager.setCurrentItem(position); 233 } 234 }); 235 236 tab.setPadding(tabPadding, 0, tabPadding, 0); 237 tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams); 238 } 239 240 private void updateTabStyles() { 241 242 for (int i = 0; i < tabCount; i++) { 243 244 View v = tabsContainer.getChildAt(i); 245 246 v.setBackgroundResource(tabBackgroundResId); 247 248 if (v instanceof TextView) { 249 250 TextView tab = (TextView) v; 251 tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize); 252 tab.setTypeface(tabTypeface, tabTypefaceStyle); 253 tab.setTextColor(tabTextColor); 254 255 // setAllCaps() is only available from API 14, so the upper case 256 // is made manually if we are on a 257 // pre-ICS-build 258 if (textAllCaps) { 259 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 260 tab.setAllCaps(true); 261 } else { 262 tab.setText(tab.getText().toString().toUpperCase(locale)); 263 } 264 } 265 if (i == selectedPosition) { 266 tab.setTextColor(selectedTabTextColor); 267 } 268 } 269 } 270 271 } 272 273 private void scrollToChild(int position, int offset) { 274 275 if (tabCount == 0) { 276 return; 277 } 278 279 int newScrollX = tabsContainer.getChildAt(position).getLeft() + offset; 280 281 if (position > 0 || offset > 0) { 282 newScrollX -= scrollOffset; 283 } 284 285 if (newScrollX != lastScrollX) { 286 lastScrollX = newScrollX; 287 scrollTo(newScrollX, 0); 288 } 289 290 } 291 292 @Override 293 protected void onDraw(Canvas canvas) { 294 super.onDraw(canvas); 295 296 if (isInEditMode() || tabCount == 0) { 297 return; 298 } 299 300 final int height = getHeight(); 301 302 // draw underline 303 rectPaint.setColor(underlineColor); 304 canvas.drawRect(0, height - underlineHeight, tabsContainer.getWidth(), height, rectPaint); 305 306 // draw indicator line 307 rectPaint.setColor(indicatorColor); 308 309 // default: line below current tab 310 View currentTab = tabsContainer.getChildAt(currentPosition); 311 float lineLeft = currentTab.getLeft(); 312 float lineRight = currentTab.getRight(); 313 314 // if there is an offset, start interpolating left and right coordinates 315 // between current and next tab 316 if (currentPositionOffset > 0f && currentPosition < tabCount - 1) { 317 318 View nextTab = tabsContainer.getChildAt(currentPosition + 1); 319 final float nextTabLeft = nextTab.getLeft(); 320 final float nextTabRight = nextTab.getRight(); 321 322 lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft); 323 lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight); 324 } 325 326 canvas.drawRect(lineLeft, height - indicatorHeight, lineRight, height, rectPaint); 327 328 // draw divider 329 330 dividerPaint.setColor(dividerColor); 331 for (int i = 0; i < tabCount - 1; i++) { 332 View tab = tabsContainer.getChildAt(i); 333 canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, 334 dividerPaint); 335 } 336 } 337 338 private class PageListener implements ViewPager.OnPageChangeListener { 339 340 @Override 341 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 342 currentPosition = position; 343 currentPositionOffset = positionOffset; 344 345 scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth())); 346 347 invalidate(); 348 349 if (delegatePageListener != null) { 350 delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels); 351 } 352 } 353 354 @Override 355 public void onPageScrollStateChanged(int state) { 356 if (state == ViewPager.SCROLL_STATE_IDLE) { 357 scrollToChild(pager.getCurrentItem(), 0); 358 } 359 360 if (delegatePageListener != null) { 361 delegatePageListener.onPageScrollStateChanged(state); 362 } 363 } 364 365 @Override 366 public void onPageSelected(int position) { 367 selectedPosition = position; 368 updateTabStyles(); 369 if (delegatePageListener != null) { 370 delegatePageListener.onPageSelected(position); 371 } 372 } 373 374 } 375 376 public void setIndicatorColor(int indicatorColor) { 377 this.indicatorColor = indicatorColor; 378 invalidate(); 379 } 380 381 public void setIndicatorColorResource(int resId) { 382 this.indicatorColor = getResources().getColor(resId); 383 invalidate(); 384 } 385 386 public int getIndicatorColor() { 387 return this.indicatorColor; 388 } 389 390 public void setIndicatorHeight(int indicatorLineHeightPx) { 391 this.indicatorHeight = indicatorLineHeightPx; 392 invalidate(); 393 } 394 395 public int getIndicatorHeight() { 396 return indicatorHeight; 397 } 398 399 public void setUnderlineColor(int underlineColor) { 400 this.underlineColor = underlineColor; 401 invalidate(); 402 } 403 404 public void setUnderlineColorResource(int resId) { 405 this.underlineColor = getResources().getColor(resId); 406 invalidate(); 407 } 408 409 public int getUnderlineColor() { 410 return underlineColor; 411 } 412 413 public void setDividerColor(int dividerColor) { 414 this.dividerColor = dividerColor; 415 invalidate(); 416 } 417 418 public void setDividerColorResource(int resId) { 419 this.dividerColor = getResources().getColor(resId); 420 invalidate(); 421 } 422 423 public int getDividerColor() { 424 return dividerColor; 425 } 426 427 public void setUnderlineHeight(int underlineHeightPx) { 428 this.underlineHeight = underlineHeightPx; 429 invalidate(); 430 } 431 432 public int getUnderlineHeight() { 433 return underlineHeight; 434 } 435 436 public void setDividerPadding(int dividerPaddingPx) { 437 this.dividerPadding = dividerPaddingPx; 438 invalidate(); 439 } 440 441 public int getDividerPadding() { 442 return dividerPadding; 443 } 444 445 public void setScrollOffset(int scrollOffsetPx) { 446 this.scrollOffset = scrollOffsetPx; 447 invalidate(); 448 } 449 450 public int getScrollOffset() { 451 return scrollOffset; 452 } 453 454 public void setShouldExpand(boolean shouldExpand) { 455 this.shouldExpand = shouldExpand; 456 notifyDataSetChanged(); 457 } 458 459 public boolean getShouldExpand() { 460 return shouldExpand; 461 } 462 463 public boolean isTextAllCaps() { 464 return textAllCaps; 465 } 466 467 public void setAllCaps(boolean textAllCaps) { 468 this.textAllCaps = textAllCaps; 469 } 470 471 public void setTextSize(int textSizePx) { 472 this.tabTextSize = textSizePx; 473 updateTabStyles(); 474 } 475 476 public int getTextSize() { 477 return tabTextSize; 478 } 479 480 public void setTextColor(int textColor) { 481 this.tabTextColor = textColor; 482 updateTabStyles(); 483 } 484 485 public void setTextColorResource(int resId) { 486 this.tabTextColor = getResources().getColor(resId); 487 updateTabStyles(); 488 } 489 490 public int getTextColor() { 491 return tabTextColor; 492 } 493 494 public void setSelectedTextColor(int textColor) { 495 this.selectedTabTextColor = textColor; 496 updateTabStyles(); 497 } 498 499 public void setSelectedTextColorResource(int resId) { 500 this.selectedTabTextColor = getResources().getColor(resId); 501 updateTabStyles(); 502 } 503 504 public int getSelectedTextColor() { 505 return selectedTabTextColor; 506 } 507 508 public void setTypeface(Typeface typeface, int style) { 509 this.tabTypeface = typeface; 510 this.tabTypefaceStyle = style; 511 updateTabStyles(); 512 } 513 514 public void setTabBackground(int resId) { 515 this.tabBackgroundResId = resId; 516 updateTabStyles(); 517 } 518 519 public int getTabBackground() { 520 return tabBackgroundResId; 521 } 522 523 public void setTabPaddingLeftRight(int paddingPx) { 524 this.tabPadding = paddingPx; 525 updateTabStyles(); 526 } 527 528 public int getTabPaddingLeftRight() { 529 return tabPadding; 530 } 531 532 @Override 533 public void onRestoreInstanceState(Parcelable state) { 534 SavedState savedState = (SavedState) state; 535 super.onRestoreInstanceState(savedState.getSuperState()); 536 currentPosition = savedState.currentPosition; 537 requestLayout(); 538 } 539 540 @Override 541 public Parcelable onSaveInstanceState() { 542 Parcelable superState = super.onSaveInstanceState(); 543 SavedState savedState = new SavedState(superState); 544 savedState.currentPosition = currentPosition; 545 return savedState; 546 } 547 548 static class SavedState extends BaseSavedState { 549 int currentPosition; 550 551 public SavedState(Parcelable superState) { 552 super(superState); 553 } 554 555 private SavedState(Parcel in) { 556 super(in); 557 currentPosition = in.readInt(); 558 } 559 560 @Override 561 public void writeToParcel(Parcel dest, int flags) { 562 super.writeToParcel(dest, flags); 563 dest.writeInt(currentPosition); 564 } 565 566 public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { 567 @Override 568 public SavedState createFromParcel(Parcel in) { 569 return new SavedState(in); 570 } 571 572 @Override 573 public SavedState[] newArray(int size) { 574 return new SavedState[size]; 575 } 576 }; 577 } 578 }
定义基类 BaseCardFragment:
1 package com.example.zhuxuekui.tool_bar; 2 3 import android.os.Bundle; 4 import android.support.v4.app.Fragment; 5 import android.util.TypedValue; 6 import android.view.Gravity; 7 import android.view.LayoutInflater; 8 import android.view.View; 9 import android.view.ViewGroup; 10 import android.widget.FrameLayout; 11 import android.widget.TextView; 12 13 /** 14 * Created by zhuxuekui on 2015/6/3. 15 */ 16 17 //每次都会new出一个fragment,这是一个基类 18 public class BaseCardFragment extends Fragment{ 19 20 private static final String ARG_POSITION = "position"; 21 22 private int position; 23 private static final int[] drawables = {R.mipmap.frag1, R.mipmap.frag2, R.mipmap.frag3, R.mipmap.frag4, 24 R.mipmap.f, R.mipmap.fo, R.mipmap.s}; 25 26 public static BaseCardFragment newInstance(int position) { 27 BaseCardFragment f = new BaseCardFragment(); 28 Bundle b = new Bundle(); 29 b.putInt(ARG_POSITION, position); 30 f.setArguments(b); 31 return f; 32 } 33 34 @Override 35 public void onCreate(Bundle savedInstanceState) { 36 super.onCreate(savedInstanceState); 37 position = getArguments().getInt(ARG_POSITION); 38 } 39 40 @Override 41 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 42 FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); 43 44 FrameLayout fl = new FrameLayout(getActivity()); 45 fl.setLayoutParams(params); 46 fl.setBackgroundResource(drawables[position]); 47 final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources() 48 .getDisplayMetrics()); 49 50 TextView v = new TextView(getActivity()); 51 params.setMargins(margin, margin, margin, margin); 52 v.setLayoutParams(params); 53 v.setLayoutParams(params); 54 v.setGravity(Gravity.BOTTOM); 55 v.setText("fragment " + (position + 1)); 56 57 fl.addView(v); 58 return fl; 59 } 60 61 /** 62 * 提供当前Fragment的主色调的Bitmap对象,供Palette解析颜色 63 * 64 * @return 65 */ 66 public static int getBackgroundBitmapPosition(int selectViewPagerItem) { 67 return drawables[selectViewPagerItem]; 68 } 69 }
定义主类:
1 package com.xwj.toolbardemo; 2 3 import android.annotation.SuppressLint; 4 import android.content.Intent; 5 import android.graphics.Bitmap; 6 import android.graphics.BitmapFactory; 7 import android.graphics.Color; 8 import android.os.Bundle; 9 import android.support.v4.app.Fragment; 10 import android.support.v4.app.FragmentManager; 11 import android.support.v4.app.FragmentPagerAdapter; 12 import android.support.v4.view.MenuItemCompat; 13 import android.support.v4.view.ViewPager; 14 import android.support.v4.widget.DrawerLayout; 15 import android.support.v7.app.ActionBarActivity; 16 import android.support.v7.app.ActionBarDrawerToggle; 17 import android.support.v7.graphics.Palette; 18 import android.support.v7.widget.ShareActionProvider; 19 import android.support.v7.widget.Toolbar; 20 import android.util.Log; 21 import android.util.TypedValue; 22 import android.view.Menu; 23 import android.view.MenuItem; 24 import android.view.View; 25 import android.view.ViewConfiguration; 26 import android.view.Window; 27 import android.widget.Toast; 28 29 import com.xwj.toolbardemo.widget.PagerSlidingTabStrip; 30 31 import java.lang.reflect.Field; 32 33 /** 34 * 此Demo 用到的控件: 35 * ToolBar + Drawer 36 * PagerSlidingTabStrip + Palette(调色板) 37 * 实现抽屉与变色效果 38 */ 39 40 public class MainActivity extends ActionBarActivity { 41 42 //抽屉效果 侧边栏 43 private DrawerLayout mDrawerLayout; 44 //actionbar和抽屉的链接效果,触发控件 45 private ActionBarDrawerToggle mDrawerToggle; 46 //标题栏分享图标 47 private ShareActionProvider mShareActionProvider; 48 //菜单栏控件 49 private PagerSlidingTabStrip mPagerSlidingTabStrip; 50 //整个内容控件结合fragment一起使用 51 private ViewPager mViewPager; 52 //标题栏 53 private Toolbar mToolbar; 54 55 @Override 56 protected void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 /** 59 * DrawerLayout不覆盖Toolbar 60 */ 61 setContentView(R.layout.activity_main); 62 /** 63 * DrawerLayout覆盖Toolbar 64 */ 65 //setContentView(R.layout.activity_main_toggleover); 66 67 //初始化控件 68 initViews(); 69 //处理溢出菜单问题 就是右侧三点问题 70 setOverflowShowingAlways(); 71 } 72 73 private void initViews() { 74 mToolbar = (Toolbar) findViewById(R.id.toolbar); 75 // toolbar.setLogo(R.drawable.ic_launcher); 76 // 标题的文字需在setSupportActionBar之前,不然会无效 77 mToolbar.setTitle("ToolbarDemo"); 78 // toolbar.setSubtitle("副标题"); 79 setSupportActionBar(mToolbar);//标题栏 80 /* 上面的这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */ 81 // getSupportActionBar().setTitle("标题"); 82 // getSupportActionBar().setSubtitle("副标题"); 83 // getSupportActionBar().setLogo(R.drawable.ic_launcher); 84 85 //我们可以在Menu方法和onOptionsItemSelected中设置监听,下面实现和最底下的效果一致 86 /* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过下面的两个回调方法来处理 */ 87 // mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { 88 // @Override 89 // public boolean onMenuItemClick(MenuItem item) { 90 // switch (item.getItemId()) { 91 // case R.id.action_settings: 92 // Toast.makeText(MainActivity.this, "action_settings", Toast.LENGTH_SHORT).show(); 93 // break; 94 // case R.id.action_share: 95 // Toast.makeText(MainActivity.this, "action_share", Toast.LENGTH_SHORT).show(); 96 // break; 97 // default: 98 // break; 99 // } 100 // return true; 101 // } 102 // }); 103 // mToolbar.setOnCreateContextMenuListener(this); 104 getSupportActionBar().setHomeButtonEnabled(true); // 设置返回键可用 105 getSupportActionBar().setDisplayHomeAsUpEnabled(true); 106 /* findView */ 107 //抽屉布局,其实和toobar相关的,他们是嵌套的关系。 108 //actionbar的切换效果 toggle 触发的意思 109 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer); 110 mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open, 111 R.string.drawer_close) { 112 @Override 113 public void onDrawerOpened(View drawerView) { 114 super.onDrawerOpened(drawerView); 115 //当drawer页面打开的时候,京东的那个RunningMan动画就是在此时关闭和打开的 116 Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT).show(); 117 } 118 119 @Override 120 public void onDrawerClosed(View drawerView) { 121 super.onDrawerClosed(drawerView); 122 //当drawer页面关闭的时候 123 Toast.makeText(MainActivity.this, "关闭", Toast.LENGTH_SHORT).show(); 124 } 125 126 }; 127 //同步 128 mDrawerToggle.syncState(); 129 //将DrawerLayout与DrawerToggle建立联系 130 mDrawerLayout.setDrawerListener(mDrawerToggle); 131 132 //下面是ViewPager + mPagerSlidingTabStrip 部分 133 mPagerSlidingTabStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs); 134 mViewPager = (ViewPager) findViewById(R.id.pager); 135 mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); 136 //建立两者关系 137 mPagerSlidingTabStrip.setViewPager(mViewPager); 138 mPagerSlidingTabStrip.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { 139 140 @Override 141 public void onPageSelected(int arg0) { 142 colorChange(arg0); 143 } 144 145 @Override 146 public void onPageScrolled(int arg0, float arg1, int arg2) { 147 } 148 149 @Override 150 public void onPageScrollStateChanged(int arg0) { 151 } 152 }); 153 //设置默认配置 154 initTabsValue(); 155 } 156 157 /** 158 * mPagerSlidingTabStrip默认值配置 159 */ 160 private void initTabsValue() { 161 // 底部游标颜色 162 mPagerSlidingTabStrip.setIndicatorColor(Color.BLUE); 163 // tab的分割线颜色 164 mPagerSlidingTabStrip.setDividerColor(Color.TRANSPARENT); 165 // tab背景 166 mPagerSlidingTabStrip.setBackgroundColor(Color.parseColor("#4876FF")); 167 // tab底线高度 168 mPagerSlidingTabStrip.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 169 1, getResources().getDisplayMetrics())); 170 // 游标高度 171 mPagerSlidingTabStrip.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 172 5, getResources().getDisplayMetrics())); 173 // 选中的文字颜色 174 mPagerSlidingTabStrip.setSelectedTextColor(Color.WHITE); 175 // 正常文字颜色 176 mPagerSlidingTabStrip.setTextColor(Color.BLACK); 177 } 178 179 /** 180 * 界面颜色的更改 181 */ 182 @SuppressLint("NewApi") 183 private void colorChange(int position) { 184 // 用来提取颜色的Bitmap 185 final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 186 BaseCardFragment.getBackgroundBitmapPosition(position)); 187 // Palette的部分 188 Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() { 189 /** 190 * 提取完之后的回调方法 191 */ 192 @Override 193 public void onGenerated(Palette palette) { 194 if (palette != null) { 195 Palette.Swatch vibrant = palette.getVibrantSwatch(); 196 /* 界面颜色UI统一性处理,看起来更Material一些 */ 197 mPagerSlidingTabStrip.setBackgroundColor(vibrant.getRgb()); 198 mPagerSlidingTabStrip.setTextColor(vibrant.getTitleTextColor()); 199 // 其中状态栏、游标、底部导航栏的颜色需要加深一下,也可以不加,具体情况在代码之后说明 200 mPagerSlidingTabStrip.setIndicatorColor(colorBurn(vibrant.getRgb())); 201 202 mToolbar.setBackgroundColor(vibrant.getRgb()); 203 if (android.os.Build.VERSION.SDK_INT >= 21) { 204 Window window = getWindow(); 205 // API>=21以上才能实现此效果,当然也可以用开源的状态栏SystemBarTintManager实现(支持4.4以上) 206 window.setStatusBarColor(colorBurn(vibrant.getRgb()));//颜色加深 207 window.setNavigationBarColor(colorBurn(vibrant.getRgb())); 208 } 209 // 释放掉,避免卡顿 210 bitmap.recycle(); 211 } 212 213 } 214 }); 215 216 } 217 218 /** 219 * 颜色加深处理 220 * 221 * @param RGBValues RGB的值,由alpha(透明度)、red(红)、green(绿)、blue(蓝)构成, 222 * Android中我们一般使用它的16进制, 223 * 例如:"#FFAABBCC",最左边到最右每两个字母就是代表alpha(透明度)、 224 * red(红)、green(绿)、blue(蓝)。每种颜色值占一个字节(8位),值域0~255 225 * 所以下面使用移位的方法可以得到每种颜色的值,然后每种颜色值减小一下,在合成RGB颜色,颜色就会看起来深一些了 226 * @return 227 */ 228 private int colorBurn(int RGBValues) { 229 Log.e("-----",RGBValues+""); 230 int alpha = RGBValues >> 24; 231 232 int red = RGBValues >> 16 & 0xFF; 233 Log.e("--red---",red+""); 234 235 int green = RGBValues >> 8 & 0xFF; 236 Log.e("--green---",green+""); 237 238 int blue = RGBValues & 0xFF; 239 Log.e("--blue---",blue+""); 240 red = (int) Math.floor(red * (1 - 0.1)); 241 green = (int) Math.floor(green * (1 - 0.1)); 242 blue = (int) Math.floor(blue * (1 - 0.1)); 243 return Color.rgb(red, green, blue); 244 } 245 246 247 @Override 248 public boolean onCreateOptionsMenu(Menu menu) { 249 getMenuInflater().inflate(R.menu.menu_main, menu); 250 mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menu 251 .findItem(R.id.action_share)); 252 Intent intent = new Intent(Intent.ACTION_SEND); 253 intent.setType("text/*"); 254 mShareActionProvider.setShareIntent(intent); 255 256 MenuItem searchItem = menu.findItem(R.id.ab_search); 257 258 //为menu事件设置监听 259 MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { 260 @Override 261 public boolean onMenuItemActionExpand(MenuItem item) { 262 Toast.makeText(MainActivity.this, "打开", Toast.LENGTH_SHORT).show(); 263 return true; 264 } 265 266 @Override 267 public boolean onMenuItemActionCollapse(MenuItem item) { 268 return true; 269 } 270 }); 271 272 return super.onCreateOptionsMenu(menu); 273 } 274 275 //为toolbar上面的每一个mune设置事件 276 @Override 277 public boolean onOptionsItemSelected(MenuItem item) { 278 // Handle action bar item clicks here. The action bar will 279 // automatically handle clicks on the Home/Up button, so long 280 // as you specify a parent activity in AndroidManifest.xml. 281 switch (item.getItemId()) { 282 case R.id.action_settings: 283 Toast.makeText(MainActivity.this, "action_settings", Toast.LENGTH_SHORT).show(); 284 break; 285 case R.id.action_share: 286 Toast.makeText(MainActivity.this, "action_share", Toast.LENGTH_SHORT).show(); 287 break; 288 case R.id.ab_search: 289 Toast.makeText(MainActivity.this, "ab_search", Toast.LENGTH_SHORT).show(); 290 break; 291 default: 292 break; 293 } 294 295 return super.onOptionsItemSelected(item); 296 } 297 298 299 /** 300 * 处理溢出菜单问题 301 */ 302 private void setOverflowShowingAlways() { 303 try { 304 ViewConfiguration config = ViewConfiguration.get(this); 305 Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey"); 306 menuKeyField.setAccessible(true); 307 menuKeyField.setBoolean(config, false); 308 } catch (Exception e) { 309 e.printStackTrace(); 310 } 311 } 312 313 //每次点一下Viewpager就会新建一个fragment, 把pagerAdpater 想象成 arrayAdapter。 314 public class MyPagerAdapter extends FragmentPagerAdapter { 315 private final String[] TITLES = {"推荐", "分类", "本月热榜", "热门推荐", "专栏", "热门收藏", "随缘"}; 316 317 public MyPagerAdapter(FragmentManager fm) { 318 super(fm); 319 } 320 321 @Override 322 public CharSequence getPageTitle(int position) { 323 return TITLES[position]; 324 } 325 326 @Override 327 public Fragment getItem(int position) { 328 return BaseCardFragment.newInstance(position); 329 } 330 331 @Override 332 public int getCount() { 333 return TITLES.length; 334 } 335 } 336 }