【Android 应用开发】自定义View 和 ViewGroup

一. 自定义View介绍

 

自定义View时, 继承View基类, 并实现其中的一些方法.

 

(1) ~ (2) 方法与构造相关

(3) ~ (5) 方法与组件大小位置相关

(6) ~ (9) 方法与触摸按键相关

(10) ~ (12) 方法与窗口 焦点相关

 

(1) 构造方法

该构造方法在创建View实例, 或者从XML布局中加载并构建界面的时候调用.

 

(2)加载回调方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onFinishInflate()  

回调方法, 从XML布局中加载该重写的View组件的时候, 就会回调这个方法;

 

 

(3)测量方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  

这个方法用来检测View组件以及该View组件包含的子组件的大小

 

 

(4)定位组件方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onLayout(boolean changed, int left, int top, int right,int bottom)  

被重写的View组件分配在其中的子组件的位置 和 大小的时候, 回调这个方法;

 

 

(5)大小改变方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onSizeChanged(int w, int h, int oldw, int oldh)  

当组件大小被改变的时候回调该方法;

 

 

(6)按键方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public boolean onKeyDown(int keyCode, KeyEvent event)  

当某个键被按下时触发该方法;

 

 

(7)松开键方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public boolean onKeyUp(int keyCode, KeyEvent event)  

当某个键松开的时候调用该方法;

 

 

(8)轨迹球事件方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public boolean onTrackballEvent(MotionEvent event)  

发生轨迹球事件时触发该方法;

 

 

(9)触摸方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public boolean onTouchEvent(MotionEvent event)  

当发生触摸时间时触发该方法;

 

 

(10)焦点改变方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public void onWindowFocusChanged(boolean hasWindowFocus)  

当组件得到, 失去焦点的时候回调的方法;

 

 

(11)组件进入窗口方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onAttachedToWindow()  

当把组件放入窗口的时候, 回调这个方法

 

 

(12)组件分离窗口方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onAttachedToWindow()  

当把组件从某个窗口分离触发的方法

 

 

(13)窗口可见性改变方法

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onWindowVisibilityChanged(int visibility)  

当包含该组件的窗口发生改变的时候触发的方法

 

二. 实现一个跟随手指的小球View

 

1. 自定义View

 

自定义一个View组件铺满全屏, 在绘制该View组件的时候, 在onDraw()方法中根据一个xy坐标绘制一个小球;

这个xy坐标在触摸回调方法onTouchEvent()方法中动态改变, 当检测到触摸位置发生改变, 那么就重新给xy坐标赋值, 并且调用invalidate()方法重绘该组件, invalidate()方法执行后, 会回调onDraw()方法;

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class FollowBallView extends View {  
  2.   
  3.     public float currentX = 40;  
  4.     public float currentY = 50;  
  5.       
  6.     Paint paint = new Paint();  
  7.       
  8.     public FollowBallView(Context context) {  
  9.         super(context);  
  10.           
  11.     }  
  12.       
  13.     public FollowBallView(Context context, AttributeSet set) {  
  14.         super(context, set);  
  15.     }  
  16.       
  17.     @Override  
  18.     protected void onDraw(Canvas canvas) {  
  19.         super.onDraw(canvas);  
  20.         paint.setColor(Color.RED);  
  21.         canvas.drawCircle(currentX, currentY, 15, paint);  
  22.     }  
  23.       
  24.     @Override  
  25.     public boolean onTouchEvent(MotionEvent event) {  
  26.         currentX = event.getX();  
  27.         currentY = event.getY();  
  28.         //重绘  
  29.         invalidate();  
  30.         return true;  
  31.     }  
  32. }  



 

2. xml文件

 

在这个xml文件中, 引入自定义的布局, 使用完整的类名包名可以引入该自定义View组件;

引入组件后, 充满整个布局;

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent" >  
  5.   
  6.     <shuliang.han.followball.FollowBallView  
  7.         android:layout_width="match_parent"  
  8.         android:layout_height="match_parent"/>  
  9.   
  10. </RelativeLayout>  

 

 

3. Activity中显示该组件

 

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class MainActivity extends Activity {  
  2.   
  3.     @Override  
  4.     public void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.     }  
  8. }  

 

 

4. 效果图

 

 

三. ViewGroup简介

 

 

1.View和ViewGroup关系

 

UI组件在Android中的位置 : Android中的UI组件大部分都放在android.widget 或者 android.view包中;  View组件 和 ViewGroup组件都在android.view包中;

 

View 和 ViewGroup关系 : 

继承关系 : ViewGroup是View的子类, 因此ViewGroup有View的一切属性, 可以当做View来使用, ViewGroup主要是当做容器使用; View是小控件widget和容器组件ViewGroup的父类, ViewGroup是布局如LinearLayout的基类;

包含关系 : ViewGroup中可以包含View和ViewGroup, ViewGroup可以无限嵌套;

 

View和ViewGroup关系图解 : 

 

抽象类 : ViewGroup是一个抽象类, 作为容器的类通常是ViewGroup的子类; ViewGroup子类对象有 : LinearLayout, FrameLayout等布局;

 

2. ViewGroup中的内部类

 

两个内部类 : 

ViewGroup通过Viewgroup.LayoutParams和ViewGroup.MarginLayoutParams来控制容器中的组件;

ViewGroup.LayoutParams支持的XML属性 : 

android:layout_height属性(指定布局高度) 和 android:layout_width属性(指定布局宽度), 这两个属性的值可以为 fill_parent, match_parent, wrap_content, 其中充满布局空间推荐使用match_parent;

 

组件的宽高 与 布局的宽高 : Android的组件的高度和宽度不是其实际的宽度和高度, 组件实际的高度和宽度同样受布局的宽高影响, 例如设置组件的宽度为100px, 如果设置布局宽度(layout_width)为match_parent, 那么组件的实际宽度就会被拉宽到整个布局, 如果设置布局的宽度为wrap_content, 那么组件的实际宽度就是100px;

 

ViewGroup.MarginLayoutParams支持的XML属性 : 

android:layout_marginBottom : 指定该子组件到父容器下边界的距离, 同理android:layout_marginTop, android:layout_marginLeft, android:layout_marginRight, 

 

3. View介绍

 

View可以有两种方式创建 : 一种是靠XML文件创建, 一种是靠代码创建;

 

这里只是简单的介绍下, View详细的属性会单独有一篇博客进行总结;

 

View创建关注的方面 : 

(1)设置属性

长宽等属性可以在XML中设置, 也可以在代码中设置; 

 

(2)请求焦点

可以通过函数实现焦点转变, 可以根据不同的焦点设置背景; 

焦点类别 : 可获取的焦点, 不可获取的焦点, 可以获取但是正在触摸状态下的焦点;

 

(3)设置事件监听

View在本身发生变化的时候, 会将信息广播出去, 这边变化例如 : 点击, 焦点改变等;

一个事件的广播到来, 该事件就会传递到相应的View中对应的监听器里, 相当于回调View中的监听器方法;

 

(4)设置显示与隐藏

View可以在XML或者代码中设置是否显示或者隐藏. 同样也可以设置滚动条等设置;

posted @ 2017-04-21 13:41  天涯海角路  阅读(117)  评论(0)    收藏  举报