Android 让他们自己控制开发的定义(一个)
作为一个创意开发。或软件UI设计要求比较高,你经常会遇到的情况来圣安德鲁斯控制不符合您的需求。这样的时候。件。同一时候。安卓也同意你去继承已经存在的控件或者实现你自己的控件以便优化界面和创造更加丰富的用户体验。
那么如何来创建一个新的控件呢?
这得看需求是如何的了。
1.须要在原生控件的基本功能上进行扩展,这个时候你仅仅须要继承并对控件进行扩展。
通过重写它的事件,onDraw ,可是始终都保持都父类方法的调用。
如从已有的高级控件上继承。比如继承一个TextView。
2.须要几个控件的功能的加和,这个时候要把控件组合起来,就是通过合并几个控件来生成一个新控件。比方在ListView中用适配器来将多种控件有机的结合在一起,又如写一个控件是多个控件的组合,通常是自己定义布局,能够用一个类继承一个布局。这个布局中包括多个控件。
3.白手起家自己创建一个新的控件。
即直接从View,ViewGroup開始绘制控件
4.另外大家不要忘了。另一个好用的东西<include>标签。 在一个项目中我们可能会须要用到同样的布局设计。假设都写在一个xml文件里。代码显得非常冗余,而且可读性也非常差。所以我们能够把同样布局的代码单独写成一个模块。然后用到的时候能够通过<include
/> 标签来重用layout代码。
作过Android 应用开发的朋友都知道,Android的UI界面都是由View和ViewGroup及其派生类组合而成的。基于安卓UI设计原理,我们作为开发人员。全然可以依照自己的意愿开发出项目定制的组件。当中,View是全部UI组件的基类。而ViewGroup是容纳这些组件的容器,其本身也是从View派生出来的。AndroidUI界面的一般结构可參见以下的示意图:

