Android 第八课 创建自定义控件

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

(待续。。。。)

所有的控件都是直接或间接继承自View的所用的所有布局都是直接或间接继承自ViewGroup的,View是Android中最基本的一种UI组件,它可以在屏幕上绘制一块矩形区域,并能响应这块区域的各种事件,ViewGroup是一中特殊的View,它可以包含很多的子View和子ViewGroup,是一个用于放置控件和布局的容器

我们可以利用上面的继承结构来创建自定义控件,创建自定义控件的两种简单方法如下所示。

我们先创建一个UICustomViews项目。

1、引入布局

Android系统已经给每个活动提供了标题栏功能,但我们决定先不使用它,而是创建一个自定义的标题栏。

只需要两个Button和一个TextView,然后在布局中摆好就可以了,但是一般我们的程序中可能有很多个活动都需要这样的标题栏,如果在每个活动的布局中都编写一遍同样的标题栏代码,明显的就会导致代码的大量重复,这个时候,我们可以引入布局的方式来解决这个问题。我们在layout目录下新建一个布局文件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="wrap_content"><Buttonandroid:id="@+id/title_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="5dp"android:background="#000"android:text="Back"android:textColor="#f00"/><TextViewandroid:id="@+id/title_text"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_weight="1"android:gravity="center"android:background="#000"android:text="Title Text"android:textColor="#f5f"android:textSize="24sp"/><Buttonandroid:id="@+id/title_edit"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="5dp"android:background="#000"android:text="Edit"android:textColor="#f00"/>
</LinearLayout>

我们在LinearLayout中分别加入了两个Batton和一个TextView,左边的Button可用于返回,右边的Button可用于编辑,中间的TextView则可以用来显示一段标题文本。熟悉一下属性,其中android:backgroud用于为布局或控件指定一个背景,可以使用颜色或者是照片来进行填充。

另外在两个Button中我们都使用了android:layout_margin这个属性,它可以指定控件在上下左右方向上偏移的距离,当然也可以使用android:layout_marginLeft或者android:layout_marginTop等属性来单独指定控件在某个方向上偏移的距离。

那么标题栏文件title.xml我们已经编写完成,那我们如何在程序中使用这个标题栏呢,修改acticity_main.xml中的代码,如下:

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

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

但是最后,不要忘了在MainActivity中将系统自带的标题栏隐藏掉,代码如下:

package com.example.uicustomviews;import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); ActionBar actionBar = getSupportActionBar();if(actionBar != null){actionBar.hide();}}
}

我们调用了getSupportActionBar()方法来获得ActionBar的实例,然后再调用ActionBar的hide()方法将标题栏隐藏起来。

使用这种方式,不管有多少布局需要标题栏,只需要一行include语句就可以了。

测试用例如下:


2、创建自定义组件

引入布局的技巧确实解决了重复编写布局代码的问题,但是如果布局中有一些控件要求能够响应事件,我们还是需要在每个活动中为这些控件单独编写一次事件注册的代码。比如说,标题栏的返回按钮,不管在哪一个活动中,都是用来销毁当前活动。为了不增加重复代码,我们使用自定义控件的方式来解决。

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

package com.example.uicustomviews;import android.content.Context;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ActionBar actionBar = getSupportActionBar();if(actionBar != null){actionBar.hide();}}public class TitleLayout  extends  LinearLayout {public TitleLayout(Context context, AttributeSet attrs) {super(context, attrs);LayoutInflater.from(context).inflate(R.layout.title, this);}}
}

我们重写了LinearLayout中带有两个参数的构造函数,在布局文件中引入TitleLayout控件就会调用这个构造函数,然后在构造函数中需要对标题进行动态加载,这就是要LayoutInflator来实现了。通过LayoutInflator的from()方法可以构建出一个LayoutInflater对象,然后调用inflator()方法就可以动态加载一个布局文件,inflate()接收两个参数,第一个参数是要加载的布局文件的id,我们传入的是R.layout.title,第二个参数是给加载好的布局再添加一个父布局,我们指定为TitleLayout,于是直接传入this。

现在自定义控件已经建好,3、我们还需要在布局文件中添加这个自定义控件,修改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.TitleLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout>

