Android开发技巧——自定义控件之组合控件

我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等。
还是那句老话,尽管我知道会被爬虫机器给过滤掉。
本文原创,转载请注明在CSDN博客上的出处:
http://blog.csdn.net/maosidiaoxian/article/details/49884261

今天写第一篇,就先写一下最简单的,也就是我们大概最早接触的一类自定义——组合控件。
这里仅讨论使用布局文件来进行组合控件。
为什么不用Java代码来写布局?原因是没有布局文件直观明了,能预览,好维护。

下面来看一个例子。
假如我们在一个界面当中的某部分布局,在另外一个界面中也会用到。

例如如上图所示,圈起来的内容,可能除了在支付界面上用到,在记录界面上也会用到,那么,你会如何处理这种情况呢?。我们先把布局实现一下:

<?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"android:paddingLeft="16dp"android:paddingRight="16dp"android:background="#494949"><TextView
        android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_toLeftOf="@+id/login_register"android:text="@string/login_guide_text"android:textColor="@color/white"android:textSize="@dimen/text_28pt"/><TextView
        android:id="@+id/login_register"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="@string/u_login_or_register"android:textColor="@color/font_span"android:textSize="@dimen/text_28pt"/>
</RelativeLayout>

接着:

直接复制代码

最新手的做法是,选中,复制,到另一个布局文件粘贴。然后会发现,要改一下界面的时候,要两边跟着改。直到我们学习了<include>标签之后。

使用<include>标签

于是,我们把这部分界面给抽出来,到一个新的布局文件中。然后在两个布局当中都include一下。现在如果要改这部分的界面,我们只需要改抽出来的那个文件即可,如果不涉及到所include的布局本身的属性的话。
现在看来是不是好多了?尽管只看布局代码是这样的,但是——
通常我们都不是写一个界面就这样了事了,我们还要在Java代码上,对一些控件设置一些文字,背景色,或是设置点击事件等等。而这部分的界面相同,它们的UI逻辑通常情况下也是相同的。显然,同样的代码要写两遍,作为一个有着懒惰习惯的程序员来说,当然是极极不情愿的。

自定义组合控件

于是我们定义一个类,继承自ViewGroup的子类,因为我们这里是组合一些控件,这些控件是要放在一个控件的容器里,所以不能是继承自View。我们把这个类命名为 LoginTipView,代码如下:

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;/*** 提示去登录注册的View* @author Geek_Soledad* @since 15-5-26*/
public class LoginTipView extends RelativeLayout implements View.OnClickListener{private TextView mLogin;public LoginTipView(Context context, AttributeSet attrs) {super(context, attrs);addView(View.inflate(context, R.layout.view_login_tip, null));mLogin = (TextView) findViewById(R.id.login_register);mLogin.setOnClickListener(this);}@Overridepublic void onClick(View v) {getContext().startActivity(new Intent(getContext(), LoginActivity.class));}
}

看这一行代码:

        addView(View.inflate(context, R.layout.view_login_tip, null));

我们把一个布局,通过View.inflate()方法加载出来,并且通过调用addView方法,把它加到我们的LoginTipView中。
然后在我们其他使用到这部分界面的布局代码中这样引用:

    <com.parkingwang.widget.LoginTipView
        android:id="@+id/login_view"android:layout_width="match_parent"android:layout_height="42dp"android:layout_alignParentBottom="true"tools:visibility="visible"android:visibility="gone"/>

并且由于我们的登录的点击事件写在了LoginTipView里,所以我们甚至不需要在其他的Java代码里来设这个点击事件。
但是上面的代码还是有很大的优化余地的。最主要的是,我们的LoginTipView本身就继承自RelativeLayout,而它里面又放了一个我们从布局文件中加载的RelativeLayout,显然这部分内容可以合并。下面开始优化:

优化

