Material Design之toolbar的自定义小封装
2017-03-02 14:45
239 查看
1. 写在前面
最近看了很多toolbar的知识,但是感觉内容都大同小异,比如这个 还有这个 还有这个 而且对于实际项目并没有什么用,所以我自己总结下。先看图,这是大众点评里面的页面其实很多app如果用到toolbar大致可以包含两种,一种是首页的toolbar非常复杂而且巧妙比如前面两张图,还有一种很简单,但是很多页面都用的着比如后面两张图。所以我认为:
1.如果是比较复杂的view,最好自己写个布局,然后添加到toolbar中,再在代码中设置到actionbar中。
2. 如果是用到地方比较多的toolbar布局,希望封装下,用的时候在xml布局中直接控制或者在java代码中代码控制,并且支持点击事件。
我下面的代码做的就是这两件事,先看下效果图。
2. 代码
a. 先看第一种情况吧,用起来比较简单,难的是将自己想要的复杂布局做出来,因为我这里只是举例子,所以布局比较简单。因为我们是用toolbar代替了actionbar,所以theme那里需要一个不带actionbar的主题
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
因为我们需要将自己的布局添加到toolbar中,先看第一个页面xml图
这里面有几个需要注意的,
contentInsetStart
这个属性,因为我们添加一个布局到xml,如果不设置这个属性,当然也可以在代码中和theme中设置,如果不设置,里面的布局在toolbar中总会隔左边一段距离。如图
当我设置后,就会这样,所以这个属性很好理解见图
还有个需要注意的是,我这里需要使用include,这个无所谓,用不用,我这里只是试一试里面用include可不可以,因为我的项目中并没有用toolbar,感觉也方便不了多少,用include也可以实现自己想要的。include包含的布局代码如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@color/colorAccent" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:src="@mipmap/back" android:layout_marginLeft="10dp" android:layout_centerVertical="true" android:layout_width="30dp" android:layout_height="30dp" /> <TextView android:text="英雄连们" android:layout_centerInParent="true" android:textSize="18sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:src="@mipmap/setting" android:layout_marginRight="10dp" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_width="30dp" android:layout_height="30dp" /> </RelativeLayout>
最后一个点需要注意的是这个高度height,因为我这里设置的是用actionbar自带的android高度,
android:layout_height="?attr/actionBarSize"
这个如果需要修改,直接去styles下面修改成自己想要的就是了,
<item name="android:actionBarSize">自己填</item>
然后去activity中拿到toolbar,设置下就可以了,
Toolbar toolbar = (Toolbar) this.findViewById(R.id.toolbar); setSupportActionBar(toolbar);
b. 现在就来看第二种情况,进行一个小小的封装,每个页面用时就是一个自定义的toolbar。
<guozhaohui.com.customtoolbar.MyToolBar android:id="@+id/my_toolbar" app:iconRight="@mipmap/back" app:iconLeft="@mipmap/setting" app:textCen="地对地导弹" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"> </guozhaohui.com.customtoolbar.MyToolBar>
里面的三个app属性都是自定义的。前面这自定义步骤直接上代码了,自attrs中定义属性,继承toolbar,修改三个构造函数。
<declare-styleable name="MyToolBar"> <attr name="iconLeft" format="reference" /> <attr name="textCen" format="string" /> <attr name="iconRight" format="reference" /> </declare-styleable>
public MyToolBar(Context context) { this(context,null); } public MyToolBar(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public MyToolBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
假设这个简单模式的toolbar布局和刚才这个布局是一样的,因为确实差不多是这样的,所以我直接复制了一份include里面的布局,然后在MyToolbar代码中对他们初始化
private void initView() { if(view==null){ layoutInflater = LayoutInflater.from(getContext()); view = layoutInflater.inflate(R.layout.item_toolbar, null); iv_toolbar_left = (ImageView) view.findViewById(R.id.iv_toolbar_left); tv_toolbar_cen = (TextView) view.findViewById(R.id.tv_toolbar_cen); iv_toolbar_right = (ImageView) view.findViewById(R.id.iv_toolbar_right); LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER_HORIZONTAL); addView(view,lp); } }
在然后通过TintTypedArray的对象对这三个自定义属性设置,
final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs, R.styleable.MyToolBar, defStyleAttr, 0);
比如设置左边的icon
//设置左边icon,其实toolbar有navigation这个属性可以用,但是为了更灵活,我们写自己的,可以随便调整 Drawable leftIcon = a.getDrawable(R.styleable.MyToolBar_iconLeft); if(leftIcon!=null){ // iv_toolbar_left.setBackground(leftIcon); iv_toolbar_left.setImageDrawable(leftIcon); }
同理右边的icon也是一样的代码
//同样,设置右边的icon Drawable rightIcon = a.getDrawable(R.styleable.MyToolBar_iconRight); if(rightIcon!=null){ iv_toolbar_right.setImageDrawable(rightIcon); }
设置中间文字
//设置文字 CharSequence cenText = a.getText(R.styleable.MyToolBar_textCen); if(!TextUtils.isEmpty(cenText)){ tv_toolbar_cen.setText(cenText); }
差不多完成了,在任何一个布局中想用的话直接用就可以了,刚才上面代码已经贴出来了,但是为了灵活一些。
在java代码中也能控制图标和文字,
/** * 使可以在java代码中动态修改图标 * @param iconRes */ public void changeLeftIcon(int iconRes){ if(iv_toolbar_left!=null){ iv_toolbar_left.setImageDrawable(getResources().getDrawable(iconRes)); } }
在activity中使用也比较简单,拿到myToolbar实例调用方法即可
myToolBar.changeLeftIcon(R.mipmap.back); myToolBar.changeRightIcon(R.mipmap.setting);
/** * java 代码中支持toolbar中间的text的修改 * @param text */ public void setCenterText(String text){ if(tv_toolbar_cen!=null){ if(!TextUtils.isEmpty(text)){ tv_toolbar_cen.setText(text); } } }
java代码中
myToolBar.setCenterText("德玛西亚");
/** * 为图标设置点击事件 * @param listener */ public void setLeftIconListener(View.OnClickListener listener){ if(iv_toolbar_left!=null){ iv_toolbar_left.setOnClickListener(listener); } }
java代码中,也是调用方法
//点击事件 myToolBar.setLeftIconListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(CustomActivity.this,"我是点击事件",Toast.LENGTH_SHORT).show(); } });
到这里应该差不多了,在项目中应该可以可以使用。
3. 源码
点击,,,,,,相关文章推荐
- 自定义ToolBar与ToolBar的封装,使ToolBar的Title居中
- Material Design之自定义Material主题及Toolbar
- 自定义被封装的工作流控件方法
- UI基础_自定义等高Cell_xib封装_版本_有GIF_源代码
- 使用Xib封装一个自定义View
- [Java]自定义Jar库,Http简单的Get和Post请求封装
- jsf自定义toolbar组件
- easyUI Dialog自定义Toolbar和button
- Material Design学习之Toolbar的使用(1)
- cocos2dx 自定义按钮封装(支持CCMenu批量管理),很久以前的代码
- baseactivity实现封装toolbar
- 创建Material Design风格的Android应用--使用自定义动画
- js利用闭包封装自定义模块的几种方法
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
- iOS 自定义键盘ToolBar(与键盘的弹出、收起保持一致)
- Toolbar的使用和自定义
- 封装PHP mail函数发送HTML邮件并使用中文发件人且自定义发件人邮箱地址
- 自定义组件之【柱状图】详解 已封装成View
- 百度编辑器Ueeditor编辑器自定义toolbar
- Android ToolBar 的容易封装