[Android]开发App,你得知道这些6——自定义控件(一)

0.前言

  • 上一篇文章中,我们讲解了Android的动画
    有兴趣的可以去看一看

准备工作

在读本文前,你最好有以下准备:

  • (1)安装Android Stuido(以下简称AS
  • (2)有一定的Java基础
  • (3)有一台安卓机
    (可以用模拟器来代替,包括AS自带的以及网上的一些著名模拟器)
  • 若想要了解有关Java的文章等其他主要知识,可以去看前面的文章

(不会使用AS的读者可以参考下面这篇文章中的例子)
[Java]开发安卓,你得掌握的Java知识2

1.本文内容简介

  • 自定义控件基础

  • 组合方式自定义控件

2.基础知识讲解

自定义控件

  • 自定义控件的最主要原因,是系统的控件无法满足自身需求
  • 自定义控件有多种方法:
    (1)组合方式——纯粹用系统控件拼接,实现相应功能
    (2)继承方式——自定义一个继承于对应容器(Layout)的类,然后在已有的控件基础上添加新的功能
    (3)自绘方式——自己画一个新的控件


自定义控件——继承方式

  • 组合方式属于自定义控件里面较常用的一种
    通过自定义一个(继承于某layout)类,对原有的控件进行组合(这方面类似组合方式),并且通过更多的java代码来使得这个控件变得像一个系统控件
  • 核心思想就是:
    1.创建一个类,然后看情况让这个类继承与某种布局(layout)
    2.继承之后,重写对应的3个方法
    3.通过3个方法完成两种创建控件的方法(java代码和xml文件)
  • 具体操作在第3部分
    这个内含多个控件的容器,就相当于是一个自定义的控件

3.具体代码操作

组合方式自定义控件的效果图:

  • 自定义一个导航栏形式的控件
    左右两边的按钮可以设置点击事件
  • 这里设置的就是变颜色的点击事件



继承方式的控件

java代码部分

第零步 准备好drawable资源

1.找到drawable




2.右键->New->Drawable resource file




3.取名叫做title_shape



4.把select改成layer-list,并且添加对应代码


<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <stroke android:width="2dp"
                android:color="#000000"/>
        </shape>
    </item>
    <item android:bottom="1dp">
        <shape>
            <solid android:color="#ffffff"/>
        </shape>
    </item>

</layer-list>

同理,创建一个button_shape.xml


<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#9B9A9A"/>
            <corners android:radius="2dp"/>
            <size android:width="20dp"
                android:height="10dp"/>
        </shape>
    </item>
</selector>
第一步 创建一个类


第二步 继承于某个容器

第三步(一) 重写三个具体的方法

选择这前三个(第四个不是)



第三步(二) 搞清楚三个构造函数的作用
  • 第一个构造函数,是用于java代码创建的


  • 第二个构造函数,是用于xml文件创建的


  • 第三个构造函数,是用于xml文件创建的,最后一个属性的style


第四步 在对应的构造函数中添加代码
  • 找到第一个构造方法



    在这个代码中添加固定的控件



    在这里面像之前一样添加控件
    素材(右键另存为):
//1.定义一个返回按钮
ImageView returnButton = new ImageView(context);

//2.返回按钮设置资源
returnButton.setBackgroundResource(R.drawable.return_btn2);

//3.设置属性
LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.width = dpToPixel(20);
layoutParams.height = dpToPixel(20);
layoutParams.addRule(CENTER_VERTICAL);

//4.将返回按钮添加到容器中
addView(returnButton,layoutParams);
  • ViewGroup.LayoutParams.WRAP_CONTENT表示内容多大,控件多大

  • addRule(CENTER_VERTICAL)表示垂直方向居中

  • 如果还对一些内容不是很清楚的,可以去看前面的文章
    [Android]开发App,你得知道这些1——基础

  • 其中,dpToPixel,是一个自己写的一个方法,将dp变为pixel

public int dpToPixel(int dp){
        float density = getResources().getDisplayMetrics().density;
        return (int) (density * dp);
}

效果图:


第五步 把添加返回按钮的代码封装起来

就是把原来的代码复制到一个独立的函数中,然后把这个函数名留在原地

private void setReturnBtn(Context context) {

        //1.定义一个返回按钮
        returnButton = new ImageView(context);

        //2.返回按钮设置资源
        returnButton.setBackgroundResource(R.drawable.return_btn2);

        //3.设置属性
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.width = dpToPixel(20);
        layoutParams.height = dpToPixel(20);
        layoutParams.addRule(CENTER_VERTICAL);


        //4.将返回按钮添加到容器中
        addView(returnButton,layoutParams);
    }
第六步 重复上述步骤,添加标题和右边的编辑按钮
  • 设置标题:
private void setTitle(Context context,String title) {

        //1.定义
        TextView textView = new TextView(context);
        //2.设置标题
        textView.setText(title);
        //3.设置字体大小
        textView.setTextSize(15.0f);
        //4.设置参数
        LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//        params.gravity = Gravity.CENTER_HORIZONTAL;
        params.addRule(CENTER_IN_PARENT);

        //5.添加控件
        addView(textView,params);
    }
  • 设置右边按钮:
private void setRightBtn(Context context,String contain) {
        //1.定义
        rightBtn = new TextView(context);
        //2.设置背景
        rightBtn.setBackgroundResource(R.drawable.button_shape);

        //3.设置属性
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.addRule(ALIGN_PARENT_RIGHT);
        layoutParams.width = dpToPixel(60);
        layoutParams.height = dpToPixel(30);
        rightBtn.setText(contain);
        rightBtn.setGravity(Gravity.CENTER);

        //添加到容器中
        addView(rightBtn,layoutParams);
    }
  • 最后构造函数的样子:
public Title(Context context,boolean hasReturnBtn, int background,String title,String rightBtn) {
        super(context);
        //设置水平布局以及背景色
        setBackgroundResource(background);
      //设置内边距,保证按钮什么的不会贴着边
        setPadding(20,20,20,20);

        //-------------返回按钮---------------//
        if (hasReturnBtn) {
            setReturnBtn(context);
        }

        //-------------中间标题---------------//
        if (title != null) {
            setTitle(context,title);

        }

        //-------------最右边的分享按钮---------------//
        if (rightBtn != null) {
            setRightBtn(context,rightBtn);

        }
    }
    1. 可能有些读者觉得有点快,但是如果真的要一点一点来的话,整篇文章会极其长,后面两个控件的书写思想其实和返回按钮是一样的,都是先在构造函数中书写对应代码进行测试,然后再取出来进行封装
  • 2.有些眼尖的观众可能已经发现了,构造函数跟原来不一样了,多了很多参数,其实一开始书写确实是按照之前说的那个构造函数里面写的,但是后来发现一个参数并不够用,就需要自己写一个独立的构造函数


3.为什么构造函数要这么多参数?

这些参数与setBackgroundResource(background);等函数的参数有关,这些参数是必须设置的

  • 为避免用户忘记设置,或者是搞错设置顺序,就需要在构造函数中进行设置
第七步 在MainActivity中完成控件的添加

完整代码:

//找到这个RelativeLayout容器
        rl = findViewById(R.id.rl_root);

        //1.定义一个
        title = new Title(this,true,R.drawable.title_shape,"Title","分享");


        //设置属性用的
        RelativeLayout.LayoutParams rLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        rl.addView(title,rLayoutParams);

效果:


第八步 添加点击事件
  • 在Title中添加点击事件的入口:



    这样就能用原先控件自带的点击事件了,代码:

    //设置返回按钮事件
    public void setReturnBtnClickListener(OnClickListener onClickListener){
        returnButton.setOnClickListener(onClickListener);
    }

    //设置右边的按钮事件
    public void setRightBtnClickListener(OnClickListener onClickListener) {
        rightBtn.setOnClickListener(onClickListener);
    }

在MainActivity中,使用这两个方法

 title.setReturnBtnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rl.setBackgroundColor(Color.BLACK);
            }
        });

        title.setRightBtnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                rl.setBackgroundColor(Color.RED);
            }
        });

还没完,由于篇幅原因,剩下的内容下回分解

[Android]开发App,你得知道这些7——自定义控件(二)

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