当前位置:   article > 正文

Android渐变标题栏的实现_android 设置navigationbar渐变

android 设置navigationbar渐变

Android4.4以上推出了Toolbar,改变程序的style属性就可以给手机的标题栏填充颜色,可以是你设置好的系统的主题色,也可以是自己填充的颜色,其实这个效果在iOS早就有了,但在Android中还是很少见的。在iOS中,最常见的Navigationbar的效果就是一个转场动画(多出现于两个界面切换的时候),一个就是随着手势滑动背景渐变(多出现于详情页)。今天我们就来实现下大多出现于详情页的这个渐变效果的标题栏。

具体效果见:点击打开链接

接下来我们就来实现这个效果。

首先,我们要先把手机上面的状态栏的颜色背景隐藏掉,在这里会有一个坑,在小米和魅族手机里,好想说是MIUI6以上,上面状态栏上的时间啊什么的文字默认的颜色是白色,如果你的Toolbar的背景是相对深颜色的话,是没有问题的,但是如果你的Toolbar是相对浅的背景颜色,那么很可能这些时间文字会显示不出来,那么就要修改上面状态栏的颜色了。具体可以参考这篇:点击打开链接

先在style里设置,这是我的style.xml:

 

  1. <resources>
  2. <style name="AppTheme" parent="Theme.AppCompat.Light">
  3. <!-- Customize your theme here. -->
  4. <item name="android:windowBackground">@color/devide</item>
  5. <item name="windowActionBar">false</item>
  6. <item name="windowNoTitle">true</item>
  7. <item name="android:windowNoTitle">true</item>
  8. <item name="android:textColorSecondary">@color/white</item>
  9. <item name="android:textColorPrimary">@color/white</item>
  10. <item name="toolbarStyle">@style/ToolbarStyle</item>
  11. <item name="colorControlNormal">@android:color/white</item>
  12. </style>
  13. <style name="ToolbarStyle" parent="Widget.AppCompat.Toolbar">
  14. <item name="contentInsetStart">0dp</item>
  15. <item name="colorControlNormal">@android:color/white</item>
  16. </style>
  17. </resources>


接下来我们就要把状态栏设置为透明:

 

 

  1. private void setTranslucentWindows(Activity activity) {
  2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  3. //透明状态栏
  4. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  5. }
  6. }


以下是我写的标题栏的布局文件:

 

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content">
  6. <RelativeLayout
  7. android:id="@+id/layout_toolbar_my_container"
  8. android:fitsSystemWindows="true"
  9. android:layout_width="match_parent"
  10. android:layout_height="wrap_content"
  11. android:background="@color/base"
  12. android:paddingBottom="0dp">
  13. <android.support.v7.widget.Toolbar
  14. android:layout_width="match_parent"
  15. android:layout_height="44dp"
  16. android:elevation="0dp">
  17. <RelativeLayout
  18. android:layout_width="match_parent"
  19. android:layout_height="match_parent">
  20. <RelativeLayout
  21. android:id="@+id/layout_toolbar_details_back"
  22. android:layout_width="60dp"
  23. android:onClick="onBack"
  24. android:layout_height="match_parent">
  25. <ImageView
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:layout_centerVertical="true"
  29. android:layout_marginLeft="10dp"
  30. android:src="@mipmap/btn_back" />
  31. </RelativeLayout>
  32. <TextView
  33. android:visibility="gone"
  34. android:id="@+id/text_toolbar_index"
  35. android:layout_centerInParent="true"
  36. android:layout_width="wrap_content"
  37. android:layout_height="wrap_content"
  38. android:text="我是一个标题"
  39. android:textColor="@color/white"
  40. android:textSize="17dp" />
  41. </RelativeLayout>
  42. </android.support.v7.widget.Toolbar>
  43. </RelativeLayout>
  44. </RelativeLayout>