重新运行程序!

为标题栏的按钮注册点击事件,修改TitleLayout中的代码,如下:

package com.example.uicustomviews;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);LayoutInflater.from(context).inflate(R.layout.title, this); Button titleBack = (Button) findViewById(R.id.title_back);Button titleEdit = (Button) findViewById(R.id.title_edit);titleBack.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {((Activity) getContext()).finish();}});titleEdit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(getContext(), "You clicked Edit button",Toast.LENGTH_SHORT).show();}});}}

首先通过findViewById()方法得到按钮的实例,然后分别调用setOnClickListener()方法给两个按钮注册了点击事件,当点击返回按钮时,销毁当前的活动,当点击编辑按钮时弹出一段文本。

效果如下图:


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/274119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

figma下载_搬到Figma对我意味着什么

figma下载A couple of years ago, amidst the boom of new design and prototyping software, I was pretty reluctant to fight on the Figma/Sketch cold war. I was working on a relatively small design team and, after years helping to design products, well sold on …

解决IE中img.onload失效的方法

解决IE中img.onload失效的方法 - CoffeeCats IT Blog - IT博客http://www.cnitblog.com/CoffeeCat/archive/2008/02/01/39533.htmlFirefox、Google Chrome不存在问题&#xff01;为什么onload没有被IE调用呢&#xff1f;因为IE会缓存图片&#xff0c;第2次加载的图片&#xff0…

Android 第九课 常用控件-------ListView

ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内&#xff0c;同时屏幕上原有数据将会滚动出屏幕。 1、ListView简单用法 如何将ListView将你要显示的大量内容关联起来呢&#xff1f;这是个很重要的问题。 1、首先我们必须先将数据提供好&#xff0c;因为你的…

Singleton patterns 单件(创建型模式)

1、模式分类 1.1 从目的来看&#xff1a; • – 创建型&#xff08;Creational&#xff09;模式&#xff1a;负责对象创建。 • – 结构型&#xff08;Structural&#xff09;模式&#xff1a;处理类与对象间的组合。 • – 行为型&#xff08;Behavioral&…

Android 第十一课 SQlite 数据库存储

Android 为了让我们能够更加方便的管理数据库&#xff0c;特意提供了一个SQLiteOpenHelper帮助类&#xff0c;通过借助这个类就可以非常简单的对数据库进行创建和升级。 SQLiteOpenHelper是一个抽象类&#xff0c;我们要创建一个自己的帮助类去继承它。SQLiteOpenHelper有两个抽…

浅析SQL Server 2005中的主动式通知机制

一、引言 在开发多人同时访问的Web应用程序&#xff08;其实不只这类程序&#xff09;时&#xff0c;开发人员往往会在缓存策略的设计上狠下功夫。这是因为&#xff0c;如果将这种环境下不常变更的数据临时存放在应用程序服务器或是用户机器上的话&#xff0c;可以避免频繁地往…

Android 第十二课 使用LitePal操作数据库(记得阅读最后面的注意事项哦)

一、LitePal简介 1、(新建项目LitePalTest)正式接触第一个开源库---LitePalLitePal是一款开源的Android 数据库框架&#xff0c;它采用了对象关系映射&#xff08;ORM&#xff09;的模式。2、配置LitePal&#xff0c;编辑app/build.gradle文件&#xff0c;在dependencies闭包中…

listview频繁刷新报错

在Android编程中使用Adapter时&#xff0c;偶尔会出现如下错误&#xff1a;The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI t…

Android 第十三课 SharedPreferences存储

SharedPreferences是使用键值对的方式来存储数据的。当保存一条数据时&#xff0c;需要给这条数据提供一个对应的键&#xff0c;这样在读取数据的时候就可以通过这个键把相应的值取出来。而且支SharedPreferences还支持多种不同的数据类型存储&#xff0c;例如&#xff1a;如果…

DSP的Gel作用

转自&#xff1a;http://blog.csdn.net/azhgul/article/details/6660960最近刚在研究Davinci系&#xff0c;特此MARK下&#xff0c;以资后续学习之用。 DSP的Gel作用 1 GEL文件基本作用 当CCSStudio启动时&#xff0c;GEL文件加载到PC机的内存中&#xff0c;如果定义了StartUp(…

