day03 创建自定义控件

1.Android 控件和布局的继承结构

这里写图片描述
可以看到,我们所用的多有的控件都是直接或间接继承自View的,所有的布局都是直接或间接继承自
ViewGroup的.View是android中一种基本的UI组件,它可以在屏幕上绘制一块矩形区域,并能够响应这块区域的各种事件.
而ViewGroup是一种特殊的View,它可以包含很多的子View和子ViewGroup,是一个用于放置控件和布局的容器.

而当系统的控件不满足我们的需求的时候,我们就可以利用系统的控件来创建自定义的控件.

2.自定义控件的使用方式

2.1 引入布局
如果我们的应用程序很多的界面都显示一个固定的标题栏,这个时候我们可以自定义一个xml文件,把那个需要的
标题栏写在这个xml文件中,在我们需要的地方引入即可.
title.xml (两个按钮,一个返回,一个编辑,中间是编辑文本的edittext)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#333333"
    android:orientation="horizontal"
    tools:context="com.example.my03_mycomponent.MainActivity"
    tools:ignore="HardcodedText" >

    <Button 
        android:id="@+id/btn_title_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="#22ff11"
        android:text="Back"
        android:textColor="#1100ff"
        />
    <TextView 
        android:id="@+id/tv_title_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:textSize="24sp"
        android:textColor="#22ff11"
        android:text="Title Text"
        />
    <Button 
        android:id="@+id/btn_title_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="5dp"
        android:background="#22ff11"
        android:text="Edit"
        android:textColor="#1100ff"
        android:textSize="24sp"
        />
</LinearLayout>

然后修改activity_main.xml中的代码:
activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <include layout="@layout/title"/>

</LinearLayout>

这样我们就通过
这一行代码将整个标题栏引入进来了.在MainActivity当中利用
requestWindowFreature(Window.FEATURE_NO_TITLE);将原来的title隐藏掉即可.
使用这种方式,不管有多少布局要引入标题栏,只需要一行代码即可.

2.2 创建自定义控件
引入布局的技巧确实解决了重复编写布局代码的问题,但是如果布局中有一些控件要求能够响应事件,我们还是
需要在每个活动中为这些控件编写事件注册和处理代码.比如说标题栏中的返回按钮,其实不管是哪一个活动
这个按钮的功能都是销毁当前的活动.而如果在每一个活动中都需要重新注册一般返回按钮的点击事件,无疑
增加了很多重复的代码,这种情况下最好是使用自定义控件的方式来解决.

新建TitleLayout继承自LinearLayout,让它成为我们自定义的标题栏控件,代码如下:

package com.example.my03_mycomponent;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;

/**
 * 自定义控件类
 *
 */
public class TitleLayout extends LinearLayout
{

    public TitleLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        /**
         * @R.layout.title 要加载的布局文件的id
         * @this 加载好的布局再添加到的一个父布局,这里是this
         */
        LayoutInflater.from(context).inflate(R.layout.title, this);
    }

}

然后在我们的activity_main.xml当中引入这个控件
修改activity_main.xml中的代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <com.example.my03_mycomponent.TitleLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </com.example.my03_mycomponent.TitleLayout>
</LinearLayout>

在xml文件布局文件中,添加自定义的控件和普通的控件是一样的,只不过在添加自定义控件的时候我们需要指明控件的完整类名和
包名.然后我们为标题栏中的按钮注册点击事件,修改TitleLayout中的代码:如下所示:
TitleLayout.java

package com.example.my03_mycomponent;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

/**
 * 自定义控件类
 *
 */
public class TitleLayout extends LinearLayout
{
    public TitleLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        /**
         * @R.layout.title 要加载的布局文件的id
         * @this 加载好的布局再添加到的一个父布局,这里是this
         */
        LayoutInflater.from(context).inflate(R.layout.title, this);

        Button btnBack  = (Button) findViewById(R.id.btn_title_back);
        Button btnEdit = (Button) findViewById(R.id.btn_title_edit);

        btnBack.setOnClickListener(new OnClickListener()
        {

            public void onClick(View v)
            {
                ((Activity)getContext()).finish();
            }
        });

        btnEdit.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View v)
            {
                Toast.makeText(getContext(), "You Click The Edit!", Toast.LENGTH_SHORT).
            }
        });
    }

}

这样的话,每当我们在一个布局中引入TitleLayout的时候,返回按钮和编辑按钮的点击事件就已经自动实现好了,也
就不用再每个activity当中去注册监听事件了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值