赞
踩
Android4.4以上推出了Toolbar,改变程序的style属性就可以给手机的标题栏填充颜色,可以是你设置好的系统的主题色,也可以是自己填充的颜色,其实这个效果在iOS早就有了,但在Android中还是很少见的。在iOS中,最常见的Navigationbar的效果就是一个转场动画(多出现于两个界面切换的时候),一个就是随着手势滑动背景渐变(多出现于详情页)。今天我们就来实现下大多出现于详情页的这个渐变效果的标题栏。
具体效果见:点击打开链接
接下来我们就来实现这个效果。
首先,我们要先把手机上面的状态栏的颜色背景隐藏掉,在这里会有一个坑,在小米和魅族手机里,好想说是MIUI6以上,上面状态栏上的时间啊什么的文字默认的颜色是白色,如果你的Toolbar的背景是相对深颜色的话,是没有问题的,但是如果你的Toolbar是相对浅的背景颜色,那么很可能这些时间文字会显示不出来,那么就要修改上面状态栏的颜色了。具体可以参考这篇:点击打开链接
先在style里设置,这是我的style.xml:
- <resources>
-
- <style name="AppTheme" parent="Theme.AppCompat.Light">
- <!-- Customize your theme here. -->
- <item name="android:windowBackground">@color/devide</item>
- <item name="windowActionBar">false</item>
- <item name="windowNoTitle">true</item>
- <item name="android:windowNoTitle">true</item>
- <item name="android:textColorSecondary">@color/white</item>
- <item name="android:textColorPrimary">@color/white</item>
- <item name="toolbarStyle">@style/ToolbarStyle</item>-
- <item name="colorControlNormal">@android:color/white</item>
- </style>
-
- <style name="ToolbarStyle" parent="Widget.AppCompat.Toolbar">
- <item name="contentInsetStart">0dp</item>
- <item name="colorControlNormal">@android:color/white</item>
- </style>
-
- </resources>
接下来我们就要把状态栏设置为透明:
- private void setTranslucentWindows(Activity activity) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- //透明状态栏
- activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- }
- }
以下是我写的标题栏的布局文件:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <RelativeLayout
- android:id="@+id/layout_toolbar_my_container"
- android:fitsSystemWindows="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/base"
- android:paddingBottom="0dp">
-
- <android.support.v7.widget.Toolbar
- android:layout_width="match_parent"
- android:layout_height="44dp"
- android:elevation="0dp">
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <RelativeLayout
- android:id="@+id/layout_toolbar_details_back"
- android:layout_width="60dp"
- android:onClick="onBack"
- android:layout_height="match_parent">
-
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_marginLeft="10dp"
- android:src="@mipmap/btn_back" />
-
- </RelativeLayout>
-
- <TextView
- android:visibility="gone"
- android:id="@+id/text_toolbar_index"
- android:layout_centerInParent="true"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="我是一个标题"
- android:textColor="@color/white"
- android:textSize="17dp" />
-
- </RelativeLayout>
-
- </android.support.v7.widget.Toolbar>
-
- </RelativeLayout>
-
- </RelativeLayout>
将标题栏的布局文件引入到我们界面的布局文件里,我们是相当于在recyclerView的header上叠加了一层透明的标题栏,这里对recyclerView的adapter的所有操作我都集成了一个通用格式来进行操作,方便很多。我给recyclerView添加了一个header,在这里为了简便,用imageView来代替了轮播图。为了达到渐变的效果,我们要去监听滑动事件,是否滑动到imageView的高度,也就是把imageView隐藏,当正好隐藏的时候标题栏的文字将出现(这个一般看交互,如果大图下面有标题,一般建议标题覆盖以后,标题栏上的标题再显示),当前的y与整体要滑动距离的百分比来控制标题栏的背景透明度。在这里要注意,当onCreate方法的时候,一个view的getMeasuredHeight()方法或者宽度的方法获得的都是0,因为这个时候你的view还没有draw上去,只有当onCreate方法执行完了以后,控件才会被onMeasure。所以有两种策略,一种是我以下代码实现的,等view的onMeasure好了以后再去调用方法,还有一种是去注册一个ViewTreeObserver的监听回调,具体大家可以去自行百度。ok,下面贴上Activity里的代码:
- public class MainActivity extends AppCompatActivity {
-
- @Bind(R.id.recycler)
- RecyclerView recyclerView;
- @Bind(R.id.layout_toolbar_my_container)
- RelativeLayout layoutToolBarBackground;
- @Bind(R.id.text_toolbar_index)
- TextView centerText;
-
- private ArrayList<Model> modelList = new ArrayList<>();
- private MyRecyclerAdapter adapter;
- private LinearLayoutManager layoutManager;
- private int itemIndex;
- private ToolBarBackgroundController toolBarBackgroundController;
- private int anchorHeight;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- setTranslucentWindows(this);
- ButterKnife.bind(this);
- layoutManager = new LinearLayoutManager(this.getApplicationContext());
- layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
- recyclerView.setLayoutManager(layoutManager);
- recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST,
- R.drawable.devide_line_gray, 0));
- initHead();
- initData();
- initView();
- }
-
- private void initHead() {
- layoutToolBarBackground.setBackgroundColor(Color.TRANSPARENT);
- toolBarBackgroundController = new ToolBarBackgroundController(layoutToolBarBackground);
- }
-
- public class ToolBarBackgroundController {
-
- private View layoutToolbar;
-
- public ToolBarBackgroundController(View layoutToolbar) {
- this.layoutToolbar = layoutToolbar;
- layoutToolbar.setBackgroundColor(Color.TRANSPARENT);
- }
-
- public void setTransparent(boolean needTransparent) {
- if (needTransparent) {
- //变透明
- centerText.setVisibility(View.GONE);
- } else {
- layoutToolbar.setBackgroundColor(getResources().getColor(R.color.base));
- centerText.setVisibility(View.VISIBLE);
- }
- }
- }
-
- private void setTranslucentWindows(Activity activity) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- //透明状态栏
- activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
- }
- }
-
- private int getStatusBarHeight(Context context) {
- int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
- if (resourceId > 0) {
- return context.getResources().getDimensionPixelSize(resourceId);
- } else return 0;
- }
-
- private void initData() {
- for (int i = 0; i < 20; i++) {
- Model model = new Model();
- model.setName("jjq" + i);
- model.setDesc("哈哈哈哈哈哈哈哈");
- modelList.add(model);
- }
- }
-
- private void initView() {
- if (adapter == null) {
- adapter = new MyRecyclerAdapter();
- } else {
- adapter.notifyDataSetChanged();
- }
- adapter.initData(false);
- adapter.appendData(modelList);
- recyclerView.setAdapter(adapter);
- recyclerView.addOnScrollListener(new OnScrollColorChangeListener());
- }
-
- private class OnScrollColorChangeListener extends RecyclerView.OnScrollListener {
-
- private boolean isTrans = true;
- private int y = 0;
-
- @Override
- public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
- if (anchorHeight != 0) {
- y += dy;
- boolean needTrans = y <= anchorHeight;
- if (needTrans != isTrans) {
- isTrans = needTrans;
- toolBarBackgroundController.setTransparent(needTrans);
- } else {
- if (y / anchorHeight < 1) {
- layoutToolBarBackground.setBackgroundColor(getResources().getColor(R.color.base));
- layoutToolBarBackground.getBackground().setAlpha((int) ((float) y / anchorHeight * 255));
- }
- }
- }
- }
- }
-
- private class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
- private final int TYPE_HEADER = 0x1000;
- private final int TYPE_NORMAL = 0x2000;
- private final int TYPE_FOOTER = 0x3000;
- private final int TYPE_EMPTY = 0x4000;
- private final int TYPE_THEME = 0x5000;
- private ArrayList<MyItemInfo> itemInfos;
- private boolean needFooter = false;
- private boolean hasFooter = false;
-
- public class MyItemInfo {
- int type;
- Model model;
-
- public MyItemInfo(int type, Model model) {
- this.type = type;
- this.model = model;
- }
- }
-
- public MyRecyclerAdapter() {
- itemInfos = new ArrayList<>();
- }
-
- public void initData(boolean needFooter) {
- this.needFooter = needFooter;
- this.hasFooter = false;
- int oldCount = itemInfos.size();
- itemInfos.clear();
- this.notifyItemRangeRemoved(0, oldCount);
- itemInfos.add(new MyItemInfo(TYPE_HEADER, null));
- //itemInfos.add(new MyItemInfo(TYPE_FOOTER, null));
- //this.notifyItemRangeInserted(0, 2);
- }
-
- public void appendData(ArrayList<Model> models) {
- int oldCount = itemInfos.size();
- if (hasFooter) {
- itemInfos.remove(oldCount - 1);
- this.notifyItemRemoved(oldCount - 1);
- oldCount--;
- }
- int size = models.size();
- for (int i = 0; i < size; i++) {
- itemInfos.add(new MyItemInfo(TYPE_NORMAL, models.get(i)));
- }
-
- this.notifyItemRangeInserted(oldCount + 1, size);
- if (needFooter) {
- itemInfos.add(new MyItemInfo(TYPE_FOOTER, null));
- this.notifyItemInserted(itemInfos.size() - 1);
- hasFooter = true;
- }
- }
-
- public void removeFooter() {
- int oldCount = itemInfos.size();
- itemInfos.remove(oldCount - 1);
- notifyItemRemoved(oldCount - 1);
- }
-
- public void appendEmptyView() {
- int oldCount = itemInfos.size();
- if (hasFooter) {
- itemInfos.remove(oldCount - 1);
- this.notifyItemRemoved(oldCount - 1);
- oldCount--;
- }
- itemInfos.add(new MyItemInfo(TYPE_EMPTY, null));
- notifyItemRangeInserted(oldCount, 1);
- }
-
- @Override
- public int getItemViewType(int position) {
- return itemInfos.get(position).type;
- }
-
- @Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- LayoutInflater inflater = LayoutInflater.from(parent.getContext());
- View view = null;
- switch (viewType) {
- case TYPE_HEADER:
- view = inflater.inflate(R.layout.layout_main_recycler_head, parent, false);
- return new MyHeaderItemHolder(view, MainActivity.this);
- case TYPE_NORMAL:
- view = inflater.inflate(R.layout.layout_list_item, parent, false);
- return new NormalViewHolder(view);
- case TYPE_EMPTY:
- return null;
- case TYPE_FOOTER:
- return null;
- default:
- return null;
- }
- }
-
- @Override
- public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
- switch (viewHolder.getItemViewType()) {
- case TYPE_NORMAL:
- NormalViewHolder normalViewHolder = (NormalViewHolder) viewHolder;
- normalViewHolder.setContent(itemInfos.get(i).model, i);
- break;
- case TYPE_HEADER:
- MyHeaderItemHolder headerViewHolder = (MyHeaderItemHolder) viewHolder;
- headerViewHolder.setContent();
- break;
- case TYPE_FOOTER:
- case TYPE_EMPTY:
- break;
- default:
- break;
- }
- }
-
- @Override
- public int getItemCount() {
- return itemInfos.size();
- }
-
- private class EmptyItemHolder extends RecyclerView.ViewHolder {
- public EmptyItemHolder(View itemView) {
- super(itemView);
- }
- }
-
- private class MyHeaderItemHolder extends RecyclerView.ViewHolder {
- private Context context;
- private ImageView imageView;
-
- public MyHeaderItemHolder(View itemView, Context context) {
- super(itemView);
- this.context = context;
- imageView = (ImageView) itemView.findViewById(R.id.img_main_recycler_head_banner);
- imageView.post(new Runnable() {
- @Override
- public void run() {
- anchorHeight = imageView.getMeasuredHeight() - layoutToolBarBackground.getMeasuredHeight();
- }
- });
- }
-
- //填充头部内容
- public void setContent() {
-
- }
- }
-
- private class NormalViewHolder extends RecyclerView.ViewHolder {
- private Model model;
- private TextView nameView;
- private TextView descView;
-
- public NormalViewHolder(View itemView) {
- super(itemView);
- nameView = (TextView) itemView.findViewById(R.id.text_list_item_name);
- descView = (TextView) itemView.findViewById(R.id.text_list_item_desc);
- itemView.setOnClickListener(new OnItemClickListener());
- }
-
- public void setContent(Model model, int index) {
- this.model = model;
- nameView.setText(model.getName());
- descView.setText(model.getDesc());
- itemIndex = index;
-
- }
-
- private class OnItemClickListener implements View.OnClickListener {
- @Override
- public void onClick(View v) {
-
- }
- }
- }
-
- private class FooterViewHolder extends RecyclerView.ViewHolder {
-
- public FooterViewHolder(View itemView) {
- super(itemView);
- }
- }
- }
-
- }
ok,到这里demo就搞定了!当然如果你的标题栏上的文字太长的话,你也可以自己给textView加上跑马灯效果,很简单,不知道的人可以自行去谷歌百度,记得给textView加上焦点就可以了。
项目地址:点击打开链接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。