首先,我们把布局代码的根元素改为`标签:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"><TextView
        android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toLeftOf="@+id/login_register"android:text="@string/login_guide_text"android:layout_alignParentLeft="true"android:textColor="@color/white"android:textSize="@dimen/text_28pt"/><TextView
        android:id="@+id/login_register"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="@string/u_login_or_register"android:textColor="@color/font_span"android:textSize="@dimen/text_28pt"/>
</merge>

然后LoginTipView代码改为如下:

public class LoginTipView extends RelativeLayout implements View.OnClickListener{private TextView mLogin;public LoginTipView(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.view_login_tip, this, true);this.setGravity(Gravity.CENTER_VERTICAL);int padding = getResources().getDimensionPixelSize(R.dimen.padding_common);this.setPadding(padding, 0, padding, 0);mLogin = (TextView) findViewById(R.id.login_register);mLogin.setOnClickListener(this);this.setBackgroundResource(R.color.bg_login_tip_view);}@Overridepublic void onClick(View v) {LoginMainActivity.showWithClosable((Activity) getContext());}
}

注意,我们现在加载布局的代码改为了LayoutInflater.from(context).inflate(R.layout.view_login_tip, this, true);,当然,使用View.inflate(context, R.layout.view_login_tip, this);也是一样的,后者在方法里面也是在调用前者的方法。然后,因为我们已经改为<merge>标签了,所以要把公共的属性写到我们的LoginTipView代码里(当然,你也可以不写,那你就需要在引用这个控件的布局代码里设置其对应属性)。

我们的优化过程是,使用<merge>标签,并在inflate时传入一个ViewGroup对象,使布局文件<merge>里的控件直接加载到这个ViewGroup里,减少层级。

对于这种自定义控件,其实可以说是对组合使用的控件的封装。需要注意的是,这时候你在<merge>元素本身定义的布局属性都是无效的。而这些你需要设定的属性,比如上面例子中的背景色,你可以写在你所封装的控件里,也是写在引用它的布局里。

下篇预告:
应该会讲一下onDraw(Canvas)来实现自定义吧。

Android开发技巧——自定义控件之组合控件相关推荐

  1. Android开发学习笔记-自定义组合控件

    为了能让代码能够更多的复用,故使用组合控件.下面是我正在写的项目中用到的方法. 1.先写要组合的一些需要的控件,将其封装到一个布局xml布局文件中. <?xml version="1. ...

  2. ASP.NET自定义控件组件开发 第四章 组合控件开发CompositeControl

    第四章 组合控件开发CompositeControl 大家好,今天我们来实现一个自定义的控件,之前我们已经知道了,要开发自定义的控件一般继承三个基 类:Control,WebControl,还有一个就 ...

  3. Android开发技巧——自定义控件之自定义属性

    Android开发技巧--自定义控件之自定义属性 掌握自定义控件是很重要的,因为通过自定义控件,能够:解决UI问题,优化布局性能,简化布局代码. 上一篇讲了如何通过xml把几个控件组织起来,并继承某个 ...

  4. (转)android UI进阶之自定义组合控件

    第一个实现一个带图片和文字的按钮,如图所示: 整个过程可以分四步走.第一步,定义一个layout,实现按钮内部的布局.代码如下: [html] view plaincopy <?xml vers ...

  5. Android自定义组合布局,Android 流式布局 + 自定义组合控件

    自定义组合控件 package yanjupeng.bawei.com.day09.two; import android.content.Context; import android.util.A ...

  6. android自定义控件中文乱码,Android笔记--自定义View之组合控件

    Android-自定义View 分享是最好的记忆-- 如需转发请注明出处 [强调]:共同学习 共同进步 不喜勿喷 内容简介 前言 实现 总结 1. 前言 这次更新有2个目的 1. 复用控件,而不是每次 ...

  7. Android开发之如何实现日历控件

    我们大家都知道,在Android平台3.0中才新增了日历视图控件,可以显示网格状的日历内容,那么对于3.0以下的版本要使用日历控件只能借助第三方,目前用的最多的是CalendarView. 先简单介绍 ...

  8. Android开发之自定义随机验证码控件

    版权申明]非商业目的注明出处可自由转载 博文地址:https://blog.csdn.net/ShuSheng0007/article/details/81455593 出自:shusheng007 ...

  9. android触摸效果,Android开发进阶:仿MIUI12控件触摸反馈效果(下沉+倾斜)附源码...

    简单模仿了下MIUI12里控件的触摸反馈效果,转载请标明出处 效果简述 按压控件内圈区域,控件整体缩小,高度降低(阴影消失) 按压内圈 按压控件外圈区域,依据触摸点控件以中心为支点,向触摸点倾斜 按压 ...

最新文章

  1. Ubuntu下Qt配置Opencv
  2. 喜报!中华万年历签约神策数据
  3. Lucene6.0 创建索引及查询text简单实例
  4. c#的http服务器和客户端实例
  5. Spring Security应用程序中的su和sudo
  6. 使用gdb调试多进程程序、同时调试父进程和子进程
  7. redis本地及远程登录
  8. springMVC 控制层添加异步线程
  9. 识别图片噪声干扰_射频相位噪声介绍
  10. spl_autoload_register函数
  11. nginx php 慢,Nginx+PHP-FPM时快时慢的解决
  12. 超参数调整——网格搜索
  13. 百家号怎么加网站链接进行引流,方法让你轻松掌握
  14. 动态规划(DP算法)详解
  15. 记一次 jenkins 构建失败 “Cannot find module ‘core-js/modules/es.promise.finally‘”
  16. Wifi热点java_java实现笔记本电脑设置成WiFi热点
  17. 记一次对PUBG吃鸡外挂病毒的反制过程
  18. 10----编程分苹果
  19. 内存管理(15)——UI(20)——DeleteObject
  20. 美团C++软件开发笔试题

热门文章

  1. 从遥感卫星(Rapideye)的视角见证“蚂蚁森林”的生长——以“蚂蚁森林1号林”为例
  2. 基于Appian低代码平台开发一个SpaceX网站
  3. 胡适说:他拍的是真正如画的北京
  4. 防止电子邮件网络钓鱼攻击的10种方法
  5. 1384Piggy-Bank
  6. CornerStone Unresolved conflicts exist for some items
  7. 从威客到互联网进化论的五年历程
  8. 你最该学的职场必修课[职场规划个人笔记]
  9. 项目经理的权力永动机
  10. 有限元三角形单元的等效节点力