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

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

作者: 入梦瞌睡 | 来源:发表于2019-10-25 16:25 被阅读0次

    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——自定义控件(二)

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/rpzupctx.html