Android 最简单的自定义Toolbar之一

作者: Jooyer, 时间: 2018.09.08

Github地址,欢迎点赞,fork

一般APP 都使用自己写的 Toolbar , 使用系统情况比较少,本次自定义其实是组合控件而已,虽然有很多大佬有类似控件,有些时候不一定完全满足自己的需要.

本次代码简单,我就直接贴源码,如果还有不清楚的,可以留言或者看github

只需要一个类 + 两个 XML 文件即可,即拷即用

接下来我们依次讲解:

  1. CustomToolbar
  2. 两个 XML 文件
  3. 属性及默认值

首先,看看 CustomToolbar

package cn.molue.jooyer.toolbar

import android.content.Context
import android.support.v4.content.ContextCompat
import android.text.TextUtils
import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView

/**
 * Desc: 自定义 Toolbar ,格式如下:
 *
 * Author: Jooyer
 * Date: 2018-08-08
 * Time: 17:13
 */
class CustomToolbar(context: Context, attr: AttributeSet, defStyleAttr: Int)
    : RelativeLayout(context, attr, defStyleAttr) {

    /**
     * 最左侧图标,默认显示
     */
    private lateinit var iv_left_icon_menu: ImageView
    /**
     * 最左侧文本
     */
    private lateinit var tv_left_name_menu: TextView
    /**
     * 中间文本
     */
    private lateinit var tv_center_title_menu: TextView
    /**
     * 最右侧文本
     */
    private lateinit var tv_right_name_menu: TextView
    /**
     * 最右侧图标,默认显示
     */
    private lateinit var iv_right_icon_menu: ImageView

    /**
     * 底部分割线
     */
    private lateinit var view_bottom_divider_menu: View


    constructor(context: Context, attr: AttributeSet) : this(context, attr, 0)

    init {
        initView()
        parseAttrs(context, attr)
    }

    private fun initView() {
        val parent = LayoutInflater.from(context).inflate(R.layout.toolbar_custom, this,true)
        iv_left_icon_menu = parent.findViewById(R.id.iv_left_icon_menu)
        tv_left_name_menu = parent.findViewById(R.id.tv_left_name_menu)
        tv_center_title_menu = parent.findViewById(R.id.tv_center_title_menu)
        tv_right_name_menu = parent.findViewById(R.id.tv_right_name_menu)
        iv_right_icon_menu = parent.findViewById(R.id.iv_right_icon_menu)
        view_bottom_divider_menu = parent.findViewById(R.id.view_bottom_divider_menu)

    }

    private fun parseAttrs(context: Context, attr: AttributeSet) {
        val arr = context.obtainStyledAttributes(attr, R.styleable.CustomToolbar)
        val leftImageVisible = arr.getBoolean(R.styleable.CustomToolbar_ct_left_image_visible, true)
        val leftImageDrawable = arr.getDrawable(R.styleable.CustomToolbar_ct_left_image_drawable)
        val leftImageWidth = arr.getDimension(R.styleable.CustomToolbar_ct_left_image_width, dp2px(20F)).toInt()
        val leftImageHeight = arr.getDimension(R.styleable.CustomToolbar_ct_left_image_height, dp2px(20F)).toInt()
        val leftImagePadding = arr.getDimension(R.styleable.CustomToolbar_ct_left_image_padding, dp2px(3F)).toInt()
        val leftImageLeftMargin = arr.getDimension(R.styleable.CustomToolbar_ct_left_image_left_margin, dp2px(0F)).toInt()

        val leftTextVisible = arr.getBoolean(R.styleable.CustomToolbar_ct_left_text_visible, false)
        val leftTextInfo = arr.getText(R.styleable.CustomToolbar_ct_left_text_info)
        val leftTextSize = arr.getInteger(R.styleable.CustomToolbar_ct_left_text_size, 15).toFloat()
        val leftTextLeftMargin = arr.getDimension(R.styleable.CustomToolbar_ct_left_text_left_margin, dp2px(20F)).toInt()
        val leftTextColor = arr.getColor(R.styleable.CustomToolbar_ct_left_text_color,
                ContextCompat.getColor(context, R.color.color_111111))

        val centerTextInfo = arr.getText(R.styleable.CustomToolbar_ct_center_text_info)
        val centerTextSize = arr.getInteger(R.styleable.CustomToolbar_ct_center_text_size, 15).toFloat()
        val centerTextColor = arr.getColor(R.styleable.CustomToolbar_ct_center_text_color,
                ContextCompat.getColor(context, R.color.color_111111))

        val rightImageVisible = arr.getBoolean(R.styleable.CustomToolbar_ct_right_image_visible, true)
        val rightImageDrawable = arr.getDrawable(R.styleable.CustomToolbar_ct_right_image_drawable)
        val rightImageWidth = arr.getDimension(R.styleable.CustomToolbar_ct_right_image_width, dp2px(20F)).toInt()
        val rightImageHeight = arr.getDimension(R.styleable.CustomToolbar_ct_right_image_height, dp2px(20F)).toInt()
        val rightImagePadding = arr.getDimension(R.styleable.CustomToolbar_ct_right_image_padding, dp2px(5F)).toInt()
        val rightImageRightMargin = arr.getDimension(R.styleable.CustomToolbar_ct_right_image_right_margin, dp2px(20F)).toInt()

        val rightTextVisible = arr.getBoolean(R.styleable.CustomToolbar_ct_right_text_visible, false)
        val rightTextInfo = arr.getText(R.styleable.CustomToolbar_ct_right_text_info)
        val rightTextSize = arr.getInteger(R.styleable.CustomToolbar_ct_right_text_size, 15).toFloat()
        val rightTextRightMargin = arr.getDimension(R.styleable.CustomToolbar_ct_right_text_right_margin, dp2px(20F)).toInt()
        val rightTextColor = arr.getColor(R.styleable.CustomToolbar_ct_right_text_color,
                ContextCompat.getColor(context, R.color.color_111111))

        val bottomDividerVisible = arr.getBoolean(R.styleable.CustomToolbar_ct_bottom_divider_visible, false)
        val bottomDividerColor = arr.getColor(R.styleable.CustomToolbar_ct_bottom_divider_color,
                ContextCompat.getColor(context, R.color.color_EEEEEE))
        val backgroundColor = arr.getColor(R.styleable.CustomToolbar_ct_background_color,
                ContextCompat.getColor(context, R.color.color_FE632E))

        iv_left_icon_menu.visibility = if (leftImageVisible) View.VISIBLE else View.GONE
        if (null != leftImageDrawable) {
            iv_left_icon_menu.setImageDrawable(leftImageDrawable)
        }
        val leftImageLp: RelativeLayout.LayoutParams = iv_left_icon_menu.layoutParams as LayoutParams
        leftImageLp.width = leftImageWidth
        leftImageLp.height = leftImageHeight
        leftImageLp.leftMargin = leftImageLeftMargin
        iv_left_icon_menu.setPadding(leftImagePadding, leftImagePadding, leftImagePadding, leftImagePadding)
        iv_left_icon_menu.layoutParams = leftImageLp

        tv_left_name_menu.visibility = if (leftTextVisible) View.VISIBLE else View.GONE
        if (!TextUtils.isEmpty(leftTextInfo)) {
            tv_left_name_menu.text = leftTextInfo
            tv_left_name_menu.setTextSize(TypedValue.COMPLEX_UNIT_DIP, leftTextSize)
            tv_left_name_menu.setTextColor(leftTextColor)
        }

        val leftTextLp: RelativeLayout.LayoutParams = tv_left_name_menu.layoutParams as LayoutParams
        leftTextLp.leftMargin = leftTextLeftMargin
        tv_left_name_menu.layoutParams = leftTextLp

        if (!TextUtils.isEmpty(centerTextInfo)) {
            tv_center_title_menu.text = centerTextInfo
            tv_center_title_menu.setTextSize(TypedValue.COMPLEX_UNIT_DIP, centerTextSize)
            tv_center_title_menu.setTextColor(centerTextColor)
        }

        iv_right_icon_menu.visibility = if (rightImageVisible) View.VISIBLE else View.GONE
        if (null != rightImageDrawable) {
            iv_right_icon_menu.setImageDrawable(rightImageDrawable)
        }
        val rightImageLp: RelativeLayout.LayoutParams = iv_right_icon_menu.layoutParams as LayoutParams
        rightImageLp.width = rightImageWidth
        rightImageLp.height = rightImageHeight
        rightImageLp.rightMargin = rightImageRightMargin
        iv_right_icon_menu.setPadding(rightImagePadding, rightImagePadding, rightImagePadding, rightImagePadding)
        iv_right_icon_menu.layoutParams = rightImageLp


        tv_right_name_menu.visibility = if (rightTextVisible) View.VISIBLE else View.GONE
        if (!TextUtils.isEmpty(rightTextInfo)) {
            tv_right_name_menu.text = rightTextInfo
            tv_right_name_menu.setTextSize(TypedValue.COMPLEX_UNIT_DIP, rightTextSize)
            tv_right_name_menu.setTextColor(rightTextColor)
        }
        val rightTextLp: RelativeLayout.LayoutParams = tv_right_name_menu.layoutParams as LayoutParams
        rightTextLp.rightMargin = rightTextRightMargin
        tv_right_name_menu.layoutParams = rightTextLp

        view_bottom_divider_menu.visibility = if (bottomDividerVisible) View.VISIBLE else View.GONE
        view_bottom_divider_menu.setBackgroundColor(bottomDividerColor)

        setBackgroundColor(backgroundColor)
        arr.recycle()
    }

    public fun setLeftImageListener(listener: View.OnClickListener) {
        iv_left_icon_menu.setOnClickListener(listener)
    }

    public fun setRightImageListener(listener: View.OnClickListener) {
        iv_right_icon_menu.setOnClickListener(listener)
    }

    public fun setRightTextListener(listener: View.OnClickListener) {
        tv_right_name_menu.setOnClickListener(listener)
    }


    public fun setCenterText(text: String) {
        tv_center_title_menu.text = text
    }

    private fun dp2px(def: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, def, context.resources.displayMetrics)
    }
}
复制代码

