Android渐变标题栏的实现

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加上焦点就可以了。

项目地址:点击打开链接

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值