可见,作为容器的ViewGroup能够包括作为叶子节点的View,也能够包括作为更低层次的子ViewGroup,而子ViewGroup又能够包括下一层的叶子节点的View和ViewGroup。其实,这样的灵活的View层次结构能够形成很复杂的UI布局,开发人员可据此设计、开发很精致的UI界面。
ViewGroup能够通过重写onMeasure,onLayout为增加当中的View进行布局和处理,功能十分强大,我们这次先学习View类派生自己定义组件:
View组件的作用类似于JAVA中Swing里的Panel。是一个矩形的空白区域,不带有不论什么内容,对于Android应用的其它UI控件来说。都是继承了View组件,然后绘制出来的。所以我们通过View子类并重写View类的方法来派生我们自己的控件。
Android自己定义View实现非常easy:
继承View。重写构造函数、onDraw,(onMeasure)等函数。以下会逐一列举。
假设自己定义的View须要有自己定义的属性,须要在values下建立attrs.xml。在当中定义你的属性。在使用到自己定义View的xml布局文件里须要增加xmlns:前缀="http://schemas.android.com/apk/res/你的自己定义View所在的包路径".在使用自己定义属性的时候。使用前缀:属性名,如my:textColor="……"。
让我们先看一下View类的方法:
|
Category |
Methods |
Description |
|
Creation |
Constructors |
There is a form of the constructor that are called when the view is created from code and a form that is called when the view is inflated from a layout file. The second form should parse and apply any attributes defined in the |
|
Called after a view and all of its children has been inflated from XML. |
||
|
Layout |
Called to determine the size requirements for this view and all of its children. |
|
|
Called when this view should assign a size and position to all of its children. |
||
|
Called when the size of this view has changed. |
||
|
Drawing |
Called when the view should render its content. |
|
|
Event processing |
Called when a new hardware key event occurs. |
|
|
Called when a hardware key up event occurs. |
||
|
Called when a trackball motion event occurs. |
||
|
Called when a touch screen motion event occurs. |
||
|
Focus |
Called when the view gains or loses focus. |
|
|
Called when the window containing the view gains or loses focus. |
||
|
Attaching |
Called when the view is attached to a window. |
|
|
Called when the view is detached from its window. |
||
|
Called when the visibility of the window containing the view has changed. |
通常可能须要重写下面方法:
1.构造器,至少用来获取Context
2.onFinishlnflate()这是一个回调方法, 当应用从 XML 布局文件载入该组件并利用
它来构建界面之后, 该方法就会被回调。
3.onMeasure(int,int):调用该方法来检測View组件及它所包括的全部子组件的大小.
4.onlayout(boolean,int,int,int,int):当该组件须要分配其子组件的位置、大小时。
该方法就会被回调. View类中布局发生改变时会调用的方法,这种方法是全部View、ViewGroup及其派生类都具有的方法,重载该类能够在布局发生改变时作定制处理,这在实现一些特效时很实用。
5.onSizeChanged(int,int, int, int):当该组件的大小被改变时回调该方法.
6.onDraw(canves): 当该组件将要绘制它的内容时回调该方法迸行绘制. View类中用于重绘的方法,这种方法是全部View、ViewGroup及其派生类都具有的方法,也是Android UI绘制最重要的方法。
开发人员可重载该方法,并在重载的方法内部基于參数canvas绘制自己的各种图形、图像效果。
7.onKeyDown(int,KeyEvent): 当某个键被按下时触发该方法.
8.onKayUp(int,KeyEvent), 当松开某个键时触发该方法.
9.onTrackballEvent (MotionEvent): 当发生轨迹球事件时触发该方法.
10.onTouchEvent (MotionEvent): 当发生触摸屏事件时触发该方法.
11.onWindowFocuschanged(boolean): 当该组件得到、失去焦点时触发该方法.
12.onAttachedToWindow():当把该组件放入某个窗体时触发该方法.
13.onDetachedFromWindow(): 当把该组件从某个窗体上分离时触发该方法.
14.onWindowVisibilityChanged(int):当包括该组件的窗体的可见性发生改变时触发该
方法.
另外再补充两个ViewGroup类常常重载的方法:
1.protected void dispatchDraw(Canvas canvas):ViewGroup类及其派生类具有的方法,这种方法主要用于控制子View的绘制分发,重载该方法可改变子View的绘制,进而实现一些复杂的视效。
2.protected boolean drawChild(Canvas canvas, View child, long drawingTime)):ViewGroup类及其派生类具有的方法,这种方法直接控制绘制某局详细的子view,重载该方法可控制详细某个详细子View。
在须要开发自己定义View的时候。我们不须要列举出上面全部的方法,,而是能够依据业务须要来有选择的使用·上面的方法,以下我们看一个简单的演示样例程序,在这个演示样例程序里面我们仅仅须要重写onDraw方法就能够了。
演示样例程序一:
我们要写一个尾随手指移动的小球,思路非常easy。仅仅要获取到用户点击屏幕的位置,而且在该位置处重绘小球就可以:
以下我们看一下程序:
我凝视写的比較清楚。我就说的简略一点:
首先我们写一个类DrawView,也就是我们自己定义的控件。继承自View
然后我们先写出构造器。获取到Context,这里假设用仅仅含有Context的构造器会在xml里调用控件的时候出错,详情请看我的另外一篇博文:
http://blog.csdn.net/sunmc1204953974/article/details/38101057
以下我们開始写:
// 构造方法
public DrawView(Context context,AttributeSet attrs){
super(context,attrs);
}
// 重写ondraw方法
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
// 创建画笔
Paint paint = new Paint();
// 设置画笔颜色
paint.setColor(Color.RED);
// 画出小球
canvas.drawCircle(circleX, circleY, circleR, paint);
}
然后不要忘了设置这些数据的setter和getter,由于我们须要再使用这个View的时候加上监听才干够:
// get set 方法
public float getCircleX() {
return circleX;
}
public void setCircleX(float circleX) {
this.circleX = circleX;
}
public float getCircleY() {
return circleY;
}
public void setCircleY(float circleY) {
this.circleY = circleY;
}
public float getCircleR() {
return circleR;
}
public void setCircleR(float circleR) {
this.circleR = circleR;
}
这样我们的一个简单地自定控件就大功告成了。以下是该类的完整代码:
package com.example.moveball; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View; public class DrawView extends View{ private float circleX = 40;
private float circleY = 50;
private float circleR = 15; // 构造方法
public DrawView(Context context,AttributeSet attrs){
super(context,attrs);
} // 重写ondraw方法
@Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
// 创建画笔
Paint paint = new Paint();
// 设置画笔颜色
paint.setColor(Color.RED);
// 画出小球
canvas.drawCircle(circleX, circleY, circleR, paint);
}
// get set 方法 public float getCircleX() {
return circleX;
} public void setCircleX(float circleX) {
this.circleX = circleX;
} public float getCircleY() {
return circleY;
} public void setCircleY(float circleY) {
this.circleY = circleY;
} public float getCircleR() {
return circleR;
} public void setCircleR(float circleR) {
this.circleR = circleR;
} }
之后我们就是像平时使用安卓原生控件那样使用就能够了,我们看一下Activity的代码:
package com.example.moveball; import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener; public class MainActivity extends Activity {
// 定义DrawView组件
DrawView drawView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建DrawView组件
drawView = (DrawView)this.findViewById(R.id.drawView);
// 为DrawView组件绑定Touch事件
drawView.setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View arg0, MotionEvent event) {
// 获取坐标并改变小球的坐标
drawView.setCircleX(event.getX());
drawView.setCircleY(event.getY());
// 通知draw组件重绘
drawView.invalidate();
// 返回true表明被运行
return true;
}
}); } }
以及xml格式的布局文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" > <com.example.moveball.DrawView
android:id="@+id/drawView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</com.example.moveball.DrawView> </RelativeLayout>
这样一个简单的样例就呈如今大家面前了。不管是多么复杂的自己定义控件,思路总是这样子的。大家是不是认为怪怪的。对了,作为一个控件,我们竟然还要为了他的实现为其添加麻烦的监听。这就是由于我们重写的方法太少的原因,下一讲再给大家介绍一个常常重写的方法:publicboolean onTouchEvent (MotionEvent event)。
源码上面已经非常具体了。我在最后一篇的最后还会发一个project上来。欢迎大家一起学习!
我也还是学生,写的不好或者有问题的地方还请多多不吝赐教~
版权声明:本文博客原创文章。博客,未经同意,不得转载。
Android 让他们自己控制开发的定义(一个)的更多相关文章
- android软件简约记账app开发day03-自定义键盘的书写
android软件简约记账app开发day03-自定义键盘的书写 我们在fragment界面使用了自定义的keybroad键盘,所以今天我们来书写自定义的键盘代码 新建util包,新建keyboard ...
- ODOO里视图开发案例---定义一个像tree、form一样的视图
odoo里视图模型MVC模式: 例子:在原来的视图上修改他: var CustomRenderer = KanbanRenderer.extend({ ....});var CustomRendere ...
- android开发——自己定义相机(Camera)开发总结
近期这段时间我一直在开发自己定义相机.谷歌了些网上的demo.发现有非常多各种各样的问题.终于还是从API的camera类開始学习,进行改进. 以下对之前的实现进行一些总结. 官方camera API ...
- 【转载】Android Metro风格的Launcher开发系列第二篇
前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客Android Metro风格的Launcher开发系列第一篇写了如 ...
- 深入浅出 - Android系统移植与平台开发(六)- 为Android启动加速
作者:唐老师,华清远见嵌入式学院讲师. Android的启动速度一直以来是他的诟病,虽然现在Android设备的硬件速度越来越快,但是随着新 版本的出现,其启动速度一直都比较慢,当然,作为程序员,我们 ...
- Android Metro风格的Launcher开发系列第三篇
前言: 各位小伙伴,又到了每周更新文章了时候了,本来是周日能发出来呢,这不是赶上清明节吗,女王大人发话了,清明节前两天半陪她玩,只留给我周一下午半天时间写博客,哪里有女王哪里就有压迫呀有木有!好了闲话 ...
- Android Wear之android穿戴式设备应用开发平台
Android Wear于2014年03月19日公布,并有Moto 360和LG watch两款产品. 眼下源代码还没有开放.可是开发人员能够下载它的Image及相应的开发SDK,这样开发人员通过模拟 ...
- Android N 新特性 + APP开发注意事项
1. 多窗口MultiWindow 多窗口MultiWindow,这是Android N里对开发者影响比较大的特性,也是大家疑问比较多的地方.站在开发者的角度其实不必太担心这个特性会导致我们需要修改很 ...
- 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一
作者:唐老师,华清远见嵌入式学院讲师. 1. Sensor的概念 Sensor即传感器,在当前智能手机上大量存在:G-Sensor.LightsSensor. ProximitySensor.Temp ...
随机推荐
- C#获取设备的IP和Mac类
/// <summary> /// 此类用于获得设备的Ip和Mac /// </summary> public class Mac { [DllImport("Iph ...
- Android SDK 5.0 这个语句带来折腾 - 生命在于折腾!
Android SDK 5.0 带来的这番折腾 - 生命在于折腾! 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一 ...
- Visual Studio跨平台开发实战(1) - Hello Xamarin!
原文 Visual Studio跨平台开发实战(1) - Hello Xamarin! 前言 应用程式发展的脚步, 从来没有停过. 从早期的Windows 应用程式, 到网路时代的web 应用程式, ...
- WPF对于xml的简单操作(上)
private void button1_Click(object sender, RoutedEventArgs e) { XmlTextWriter writer = new XmlTextWri ...
- mysql copy复制拷贝表数据及结构的几种方式(转)
mysql拷贝表操作我们会常常用到,下面就为您详细介绍几种mysql拷贝表的方式,希望对您学习mysql拷贝表方面能够有所帮助.假如我们有以下这样一个表:id username password--- ...
- POJ 3450 Corporate Identity KMP解决问题的方法
这个问题,需要一组字符串求最长公共子,其实灵活运用KMP高速寻求最长前缀. 请注意,意大利愿父亲:按照输出词典的顺序的规定. 另外要提醒的是:它也被用来KMP为了解决这个问题,但是很多人认为KMP使用 ...
- Embedding Lua, in Scala, using Java(转)
LuaJ I was reading over the list of features that CurioDB lacks compared to Redis , that I’d previou ...
- 采用PopupWin控制消息推送功能
最近的项目需要,急需实现消息推送功能.接连试了很多办法,让我们用JavaScript为了实现啊,其效果是不咋好,最后,我发现了一个PopupWin这个,看着眼前的成绩不错,开始使用. 1.准备工作.先 ...
- Android SwipeRefreshLayout 官方下拉刷新控件介绍
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24521483 下面App基本都有下拉刷新的功能,以前基本都使用XListView ...
- poj 1962 Corporative Network
主题链接:http://poj.org/problem?id=1962 思路:每一个集合中用根节点标记这个集合,每一个点到根节点的距离. code: <span style="font ...