来看看自定义的属性(xml文件)

里面就是一大堆自定义的属性,具体含义往下看

    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    
复制代码

属性虽然有些多,但是大都都见名知意. 这里还是要看下其布局文件,虽然 so easy

再来看看其布局(xml文件)

xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="@dimen/height_50"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/iv_left_icon_menu"
        android:layout_width="@dimen/width_45"
        android:layout_height="match_parent"
        android:layout_centerVertical="true"
        android:src="@mipmap/icon_black_back" />

    <TextView
        android:id="@+id/tv_left_name_menu"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_centerVertical="true"
        android:gravity="center_vertical"
        android:textColor="@color/color_111111"
        android:textSize="@dimen/text_size_15"
        tools:text="宝贝头像" />


    <TextView
        android:id="@+id/tv_center_title_menu"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:layout_marginEnd="@dimen/padding_20"
        android:gravity="center_vertical"
        android:textColor="@color/color_111111"
        android:textSize="@dimen/text_size_18"
        android:textStyle="bold"
        tools:text="请填写" />


    <TextView
        android:id="@+id/tv_right_name_menu"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="@dimen/padding_20"
        android:gravity="center_vertical"
        android:textColor="@color/color_111111"
        android:textSize="@dimen/text_size_15"
        tools:text="请填写" />


    <ImageView
        android:id="@+id/iv_right_icon_menu"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_alignParentEnd="true"
        android:layout_centerVertical="true"
        android:layout_marginEnd="@dimen/padding_20" />


    <View
        android:id="@+id/view_bottom_divider_menu"
        android:layout_width="match_parent"
        android:layout_height="@dimen/divider_2"
        android:layout_alignParentBottom="true"
        android:background="@color/color_EEEEEE" />
