android开发系列之使用xml自定义控件

在android开发的过程中,有的时候面对多个Activity里面一些相同的布局,我们需要写多次相同的代码,同时这种方法给我们的项目维护也带来了很大不便。那么有没有一种可行的办法能够将Activity里面相同的布局拆分的很清楚呢?当然是有的,这个时候就轮到自定义控件闪亮登场了。

其实在android里面有多种方法去实现自定义控件,但是今天这篇博客里面只介绍使用xml的方式进行自定义控件的创建。请看下面的这种场景,不管在哪个页面里面都有个标题,包括一条居中的文本信息和在左边的返回按钮。这个时候我们就可以将上面的标题拆分成一个控件,然后在该控件里面暴露出一个text属性和一个按钮的点击事件。

首先让我们先来创建一个前台的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="match_parent"
    android:background="@color/test"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/tvBack"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="<"
        android:layout_alignParentLeft="true" />

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录"
        android:layout_centerHorizontal="true"/>

</RelativeLayout>

可以看到在上面的布局里面,我们只是放置了两个TextView,一个表示返回,另一个则表示title。

看到这里聪明的你也许就能猜到了,会不会在自定义控件的时候,我们也同样需要采用某种方法加载上面的布局文件,然后在加载的时候同时关联自己定义好的属性和事件到上面返回的TextView点击事件和标题的TextView的text属性呢?是的,请看比较重要的后台关联代码类定义:

public class TitleControl extends RelativeLayout {
}

可以发现TitleControl我们是直接从RelativeLayout继承而来的,这样的话TitleControl就属于一种View控件了。接下来所要做的事情,就是定义属性和事件了。现在假设我们需要定义一个MyText属性,那么应该怎么做呢?请看如下代码:

public class TitleControl extends RelativeLayout {

    private TextView tvBack, tvTitle;
    private String title;

    public TitleControl(Context context) {
        super(context);
    }

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

        View view = View.inflate(context, R.layout.activity_title, this);
        tvTitle = (TextView) view.findViewById(R.id.tvTitle);

        tvBack = (TextView) view.findViewById(R.id.tvBack);
        tvBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.title);
        title = a.getString(R.styleable.title_MyText);
        a.recycle();

        tvTitle.setText(title, TextView.BufferType.SPANNABLE);

    }

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

在上面的代码里面我们通过View的inflate方法加载前台页面,然后通过findViewById方法就找到了前台需要关联的控件了。但是我们自己定义的属性放在哪里呢?一种比较容易维护的做法就是将属性放置在xml文件里面。下面就让我们来看看属性的xml代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="title">
        <attr name="MyText" format="string"/>
    </declare-styleable>
</resources>

当我们定义好属性xml之后,就可以通过下面的这段代码,将我们自己定义的MyText属性关联到TextView的Text属性上面了。这样就相当于实现了自定义属性。

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.title);
title = a.getString(R.styleable.title_MyText);
a.recycle();

tvTitle.setText(title, TextView.BufferType.SPANNABLE);

做到这里我们就差一个自定义事件了,那么我们怎样去定义一个事件关联到TextView的点击上面呢?答案是通过回调方法的方式实现的,请看回调方法的定义:

private ITitleCallback iTitleCallback;

    public interface ITitleCallback {
        void OnBackClickLinear();
    }

    public void setTitleClickLinear(ITitleCallback iTitleCallback) {
        this.iTitleCallback = iTitleCallback;
    }

然后在TextView点击的时候执行如下代码就可以了:

tvBack = (TextView) view.findViewById(R.id.tvBack);
        tvBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(iTitleCallback!=null){
                    iTitleCallback.OnBackClickLinear();
                }
            }
        });

好了,今天就到这里吧!如有不对,欢迎拍砖。

时间: 2024-10-14 01:05:55

android开发系列之使用xml自定义控件的相关文章

C#程序员学习Android开发系列之ListView

