•前言

  常用控件和布局的继承结构,如下图所示:

    

  可以看到,我们所用的所有的控件都是直接或者间接的继承自View的;

  所用的所有布局都是直接或者间接继承自ViewGroup的;

  View 是 Android 中最基本的一种 UI 组件,它可以在屏幕上绘制一块矩形区域,并能相应这块区域的各种事件;

  因此,我们使用的各种控件其实是在 View 的基础之上又添加了各自特有的功能;

  而 ViewGroup 是一种特殊的 View,他可以包含很多 View 和子 ViewGroup,是一个用于放置控件和布局的容器;

•引入布局——创建自定义标题栏

  我们先来看一下标题栏的样式:

    

  面对这种标题栏的样式,只需要加入两个 Button 和一个 TextView,然后在布局中摆放好就可以了。

  可是这样做却存在着一个问题,一般我们的程序中可能有很多个活动都需要这样的标题栏;

  如果在每个活动的布局中都编写一遍同样的标题栏代码,明显就会导致代码的大量重复;

  这个时候,我们就可以使用引入布局的方式来解决这个问题;

  新建一个布局 title.xml,添加代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="10dp"> <Button
android:id="@+id/title_back"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="Back"
android:textAllCaps="false"
android:textSize="20sp"/> <TextView
android:id="@+id/title_text"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:text="Title Text"
android:textSize="20sp" /> <Button
android:id="@+id/title_edit"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:text="Edit"
android:textAllCaps="false"
android:textSize="20sp"/> </LinearLayout>

  可以看到,我们在 LinearLayout 中分别加入了两个 Button 和一个 TextView;

  左边的 Button 可以用于返回,右边的 Button 可用于编辑,中间的 TextView 则可以显示一段标题文本;

•自定义标题栏的使用

  现在标题栏布局已经编写完成了,剩下的就是如何在程序中使用这个标题栏了;

  修改 activity_main.xml 中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <include layout="@layout/title"/> </LinearLayout>

  我们只需要一行 include 语句将标题栏布局引入进来就可以了。

  最后别忘了在 MainActivity.java 中将系统自带的标题栏隐藏掉,代码如下:

public class MainActivity extends AppCompatActivity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); ActionBar actionbar = getSupportActionBar();
if(actionbar != null)
actionbar.hide();
}
}

  通过调用 getSupportActionBar() 方法来获得 ActionBar 的实例;

  然后调用 ActionBar 的 hide() 方法将系统自带的标题栏隐藏。

•创建自定义控件

  引入布局的技巧确实解决了重复编写布局代码的问题;

  但是如果布局中有一些控件要求能够响应事件,我们还是需要在每个活动中为这些控件单独编写一次实践注册的代码;

  比如说标题栏中的返回按钮,其实不管是在哪一个活动中,这个按钮的功能都是相同的,即销毁当前活动;

  而如果在每一个活动中都需要重新注册一遍返回按钮的点击事件,无疑会增加很多重复的代码;

  这种情况下最好使用自定义控件的方式来解决;

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

public class TitleLayout extends LinearLayout {

    public TitleLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.title,TitleLayout.this);

}

  首先我们重写了 LinearLayout 中带有两个参数的构造函数;

  在布局中引入 TitleLayout 控件就会调用这个构造函数;

  然后在构造函数中需要对标题栏布局进行动态加载,这就要借助 LayoutInflater 来实现;

  通过 LayoutInflater 的 from() 方法可以构建出一个LayoutInflater 对象。

  然后调用 inflate() 方法动态加载一个布局文件。

  inflate() 方法接收两个参数:

    • 第一个参数是要加载的布局文件的 id
    • 第二个参数是给加载好的布局再添加一个父布局

•自定义控件的使用

  现在自定义控件已经创建好了,然后我们需要在布局文件中添加这个自定义控件;

  修改 activity_main.xml 中的代码,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <com.example.uicustomviews.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" /> </LinearLayout>

  添加自定义控件和添加普通控件的方式基本上是一样的;

  只不过在添加自定义控件的时候,我们需要指明控件的完整类名,包名在这里是不可以省略的。

  下面我们尝试为标题栏中的按钮注册点击事件,修改 TitleLayout 中的代码,如下所示:

public class TitleLayout extends LinearLayout {

    public TitleLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.title,TitleLayout.this); Button back = findViewById(R.id.title_back);