RelativeLayout>
复制代码

最后来看看在 Activity 布局中的用法

xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="cn.molue.jooyer.toolbar.MainActivity"
    >

    <cn.molue.jooyer.toolbar.CustomToolbar
        android:id="@+id/ct_tool_bar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding_6"
        android:layout_marginBottom="@dimen/padding_6"
        app:ct_center_text_info="左边图片,右边文本"
        app:ct_right_text_info="清空"
        app:ct_right_text_right_margin="@dimen/padding_5"
        app:ct_right_text_visible="true"
        />


    <cn.molue.jooyer.toolbar.CustomToolbar
        android:id="@+id/ct_tool_bar2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding_6"
        android:layout_marginBottom="@dimen/padding_6"
        app:ct_center_text_info="左边图片,右边图片"
        app:ct_right_image_drawable="@mipmap/icon_black_back"
        app:ct_right_image_right_margin="@dimen/padding_5"
        />

    <cn.molue.jooyer.toolbar.CustomToolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding_6"
        android:layout_marginBottom="@dimen/padding_6"
        app:ct_center_text_info="左边文本,右边文本"
        app:ct_left_image_visible="false"
        app:ct_left_text_info="返回"
        app:ct_left_text_left_margin="@dimen/padding_5"
        app:ct_left_text_visible="true"
        app:ct_right_image_right_margin="@dimen/padding_5"
        app:ct_right_text_info="清空"
        app:ct_right_text_right_margin="@dimen/padding_5"
        app:ct_right_text_visible="true"
        />

    <cn.molue.jooyer.toolbar.CustomToolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding_6"
        android:layout_marginBottom="@dimen/padding_6"
        app:ct_center_text_info="左边文本,右边图片"
        app:ct_left_image_visible="false"
        app:ct_left_text_info="返回"
        app:ct_left_text_left_margin="@dimen/padding_5"
        app:ct_left_text_visible="true"
        app:ct_right_image_drawable="@mipmap/icon_black_back"
        app:ct_right_image_right_margin="@dimen/padding_5"

        />

    <cn.molue.jooyer.toolbar.CustomToolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/padding_6"
        android:layout_marginBottom="@dimen/padding_6"
        app:ct_background_color="@color/colorAccent"
        app:ct_center_text_info="改变背景色"
        app:ct_left_image_visible="false"
        app:ct_left_text_info="返回"
        app:ct_left_text_left_margin="@dimen/padding_5"
        app:ct_left_text_visible="true"
        app:ct_right_image_drawable="@mipmap/icon_black_back"
        app:ct_right_image_right_margin="@dimen/padding_5"
        />


LinearLayout>

复制代码

这个就不解释了,最后看看 Activity中的操作

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ct_tool_bar1.setLeftImageListener(View.OnClickListener {
            Toast.makeText(this@MainActivity,"点击了左侧图片",Toast.LENGTH_SHORT).show()
        })

        ct_tool_bar1.setRightTextListener(View.OnClickListener {
            Toast.makeText(this@MainActivity,"点击了右侧文字",Toast.LENGTH_SHORT).show()
        })

        ct_tool_bar2.setRightImageListener(View.OnClickListener {
            Toast.makeText(this@MainActivity,"点击了右侧图片",Toast.LENGTH_SHORT).show()
        })
    }
}
复制代码

最后讲解下属性和默认值

 		
        "ct_left_text_visible" format="boolean"/>  // 默认是false
        
        "ct_left_text_info" format="reference|string"/>
        
        "ct_left_text_size" format="dimension|integer"/> // 默认是15dp
        
        "ct_left_text_color" format="color|reference"/> // 默认颜色是 #111111
        
        "ct_left_text_left_margin" format="dimension|integer"/> // 默认是20dp
        
        "ct_left_image_visible" format="boolean"/> // 默认是 true
        
        "ct_left_image_drawable" format="reference"/> // 给了个黑色箭头
        
        "ct_left_image_width" format="dimension|integer"/> // 默认20dp
        
        "ct_left_image_height" format="dimension|integer"/> // 默认20dp
        
        "ct_left_image_padding" format="dimension|integer"/> // 默认3dp
        
        "ct_left_image_left_margin" format="dimension|integer"/> // 默认为 0 
        
        "ct_center_text_info" format="reference|string"/>
        
        "ct_center_text_size" format="dimension|integer"/> // 默认15dp
        
        "ct_center_text_color" format="color|reference"/> // 默认#111111
        
        "ct_right_text_visible" format="boolean"/> // 默认false
        
        "ct_right_text_info" format="reference|string"/>
        
        "ct_right_text_size" format="dimension|integer"/> // 默认15dp
        
        "ct_right_text_color" format="color|reference"/> // 默认#111111
        
        "ct_right_text_right_margin" format="dimension|integer"/>  // 默认20dp
        
        "ct_right_image_visible" format="boolean"/> // 默认是true 
        
        "ct_right_image_drawable" format="reference"/>
        
        "ct_right_image_width" format="dimension|integer"/> // 默认20dp
        
        "ct_right_image_height" format="dimension|integer"/> // 默认20dp
        
        "ct_right_image_padding" format="dimension|integer"/> // 默认5dp
        
        "ct_right_image_right_margin" format="dimension|integer"/> // 默认20dp
        
        "ct_bottom_divider_visible" format="boolean"/> // 默认false
        
        "ct_bottom_divider_color" format="color|reference"/> // 默认#EEEEEE
        
        "ct_background_color" format="color|reference"/> // 默认#FE632E
复制代码

注意,如果不是使用默认属性,比如左侧不是图片,而是文字,记得隐藏图片,同时显示文字

当然,这些属性也可以在 CustomToolbar 中定义方法,在代码里动态设置,这个就没有写,主要是懒,大家需要什么加入什么就好了!

喜欢记得点赞,收藏,转发哈!

你可能感兴趣的:(Android 最简单的自定义Toolbar之一)