上篇博客解决了Android客户端通过WebService与服务器端程序进行交互的问题,这篇博客重点关注两个问题,一个是Android应用程序如何与本机文件型数据库SQLite进行交互,另一问题则是如何在ListView中按照我们想要的界面效果进行展示.限于篇幅这篇重点讲ListView,下篇博客重点阐述SQLite. ListView是一个常用的数据显示控件,假设我们要做一个简单的界面,如图所示. 这张图是我直接从Android平板电脑(Android 4.2.2)上面截图下来的,就是一个普通

C#程序员学习Android开发系列之学习路线图

通过前面的3篇博客已经简单的介绍了Android开发的过程并写了一个简单的demo,了解了Android开发的环境以及一些背景知识. 接下来这篇博客不打算继续学习Android开发的细节,先停一下,明确一下接下来的学习目标以及学习路线. 一.对Android开发的基本认识 1.Android原生开发是基于Java语言的,由于我比较擅长C#,所以对Java语言本身不太熟练,需要加强Java语言基础的练习,这一块我会穿插到具体的知识点练习当中,并且在必要的地方给出与C#语言的对比(其实基本上在语法层

快速Android开发系列网络篇之Retrofit

Retrofit是一个不错的网络请求库,用官方自己的介绍就是: A type-safe REST client for Android and Java 看官网的介绍用起来很省事,不过如果不了解它是怎么实现的也不太敢用,不然出问题了就不知道怎么办了.这几天比较闲就下下来看了一下,了解一下大概实现方法,细节就不追究了.先来看一个官网的例子,详细说明去网官看 简单示例 首先定义请求接口,即程序中都需要什么请求操作 public interface GitHubService { @GET("/use

C#程序员学习Android开发系列之Android项目的目录结构

今天开始正式学习Android开发的种种细节,首先从最基本的概念和操作学起. 首先看一下Android项目的目录结构. 这是我随便建立的一个test项目,我们重点关注一下几个方面的内容: 1.src目录:存放java源代码的目录,里面建立一个包,包里面有4个java源文件(分别都继承自Activity).由于java要求比较严格,因此要求类名与文件名一致. gen(Generated Java Files)目录:自动产生Java源文件的目录,是由工具自动生成的,一般不需要自己修改.里面主要有一个

C#程序员学习Android开发系列之调用WebService

我在学习Android开发过程中遇到的第一个疑问就是Android客户端是怎么跟服务器数据库进行交互的呢?这个问题是我当初初次接触Android时所困扰我的一个很大的问题,直到几年前的一天,我突然想到WebService是否可以呢?让WebService充当服务器端的角色,完成与服务器数据库操作相关的事情,而Android客户端只要按照WebService方法参数的要求去调用就行了.在当时我对这个解决方案的实现还没模糊,我想这个问题也是初学Android的朋友肯定会想到的问题.那么现在就让我们动

Android开发系列(五):Android应用中文件的保存与读取

在本篇博客中,我们要实现在Android中"新建文件"和"读取文件": 目标界面: 在输入文件名称之后,输入文件内容,点击保存,可以保存成为一个文档 首先,我们先建立一个Android Project项目,项目名称:File. 然后,我们需要先实现目标视图中的界面: 编辑strings.xml文件: <?xml version="1.0" encoding="utf-8"?> <resources> &

C#程序员学习Android开发系列之按钮事件的4种写法

经过前两篇blog的铺垫,我们今天热身一下,做个简单的例子. 目录结构还是引用上篇blog的截图. 具体实现代码: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 方法1.

android开发中eclipse里xml开发的自动提示和使用帮助快捷键提示

Eclipse Android 代码自动提示功能 Eclipse for android 设置代码提示功能 打 开 Eclipse 依次选择 Window > Preferences > Java > Editor - Content Assist > Auto activation triggers for Java ,设置框中默认是一个点, .abcdefghijklmnopqrstuvwxyz(, 打 开 Eclipse 依次选择 Window > Preference

快速Android开发系列网络篇之Android-Async-Http

快速Android开发系列网络篇之Android-Async-Http 转:http://www.cnblogs.com/angeldevil/p/3729808.html 先来看一下最基本的用法 AsyncHttpClient client = new AsyncHttpClient(); client.get("http://www.google.com", new AsyncHttpResponseHandler() { @Override public void onSucce