Android笔记--自定义View之组合控件

Android-自定义View

分享是最好的记忆--
如需转发请注明出处

[强调]:共同学习 共同进步 不喜勿喷

内容简介


  1. 前言
  2. 实现
  3. 总结

1. 前言


这次更新有2个目的
1. 复用控件,而不是每次都写冗余代码
2. 好久没有更新了(๑• . •๑)

在Android开发当中自定义View是一项不可或缺的技能,也是我们大部分小白以及小小白的软肋。
  自定义View其实也不是很难,因为我们不需要攻克什么技术难关,只需要坐在巨人的肩膀上,抱紧巨人的脑袋就行(ฅ>ω<*ฅ)
  自定义View分两大类:
一 : 组合 : 也就是在现有的控件基础上通过组合各种不同功能的控件来组合出功能更强大全民的新控件。
二 : 完全自定义:通过继承View或者ViewGroup来自定义全新的View。  今天讨论的自定义View是第一种方式,即组合方式。如果想了解完全自定义或者更多自定义方面的知识,推荐看扔物线大神以及张鸿翔大神的文章。

2. 实现


1. 确定需求

  功能列表中的Item是我们经常用到的控件之一。它也许是这样的:
item1.png

或者是这样的:
item2.png

再或者是这样的:
item3.png

  为了满足这些情况,我们抽象出功能最丰富的Item;确定了需求之后开始编码。

2. 编码

1. 自定义属性
  首先确定我们需要动态设置的属性;包括 :1-左边图片2-3-左边图片的宽高4-大标题5-大标题文字大小6-大标题文字颜色7-副标题8-副标题文字大小9-副标题文字颜色10-右边图片11-12-右边图片宽高等12个属性,当然不止这些,这个可以根据自己的需求丰富,比如 Item 下面是否显示阴影线条,右边图片是否显示等;
  那么在../res/attrs.xml中定义自定义属性;

<declare-styleable name="UILibraryListItem">
        <attr name="leftImg" format="reference"/>
        <attr name="leftImg_width" format="dimension"/>
        <attr name="leftImg_height" format="dimension"/>
        <attr name="rightImg" format="reference"/>
        <attr name="rightImg_width" format="dimension"/>
        <attr name="rightImg_height" format="dimension"/>
        <attr name="title" format="string"/>
        <attr name="title_color" format="color"/>
        <attr name="title_size" format="dimension"/>
        <attr name="subTitle" format="string"/>
        <attr name="subTitle_color" format="color"/>
        <attr name="subTitle_size" format="dimension"/>
</declare-styleable>

这里有必要解释一下属性定义中的format

name format 描述
资源 reference 通过id来指定资源
颜色 color 设置颜色
尺寸 dimension 长宽,字体大小等尺寸
字符串 String 设置文本
布尔值 boolean 通过布尔值设置
浮点值 float 设置浮点值
百分数 fraction 设置百分数值
枚举值 enum 设置枚举值
位或运算 flag 位或运算
整型值 integer 设置整型

属性定义时可以指定多种类型值

2.抽象组建
  这里说的抽象组建是把该Item可能有的所有功能都写出来;
../res/layout/item.xml中写出包含组建所有功能的样式;

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        style="@style/UILibraryListItemBase"
        android:id="@+id/leftImg"
        android:layout_alignParentLeft="true"
        android:padding="8dp"
        />
    <TextView
        style="@style/UILibraryListItemBase"
        android:id="@+id/title"
        android:layout_toRightOf="@+id/leftImg"
        />
    <TextView
        style="@style/UILibraryListItemBase"
        android:id="@+id/subTitle"
        android:layout_toLeftOf="@+id/rightImg"
        android:layout_toRightOf="@+id/title"
        android:gravity="right"
        />
    <ImageView
        style="@style/UILibraryListItemBase"
        android:id="@+id/rightImg"
        android:layout_alignParentRight="true"
        android:padding="8dp"
        />
    <View
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_alignBottom="@+id/leftImg"
        />
</RelativeLayout>

3.实现功能
选择一个适当的ViewGroup来继承,实现Item;
我的样式中rootView是个RelativeLayout,因此我继承了RelativeLayout。具体实现如下:

package com.uilib.ui.listitem;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.example.uilibrary.R;
import com.uilib.ui.util.FindView;

/**
 * Created by Elyar.Anwar on 2017/8/10.
 */

public class UILibraryListItem extends RelativeLayout {

    /**
     * 选项控件的左边图片
     */
    private ImageView leftImageView;

    /**
     * 选项控件的右边图片
     */
    private ImageView rightImageView;

    /**
     * 选项控件的标题
     */
    private TextView titleView;

    /**
     * 选项控件的副标题
     */
    private TextView subTitleView;

    /**
     * 左边图片资源
     */
    private Drawable leftImage;

    /**
     * 左边图片资源宽度
     */
    private int leftImageWidth;

    /**
     * 左边图片资源高度
     */
    private int leftImageHeight;

    /**
     * 右边图片资源
     */
    private Drawable rightImage;

    /**
     * 右边图片资源宽度
     */
    private int rightImageWidth;

    /**
     * 右边图片资源高度
     */
    private int rightImageHeight;

    /**
     * 标题文本
     */
    private String title;

    /**
     * 标题文本颜色
     */
    private int titleTextColor;