back.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
//为 back 按钮设置点击事件
}
}); Button edit = findViewById(R.id.title_edit);
edit.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
//为 edit 按钮设置点击事件
}
});
}
}

Android Studio 之创建自定义控件的更多相关文章

  1. Android Studio中创建Kotlin For Android项目

    Kotlin俗称Android中的Swift,它是Jetbrains公司开发的基于JVM的一门语言,JetBrains公司可能大家并不熟悉,不过相信IntelliJ IDE大家一定知道,Android ...

  2. Android studio 中创建AIDL Service

      1.概述  AIDL在android系统中的作用 AIDL,Android Interface definition language的缩写,它是一种android内部进程通信接口的描写叙述语言, ...

  3. Android实验一(在Android Studio中创建项目和模拟器)

    北京电子科技学院(BESTI) 实     验    报     告 课程:移动平台开发         班级:1592 姓名:苏泽楠 学号:20159207 成绩:             指导教师 ...

  4. 在Android Studio中创建项目和模拟器

    北京电子科技学院 实      验      报      告 课程:移动平台应用开发实践  班级:201592  姓名:杨凤  学号:20159213 成绩:___________  指导老师:娄嘉 ...

  5. android studio 不能创建或者安装模拟器

    解决方法: (1).对与这类问题实在不行卸载然后安装,看看自己的网络是否把android studio下载的东西给墙了,墙了记得换网. (2).我安装andriod studio 2.2.2.0 版本 ...

  6. android学习——Android Studio下创建menu布局文件

    一.问题: android studio项目中没有看到menu文件夹: 在android studio项目中想要添加menu布局文件,一开始我的做法是:直接在res文件夹右键选择xml文件来添加,如下 ...

  7. Android Studio下创建menu布局文件

    一.问题: android studio项目中没有看到menu文件夹: 在android studio项目中想要添加menu布局文件,一开始我的做法是:直接在res文件夹右键选择xml文件来添加,如下 ...

  8. Android学习笔记之Android Studio下创建menu布局文件

    1.创建menu文件夹 Android Studio项目中如果没有menu文件夹,在res文件夹右键,new-Android resource directory: 则会弹出下图对话框,在Resour ...

  9. 在Android Studio中创建(或添加)第一个Hello World应用程序

    下面我们将使用Android Studio创建第一个简单的Hello World应用程序. 1.打开Android Studio,加载画面如下图所示:   2.选择”Start a new Andro ...

随机推荐

  1. Github access token

    Github access token https://github.com/settings/tokens https://docs.github.com/en/free-pro-team@late ...

  2. iPhone 12 导入通讯录排序 Bug

    iPhone 12 导入通讯录排序 Bug iOS iOS 通讯录排序问题 Huawei OK solution iOS 切换中英文,修复排序通讯录 bug Awesome iOS Contacts ...

  3. Python Web Frameworks

    Python Web Frameworks top 10 Python web frameworks Django (Full-stack framework) Flask (Micro framew ...

  4. HTML5 Canvas in Action

    HTML5 Canvas in Action canvas 图片处理 视频编辑工具 xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  5. node mailer & email bot

    node mailer & email bot email https://nodemailer.com/about/ https://github.com/nodemailer/nodema ...

  6. iPad Pro 如何通过 USB-C 接口外接机械键盘

    iPad Pro 如何通过 USB-C 接口外接机械键盘 外接机械键盘 Type-C Dock OK,cnblogs 图片文件不能超过20M https://support.apple.com/zh- ...

  7. C++算法代码——众数

    好久没更新了-- 题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1615 题目描述 N 个 1 到 30000 间无序数正整数,其中 ...

  8. 详解SSH 框架中对象调用流程

    摘要:SSH=Struts+Spring+Hibernate SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用 ...

  9. 敏捷史话(七):从程序员、作家到摇滚乐手——Andy Hunt的多面人生

    与其说 Andy Hunt 是敏捷宣言的创始人,不如说他是一名专业作家来得更为合适.他的<实用程序员><程序员修炼之道:从小工到专家><编程 Ruby:实用程序员指南&g ...

  10. Linux的启动过程及init进程

    Linux下有三个特殊进程: idle进程(pid=0)idle进程其前身是系统创建的第一个进程,0号进程,也唯一一个没有通过fork()或者kernel_thread产生的进程,由系统自动创建,运行 ...