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

自定义组合控件——简单实现自定义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间的耦合,让代码更易维护,谢谢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值