    /**
     *标题文本字体大小
     */
    private float titleTextSize;

    /**
     *副标题文本
     */
    private String subTitle;

    /**
     *副标题文本颜色
     */
    private int subTitleTextColor;

    /**
     *副标题文本字体大小
     */
    private float subTitleTextSize;

    /**
     *上下文
     */
    private Context mContext;

    /**
     * 属性结合
     */
    private AttributeSet attrs;

    public UILibraryListItem(Context context) {
        this(context,null);
    }

    public UILibraryListItem(Context context, AttributeSet attrs) {
        this(context, attrs,0);
        this.mContext = context;
        this.attrs = attrs;
        init();
    }

    public UILibraryListItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        this.attrs = attrs;
        init();
    }

    /**
     * 初始化视图
     */
    private void init() {
        View.inflate(mContext, R.layout.listitem, this);
        findView();//绑定视图
        loadParams();//加载属性值
        initView();//为视图赋值
    }

    /**
     *  为控件赋值
     */
    private void initView() {
        if(leftImage!=null){
            leftImageView.setImageDrawable(leftImage);
        }
        leftImageView.getLayoutParams().width = leftImageWidth;
        leftImageView.getLayoutParams().height = leftImageHeight;

        if(rightImage!=null){
            rightImageView.setImageDrawable(rightImage);
        }
        rightImageView.getLayoutParams().width = rightImageWidth;
        rightImageView.getLayoutParams().height = rightImageHeight;

        if (!TextUtils.isEmpty(title)){
            titleView.setText(title);
            titleView.setTextColor(titleTextColor);
            titleView.setTextSize(titleTextSize);
        }
        if (!TextUtils.isEmpty(subTitle)){
            subTitleView.setText(subTitle);
            subTitleView.setTextColor(subTitleTextColor);
            subTitleView.setTextSize(subTitleTextSize);
        }
    }


    /**
     * 初始化控件的属性
     */
    private void loadParams() {
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs,R.styleable.UILibraryListItem);
        leftImage = typedArray.getDrawable(R.styleable.UILibraryListItem_leftImg);
        leftImageHeight = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_leftImg_height,128);
        leftImageWidth = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_leftImg_width,128);

        rightImage = typedArray.getDrawable(R.styleable.UILibraryListItem_rightImg);
        rightImageHeight = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_rightImg_height,128);
        rightImageWidth = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_rightImg_width,128);

        title = typedArray.getString(R.styleable.UILibraryListItem_title);
        titleTextColor = typedArray.getColor(R.styleable.UILibraryListItem_title_color,Color.BLACK);
        titleTextSize = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_title_size,20);

        subTitle = typedArray.getString(R.styleable.UILibraryListItem_subTitle);
        subTitleTextColor = typedArray.getColor(R.styleable.UILibraryListItem_subTitle_color,Color.GRAY);
        subTitleTextSize = typedArray.getDimensionPixelSize(R.styleable.UILibraryListItem_subTitle_size,14);
        typedArray.recycle();
    }

    /**
     * 关联控件
     */
    private void findView() {
        leftImageView =  FindView.findView(this,R.id.leftImg);
        rightImageView = FindView.findView(this,R.id.rightImg);
        titleView = FindView.findView(this,R.id.title);
        subTitleView = FindView.findView(this,R.id.subTitle);
    }


}

4.引用并预览
  引用时为了看出明显效果我定义了2个Item;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:uilib="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <com.uilib.ui.listitem.UILibraryListItem
        android:id="@+id/it"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        uilib:leftImg="@drawable/icon_a"
        uilib:rightImg="@drawable/icon_b"
        uilib:subTitle="SubTitle"
        uilib:title="Title" />

    <com.uilib.ui.listitem.UILibraryListItem
        android:id="@+id/it2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        uilib:leftImg="@drawable/test_icon_allow"
        uilib:subTitle="SubTitle"
        uilib:subTitle_color="@color/red"
        uilib:title="Title" />
</LinearLayout>

于是完成结果如下:
2017-08-11_004205.png

可以根据自己的实际情况灵活改变样式,且仅仅在第四步引用处做出更改即可;

总结


自定义View之组合;
通过组合来自定义View能满足我们大部分的需求,且相对容易。
总结其过程:
1.自定义属性
2.抽象出样式
3.编码实现类
4.引用和预览

我是ElyarAnwar,在技术的道路上摸爬滚打;
热爱生活,热爱技术;如果喜欢记得点赞;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,825评论 25 707
  • 一三五 二四六 时光拂过发梢 梧桐叶落生生 时光的墙板上 写满了 两千一百多昼夜呢喃 人来人往的路口 抬头 是你笑...
    往往以往阅读 165评论 2 0
  • 源码来自时序数据库InfluxDB的高可用套件InfluxDB-relay.
    lwhile阅读 232评论 0 0
  • 对越南的向往,是源于岘港那间占婆博物馆。 说了好几年,错过了好几次,终于成行。和从未想过一起出行的人出行(相关文章...
    黄小智子阅读 407评论 0 0
  • 经年故纸遗长恨,转眼成非 ,转眼成非,昨日深红已半飞。 丝弦和尽黄昏雨,一缕相催,一缕相催 ,渐有心思散作灰。
    baobei朵朵阅读 255评论 0 0