将标题栏的布局文件引入到我们界面的布局文件里,我们是相当于在recyclerView的header上叠加了一层透明的标题栏,这里对recyclerView的adapter的所有操作我都集成了一个通用格式来进行操作,方便很多。我给recyclerView添加了一个header,在这里为了简便,用imageView来代替了轮播图。为了达到渐变的效果,我们要去监听滑动事件,是否滑动到imageView的高度,也就是把imageView隐藏,当正好隐藏的时候标题栏的文字将出现(这个一般看交互,如果大图下面有标题,一般建议标题覆盖以后,标题栏上的标题再显示),当前的y与整体要滑动距离的百分比来控制标题栏的背景透明度。在这里要注意,当onCreate方法的时候,一个view的getMeasuredHeight()方法或者宽度的方法获得的都是0,因为这个时候你的view还没有draw上去,只有当onCreate方法执行完了以后,控件才会被onMeasure。所以有两种策略,一种是我以下代码实现的,等view的onMeasure好了以后再去调用方法,还有一种是去注册一个ViewTreeObserver的监听回调,具体大家可以去自行百度。ok,下面贴上Activity里的代码:

 

 

  1. public class MainActivity extends AppCompatActivity {
  2. @Bind(R.id.recycler)
  3. RecyclerView recyclerView;
  4. @Bind(R.id.layout_toolbar_my_container)
  5. RelativeLayout layoutToolBarBackground;
  6. @Bind(R.id.text_toolbar_index)
  7. TextView centerText;
  8. private ArrayList<Model> modelList = new ArrayList<>();
  9. private MyRecyclerAdapter adapter;
  10. private LinearLayoutManager layoutManager;
  11. private int itemIndex;
  12. private ToolBarBackgroundController toolBarBackgroundController;
  13. private int anchorHeight;
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. setTranslucentWindows(this);
  19. ButterKnife.bind(this);
  20. layoutManager = new LinearLayoutManager(this.getApplicationContext());
  21. layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  22. recyclerView.setLayoutManager(layoutManager);
  23. recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST,
  24. R.drawable.devide_line_gray, 0));
  25. initHead();
  26. initData();
  27. initView();
  28. }
  29. private void initHead() {
  30. layoutToolBarBackground.setBackgroundColor(Color.TRANSPARENT);
  31. toolBarBackgroundController = new ToolBarBackgroundController(layoutToolBarBackground);
  32. }
  33. public class ToolBarBackgroundController {
  34. private View layoutToolbar;
  35. public ToolBarBackgroundController(View layoutToolbar) {
  36. this.layoutToolbar = layoutToolbar;
  37. layoutToolbar.setBackgroundColor(Color.TRANSPARENT);
  38. }
  39. public void setTransparent(boolean needTransparent) {
  40. if (needTransparent) {
  41. //变透明
  42. centerText.setVisibility(View.GONE);
  43. } else {
  44. layoutToolbar.setBackgroundColor(getResources().getColor(R.color.base));
  45. centerText.setVisibility(View.VISIBLE);
  46. }
  47. }
  48. }
  49. private void setTranslucentWindows(Activity activity) {
  50. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  51. //透明状态栏
  52. activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  53. }
  54. }
  55. private int getStatusBarHeight(Context context) {
  56. int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
  57. if (resourceId > 0) {
  58. return context.getResources().getDimensionPixelSize(resourceId);
  59. } else return 0;
  60. }
  61. private void initData() {
  62. for (int i = 0; i < 20; i++) {
  63. Model model = new Model();
  64. model.setName("jjq" + i);
  65. model.setDesc("哈哈哈哈哈哈哈哈");
  66. modelList.add(model);
  67. }
  68. }
  69. private void initView() {
  70. if (adapter == null) {
  71. adapter = new MyRecyclerAdapter();
  72. } else {
  73. adapter.notifyDataSetChanged();
  74. }
  75. adapter.initData(false);
  76. adapter.appendData(modelList);
  77. recyclerView.setAdapter(adapter);
  78. recyclerView.addOnScrollListener(new OnScrollColorChangeListener());
  79. }
  80. private class OnScrollColorChangeListener extends RecyclerView.OnScrollListener {
  81. private boolean isTrans = true;
  82. private int y = 0;
  83. @Override
  84. public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
  85. super.onScrolled(recyclerView, dx, dy);
  86. if (anchorHeight != 0) {
  87. y += dy;
  88. boolean needTrans = y <= anchorHeight;
  89. if (needTrans != isTrans) {
  90. isTrans = needTrans;
  91. toolBarBackgroundController.setTransparent(needTrans);
  92. } else {
  93. if (y / anchorHeight < 1) {
  94. layoutToolBarBackground.setBackgroundColor(getResources().getColor(R.color.base));
  95. layoutToolBarBackground.getBackground().setAlpha((int) ((float) y / anchorHeight * 255));
  96. }
  97. }
  98. }
  99. }
  100. }
  101. private class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
  102. private final int TYPE_HEADER = 0x1000;
  103. private final int TYPE_NORMAL = 0x2000;
  104. private final int TYPE_FOOTER = 0x3000;
  105. private final int TYPE_EMPTY = 0x4000;
  106. private final int TYPE_THEME = 0x5000;
  107. private ArrayList<MyItemInfo> itemInfos;
  108. private boolean needFooter = false;
  109. private boolean hasFooter = false;
  110. public class MyItemInfo {
  111. int type;
  112. Model model;
  113. public MyItemInfo(int type, Model model) {
  114. this.type = type;
  115. this.model = model;
  116. }
  117. }
  118. public MyRecyclerAdapter() {
  119. itemInfos = new ArrayList<>();
  120. }
  121. public void initData(boolean needFooter) {
  122. this.needFooter = needFooter;
  123. this.hasFooter = false;
  124. int oldCount = itemInfos.size();
  125. itemInfos.clear();
  126. this.notifyItemRangeRemoved(0, oldCount);
  127. itemInfos.add(new MyItemInfo(TYPE_HEADER, null));
  128. //itemInfos.add(new MyItemInfo(TYPE_FOOTER, null));
  129. //this.notifyItemRangeInserted(0, 2);
  130. }
  131. public void appendData(ArrayList<Model> models) {
  132. int oldCount = itemInfos.size();
  133. if (hasFooter) {
  134. itemInfos.remove(oldCount - 1);
  135. this.notifyItemRemoved(oldCount - 1);
  136. oldCount--;
  137. }
  138. int size = models.size();
  139. for (int i = 0; i < size; i++) {
  140. itemInfos.add(new MyItemInfo(TYPE_NORMAL, models.get(i)));
  141. }
  142. this.notifyItemRangeInserted(oldCount + 1, size);
  143. if (needFooter) {
  144. itemInfos.add(new MyItemInfo(TYPE_FOOTER, null));
  145. this.notifyItemInserted(itemInfos.size() - 1);
  146. hasFooter = true;
  147. }
  148. }
  149. public void removeFooter() {
  150. int oldCount = itemInfos.size();
  151. itemInfos.remove(oldCount - 1);
  152. notifyItemRemoved(oldCount - 1);
  153. }
  154. public void appendEmptyView() {
  155. int oldCount = itemInfos.size();
  156. if (hasFooter) {
  157. itemInfos.remove(oldCount - 1);
  158. this.notifyItemRemoved(oldCount - 1);
  159. oldCount--;
  160. }
  161. itemInfos.add(new MyItemInfo(TYPE_EMPTY, null));
  162. notifyItemRangeInserted(oldCount, 1);
  163. }
  164. @Override
  165. public int getItemViewType(int position) {
  166. return itemInfos.get(position).type;
  167. }
  168. @Override
  169. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  170. LayoutInflater inflater = LayoutInflater.from(parent.getContext());
  171. View view = null;
  172. switch (viewType) {
  173. case TYPE_HEADER:
  174. view = inflater.inflate(R.layout.layout_main_recycler_head, parent, false);
  175. return new MyHeaderItemHolder(view, MainActivity.this);
  176. case TYPE_NORMAL:
  177. view = inflater.inflate(R.layout.layout_list_item, parent, false);
  178. return new NormalViewHolder(view);
  179. case TYPE_EMPTY:
  180. return null;
  181. case TYPE_FOOTER:
  182. return null;
  183. default:
  184. return null;
  185. }
  186. }
  187. @Override
  188. public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
  189. switch (viewHolder.getItemViewType()) {
  190. case TYPE_NORMAL:
  191. NormalViewHolder normalViewHolder = (NormalViewHolder) viewHolder;
  192. normalViewHolder.setContent(itemInfos.get(i).model, i);
  193. break;
  194. case TYPE_HEADER:
  195. MyHeaderItemHolder headerViewHolder = (MyHeaderItemHolder) viewHolder;
  196. headerViewHolder.setContent();
  197. break;
  198. case TYPE_FOOTER:
  199. case TYPE_EMPTY:
  200. break;
  201. default:
  202. break;
  203. }
  204. }
  205. @Override
  206. public int getItemCount() {
  207. return itemInfos.size();
  208. }
  209. private class EmptyItemHolder extends RecyclerView.ViewHolder {
  210. public EmptyItemHolder(View itemView) {
  211. super(itemView);
  212. }
  213. }
  214. private class MyHeaderItemHolder extends RecyclerView.ViewHolder {
  215. private Context context;
  216. private ImageView imageView;
  217. public MyHeaderItemHolder(View itemView, Context context) {
  218. super(itemView);
  219. this.context = context;
  220. imageView = (ImageView) itemView.findViewById(R.id.img_main_recycler_head_banner);
  221. imageView.post(new Runnable() {
  222. @Override
  223. public void run() {
  224. anchorHeight = imageView.getMeasuredHeight() - layoutToolBarBackground.getMeasuredHeight();
  225. }
  226. });
  227. }
  228. //填充头部内容
  229. public void setContent() {
  230. }
  231. }
  232. private class NormalViewHolder extends RecyclerView.ViewHolder {
  233. private Model model;
  234. private TextView nameView;
  235. private TextView descView;
  236. public NormalViewHolder(View itemView) {
  237. super(itemView);
  238. nameView = (TextView) itemView.findViewById(R.id.text_list_item_name);
  239. descView = (TextView) itemView.findViewById(R.id.text_list_item_desc);
  240. itemView.setOnClickListener(new OnItemClickListener());
  241. }
  242. public void setContent(Model model, int index) {
  243. this.model = model;
  244. nameView.setText(model.getName());
  245. descView.setText(model.getDesc());
  246. itemIndex = index;
  247. }
  248. private class OnItemClickListener implements View.OnClickListener {
  249. @Override
  250. public void onClick(View v) {
  251. }
  252. }
  253. }
  254. private class FooterViewHolder extends RecyclerView.ViewHolder {
  255. public FooterViewHolder(View itemView) {
  256. super(itemView);
  257. }
  258. }
  259. }
  260. }


ok,到这里demo就搞定了!当然如果你的标题栏上的文字太长的话,你也可以自己给textView加上跑马灯效果,很简单,不知道的人可以自行去谷歌百度,记得给textView加上焦点就可以了。

项目地址:点击打开链接

 

 

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号