作为一个创意开发。或软件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
layout file.

onFinishInflate()

Called after a view and all of its children has been inflated from XML.

Layout

onMeasure(int, int)

Called to determine the size requirements for this view and all of its children.

onLayout(boolean, int, int, int, int)

Called when this view should assign a size and position to all of its children.

onSizeChanged(int, int, int, int)

Called when the size of this view has changed.

Drawing

onDraw(android.graphics.Canvas)

Called when the view should render its content.

Event processing

onKeyDown(int, KeyEvent)

Called when a new hardware key event occurs.

onKeyUp(int, KeyEvent)

Called when a hardware key up event occurs.

onTrackballEvent(MotionEvent)

Called when a trackball motion event occurs.

onTouchEvent(MotionEvent)

Called when a touch screen motion event occurs.

Focus

onFocusChanged(boolean, int, android.graphics.Rect)

Called when the view gains or loses focus.

onWindowFocusChanged(boolean)

Called when the window containing the view gains or loses focus.

Attaching

onAttachedToWindow()

Called when the view is attached to a window.

onDetachedFromWindow()

Called when the view is detached from its window.

onWindowVisibilityChanged(int)

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 让他们自己控制开发的定义(一个)的更多相关文章

  1. android软件简约记账app开发day03-自定义键盘的书写

    android软件简约记账app开发day03-自定义键盘的书写 我们在fragment界面使用了自定义的keybroad键盘,所以今天我们来书写自定义的键盘代码 新建util包,新建keyboard ...

  2. ODOO里视图开发案例---定义一个像tree、form一样的视图

    odoo里视图模型MVC模式: 例子:在原来的视图上修改他: var CustomRenderer = KanbanRenderer.extend({ ....});var CustomRendere ...

  3. android开发——自己定义相机(Camera)开发总结

    近期这段时间我一直在开发自己定义相机.谷歌了些网上的demo.发现有非常多各种各样的问题.终于还是从API的camera类開始学习,进行改进. 以下对之前的实现进行一些总结. 官方camera API ...

  4. 【转载】Android Metro风格的Launcher开发系列第二篇

    前言: 各位小伙伴们请原谅我隔了这么久才开始写这一系列的第二篇博客,没办法忙新产品发布,好了废话不说了,先回顾一下:在我的上一篇博客Android Metro风格的Launcher开发系列第一篇写了如 ...

  5. 深入浅出 - Android系统移植与平台开发(六)- 为Android启动加速

    作者:唐老师,华清远见嵌入式学院讲师. Android的启动速度一直以来是他的诟病,虽然现在Android设备的硬件速度越来越快,但是随着新 版本的出现,其启动速度一直都比较慢,当然,作为程序员,我们 ...

  6. Android Metro风格的Launcher开发系列第三篇

    前言: 各位小伙伴,又到了每周更新文章了时候了,本来是周日能发出来呢,这不是赶上清明节吗,女王大人发话了,清明节前两天半陪她玩,只留给我周一下午半天时间写博客,哪里有女王哪里就有压迫呀有木有!好了闲话 ...

  7. Android Wear之android穿戴式设备应用开发平台

    Android Wear于2014年03月19日公布,并有Moto 360和LG watch两款产品. 眼下源代码还没有开放.可是开发人员能够下载它的Image及相应的开发SDK,这样开发人员通过模拟 ...

  8. Android N 新特性 + APP开发注意事项

    1. 多窗口MultiWindow 多窗口MultiWindow,这是Android N里对开发者影响比较大的特性,也是大家疑问比较多的地方.站在开发者的角度其实不必太担心这个特性会导致我们需要修改很 ...

  9. 深入浅出 - Android系统移植与平台开发(十一) - Sensor HAL框架分析之一

    作者:唐老师,华清远见嵌入式学院讲师. 1. Sensor的概念 Sensor即传感器,在当前智能手机上大量存在:G-Sensor.LightsSensor. ProximitySensor.Temp ...

随机推荐

  1. Java设计模式之认识阶段

    设计模式是什么? 设计模式(Design pattern)是一套被重复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 其本质就是继承与接口的组合应用. 为什么要用设计模? 使用设计模式是为了 ...

  2. windows phone (23) ScrollViewer元素

    原文:windows phone (23) ScrollViewer元素 ScrollViewer类表示可包含其他可见元素的可滚动区域,一般会用在屏幕的宽度和高度不够用时,作为一种延伸使用,参考书上称 ...

  3. Linux shell用法和技巧(转)

    使用Linux shell是我每天的基本工作,但我经常会忘记一些有用的shell命令和l技巧.当然,命令我能记住,但我不敢说能记得如何用它执行某个特定任务.于是,我开始在一个文本文件里记录这些用法,并 ...

  4. Eclipse+Maven创建webapp项目<一> (转)

    Eclipse+Maven创建webapp项目<一> 1.开启eclipse,右键new——>other,如下图找到maven project 2.选择maven project,显 ...

  5. 【夸QT在十五】ctkPluginFrameWork插件系统Windows编译器

    采用ctkPluginFramework作为一个插件系统开发框架确实有很多优点. 有些车站最近收到的一封信,每个人都想用ctkPluginFramework但我不知道如何建立,本教程对谈ctkPlug ...

  6. bin home

    bin=$(cd `dirname $0`;pwd)home=$(dirname $bin)

  7. Oracle 六闪回技术,flashback

    Flashback 技术基于Undo segment基于内容的, 因此,限制UNDO_RETENTON参数. 要使用flashback 特征,您必须启用自己主动撤销管理表空间. 在Oracle 11g ...

  8. table插入标签form标记怪现象

    最近帮朋友处理问题,它无法提交表单,得到一些时间,我发现了一个奇怪的问题 <table> <form action="upload.php" method=&qu ...

  9. webstorm创建nodejs + express + jade 的web 项目

    webstorm创建nodejs + express + jade 的web 项目 前简单了解过nodejs,觉得用nodejs来做个网站也太麻烦了,要自己拼html的字符串返回,这能做网站嘛? 最近 ...

  10. 【Android进阶】ZXing android 错误(Could not find class 'com.google.zxing.ResultPoint)

    解决方法: 1.右键工程Build path, java build path,选择libraries 在右边的按钮中点击"Add Library" 选择"User li ...