自定义组合控件——简单实现自定义toolbar

来源:互联网 发布:网站统计分析系统源码 编辑:程序博客网 时间:2024/05/19 21:40

自定义组合控件——简单实现自定义toolbar

首先,要写一个toolbar,十分简单,在xml文件定义几个控件组合在一起,用include就能简单复用,但是今天这里来讲下自定义组合控件,目的很明显,就是降低布局文件和activity的耦合。

话不多说,直接帖代码:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MyToolBar">        <attr name="titlename"  format="string"/>        <attr name="titlesize" format="dimension"/>        <attr name="titlecolor" format="color"/>        <attr name="leftbg" format="reference"/>        <attr name="righttext" format="string"/>        <attr name="rightsize" format="dimension"/>        <attr name="rightcolor" format="color"/>    </declare-styleable></resources>

这里我在values文件夹下新建一个叫做attrs的xml文件 <declare-styleable\>标签告诉系统这是我们自己定义的属性, <attr\> 标签是我们定义属性的名字,format属性 定义值的类型

package com.customtoolbar;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.RelativeLayout;import android.widget.TextView;/** * Created by z on 2017/6/20. */public class Toolbar extends RelativeLayout{    //标题栏所包含的三个控件  private   Button leftbutton ;   private TextView title,righttext;    //标题中心文字的属性    private String titlename;    private float titlesize;    private int titlecolor;    //左边按钮的属性    private Drawable leftbg;    //右边文字的属性    private String rightname;    private float rightsize;    private int rightcolor;   private LayoutParams leftParams;    private LayoutParams titleParams;    private LayoutParams rightParams;    public Toolbar(Context context, AttributeSet attrs) {        super(context, attrs);        TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.MyToolBar);        //获取xml文件中的属性值        titlename=typedArray.getString(R.styleable.MyToolBar_titlename);        titlesize=typedArray.getDimension(R.styleable.MyToolBar_titlesize,0);        titlecolor=typedArray.getColor(R.styleable.MyToolBar_titlecolor,0);        leftbg=typedArray.getDrawable(R.styleable.MyToolBar_leftbg);        rightname=typedArray.getString(R.styleable.MyToolBar_righttext);        rightsize=typedArray.getDimension(R.styleable.MyToolBar_rightsize,0);        rightcolor=typedArray.getInt(R.styleable.MyToolBar_rightcolor,0);        //回收,避免浪费资源以及未知的缓存错误        typedArray.recycle();        //实例化控件        leftbutton=new Button(context);        title=new TextView(context);        righttext=new TextView(context);        //属性赋给定义的控件        title.setText(titlename);        title.setTextSize(titlesize);        title.setTextColor(titlecolor);        title.setGravity(Gravity.CENTER);        leftbutton.setBackground(leftbg);        righttext.setText(rightname);        righttext.setTextSize(rightsize);        righttext.setTextColor(rightcolor);        setBackgroundColor(Color.parseColor("#63B8FF"));        //定义子控件在父容器中的位置        leftParams=new LayoutParams(100, 100);        leftParams.setMarginStart(20);        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);        leftParams.addRule(RelativeLayout.CENTER_VERTICAL);        addView(leftbutton,leftParams);        titleParams=new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        titleParams.addRule(RelativeLayout.CENTER_IN_PARENT);        addView(title,titleParams);        rightParams=new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        rightParams.setMarginEnd(20);        rightParams.addRule(RelativeLayout.CENTER_VERTICAL);        rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);        addView(righttext,rightParams);//给左边的按钮设置点击事件        leftbutton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //执行回调方法                leftButtonListener.LeftBtnOnclick();            }        });    }    private LeftButtonListener leftButtonListener;    public void setOnToolbarclickListener (LeftButtonListener listener) {        leftButtonListener=listener;    }    public interface LeftButtonListener    {        void LeftBtnOnclick();    }}

这里是自定义的核心代码,用typedarray类存储我们xml文件中定义的属性,然后通过各种get方法,取出你xml文件中定义的值,再将这些属性值附给我们自定义控件的各个子控件。
那么点击事件该怎么处理呢?我们不能在自定义控件中写死他的执行方法,这样十分不合理,这时候我们就想到了接口回调。
定义一个LeftButtonListener,里面有待实现方法LeftBtnOnclick() 在activity中实现这个方法。
当我们点击这个按钮的时候,执行LeftBtnOnclick() ,具体执行代码,自己在activity中定义。

package com.customtoolbar;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    Toolbar myToolbar;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        myToolbar= (Toolbar) findViewById(R.id.mytoolbar);        myToolbar.setOnToolbarclickListener(new Toolbar.LeftButtonListener() {            @Override            public void LeftBtnOnclick() {                Toast.makeText(MainActivity.this,"你点击了左边按钮",Toast.LENGTH_SHORT).show();            }        });    }}
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:custom="http://schemas.android.com/apk/res-auto"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.customtoolbar.MainActivity">    <com.customtoolbar.Toolbar        android:layout_width="match_parent"        android:layout_height="50dp"        android:id="@+id/mytoolbar"        custom:titlename="标题"        custom:titlesize="10sp"        custom:titlecolor="#ffffff"        custom:leftbg="@mipmap/ic_launcher"        custom:righttext="右键"        custom:rightsize="6sp"        custom:rightcolor="#000"        >    </com.customtoolbar.Toolbar></RelativeLayout>

布局文件中给我们之前自定义属性赋值,这里有一点很重要,就是命名空间,例如要使用android:要用到

xmlns:android="http://schemas.android.com/apk/res/android"

同理

xmlns:custom="http://schemas.android.com/apk/res-auto"

我们讲前面的名字改成自定义名字,到时候就用这个名字来调用,后面改成res-auto让他自动搜寻

最后我们来看下演示效果:

这里写图片描述

总结:
这种方法看似会复杂不少,但是其实条理很清晰,并且能有效的降低布局和activity间的耦合,让代码更易维护,谢谢。