您的位置:首页 > 其它

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. 源码

点击,,,,,,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: