Androidで最も簡単なカスタムToolbarの1つ

35732 ワード

作者:Jooyer,時間:2018.09.08
Githubアドレス、ようこそ、fork
一般的なアプリはすべて自分で書いたToolbarを使って、システムの情況を使うのは比較的に少なくて、今回のカスタマイズは実は組み合わせのコントロールで、多くの大物は類似のコントロールがあって、時には完全に自分の需要を満たすとは限らない.
今回のコードは简単で、私は直接ソースコードを贴って、もしまだはっきりしないことがあるならば、伝言あるいはgithubを见ることができます
1つのクラス+2つのXMLファイルだけで、コピーして使用できます.
次に、次のように説明します.
  • CustomToolbar
  • 2 2個のXMLファイル
  • プロパティおよびデフォルト
  • まず、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で方法を定義することができて、コードの中で動的に設定して、これは書いていません.主に怠け者で、みんなは何かを入れなければなりません.
    いいね、コレクション、転送を覚えているのが好きです!