解决关于登录校园网显示不在IP段的问题方案(要看注意事项哦!)

有时&#xff0c;登录校园网&#xff0c;账号和密码都显示正确&#xff0c;但是却显示出“账号只能在指定IP段登录”的问题。 那我们就提供了一个解决方案&#xff1a; 使用WinR,并在输入框&#xff0c;输入cmd命令&#xff1a;&#xff08;如下&#xff09;接着输入&#xff1…

jquery插件编写

jQuery为开发插件提拱了两个方法&#xff0c;分别是&#xff1a; jQuery.fn.extend(object); jQuery.extend(object); jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。可以理解为添加静态方法。是全局的&#xff08;位于jQuery命名空间内部的函数&#xff09;…

gtk/Glade编程 编译命令不成功 解决方法

摘自&#xff1a;http://blog.chinaunix.net/uid-26746982-id-3433656.html 当我们编写gtk/glade程序&#xff0c;gcc编译时&#xff0c;用如下命令&#xff1a; #gcc -o server server.c pkg-config --cflags --libs gtk-2.0 报错&#xff1a;/tmp/ccoXadAd.o: In function …

Android 第十五课 如何使用LitePal从SQLite数据库中删除数据(十四课用来保留讲解如何向SQLite数据库中存入数据)

使用LitePal删除数据的方式主要有两种&#xff0c;第一种就是直接调用已存对象的delete()方法&#xff0c;所谓已存储对象就是调用过save()方法的对象&#xff0c;或者说是通过LitePal提供的查询API查出来的对象&#xff0c;都是可以直接使用delete方法来删除对象的。这是比较简…

页面返回顶部(方法比较)

下面就说下简单的返回顶部效果的代码实现&#xff0c;附注释说明。 1. 最简单的静态返回顶部&#xff0c;点击直接跳转页面顶部&#xff0c;常见于固定放置在页面底部返回顶部功能 方法一&#xff1a;用命名锚点击返回到顶部预设的id为top的元素 html代码 <a href"#top…

Android 第十六课 使用LitePal查询数据

LitePal在查询API方面做了非常多的优化&#xff0c;基本上可以满足绝大多数场景的查询需求&#xff0c;并且代码也十分整洁。 例如我们需要查询表中的所有数据&#xff1a; List<books> DataSupport.findAll(Book.class); 没有冗长的参数列表&#xff0c;只需要调用一下…

linux创建桌面图标,和开始菜单栏图标

转自&#xff1a;http://blog.csdn.net/qq_25773973/article/details/50514767 ###环境&#xff1a;Mint17&#xff0c;&#xff08;其他类似的linux系统是一样的&#xff09; 如果开始菜单有图标&#xff0c;创建桌面图标很简单&#xff0c;右键添加到桌面即可。 如果没有&am…

ScrollView中使用ListView

转自 http://blog.csdn.net/fzh0803/article/details/7971391 由于scrollview和listview不能直接共存&#xff0c;在scrollview中直接使用lsitview的话只会显示一个条目&#xff0c;要使他们共存&#xff0c; 据我所知&#xff0c;有三种方法&#xff1a; 1。如果listview的高度…

Android 第十四课 使用LitePal添加数据(更新数据)

我们注意到当你登录一个app&#xff0c;是不是需要先注册呢&#xff1f;&#xff0c;所谓注册&#xff0c;简单地来理解是不是就是把输入框中地数据传入数据库中呢&#xff1f; 这里我们设置简单一点&#xff0c;注册的信息只包括两项&#xff0c;一项是用户名&#xff0c;另一…

微信公众平台的服务号和订阅号

微信公众平台 服务号 订阅号 作者&#xff1a;方倍工作室 地址&#xff1a;http://www.cnblogs.com/txw1958/p/ServiceNumber-subscriptionNumber.html 什么是服务号&#xff1f; 服务号给企业和组织提供更强大的业务服务与用户管理能力&#xff0c;帮助企业快速实现全新的公众…