android.view.View及android.view.ViewGroup
来源:互联网 发布:传奇霸业装备炼体数据 编辑:程序博客网 时间:2024/05/28 15:40
本文摸索了View的几个特性,measure、layout、draw及event处理,包括它们的功能、步骤及调用栈。
首先measure获得View的大小,即width和height;其次由layout获得View的位置,及left、top、right、bottom;最后由draw来绘制内容。
由event来处理触屏事件,如单击、双击、滑动等。
1、下面用一个自定义View来演示具体功能。
public class MyView extends View {private static final String TAG = MyView.class.getSimpleName();GestureDetector mGestureDetector;public MyView(Context context){this(context, null);}public MyView(final Context context, AttributeSet attrs) {super(context, attrs);Log.println(Log.DEBUG, TAG, "MyView");mGestureDetector = new GestureDetector(context, mSimpleOnGestureListener,null);}@Overrideprotected void onDraw(Canvas canvas) {Log.println(Log.DEBUG, TAG, "onDraw-"+getWidth()+"-"+getHeight());//do your drawing//ViewGroup.drawChild->View.draw->View.onDrawsuper.onDraw(canvas);canvas.drawColor(Color.RED);}@Overridepublic void draw(Canvas canvas) {Log.d(TAG, "draw");super.draw(canvas);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {//ViewGroup.onLayout->View.layout->View.onLayoutLog.println(Log.DEBUG, TAG, "onLayout-"+changed+"-"+left+"-"+top+"-"+right+"-"+bottom);}@Overridepublic void layout(int l, int t, int r, int b) {Log.d(TAG, "layout-"+l+"-"+t+"-"+r+"-"+b);super.layout(l, t, r, b);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//ViewGroup.onMeasure->View.measure->View.onMeasureint widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);Log.println(Log.DEBUG, TAG, "onMeasure-"+widthMode+"-"+heightMode+"-"+widthSize+"-"+heightSize);//在这里设置自定义视图的大小setMeasuredDimension(widthSize/2, widthSize/2+100);}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {//接受并在这里处理触摸事件//MyView->MyLinearLayout->MyScrollView->MainActivityLog.println(Log.DEBUG, TAG, "onTouchEvent");//return super.onTouchEvent(event);return mGestureDetector.onTouchEvent(event);}//implements OnGestureListener, OnDoubleTapListenerprivate SimpleOnGestureListener mSimpleOnGestureListener = new GestureDetector.SimpleOnGestureListener(){public boolean onDown(MotionEvent e) {Log.d(TAG, "onDown-"+e.getX()+"-"+e.getY()+"-"+e.hashCode());//起点return true;};public boolean onDoubleTap(MotionEvent e) {Log.d(TAG, "onDoubleTap-"+e.getX()+"-"+e.getY()+"-"+e.hashCode());return true;};public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {Log.d(TAG, "onFling-"+e1.getX()+"-"+e1.getY()+"-"+e1.hashCode());return true;};public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {Log.d(TAG, "onScroll-"+e1.getX()+"-"+e1.getY()+"-"+e1.hashCode());return true;};public boolean onSingleTapConfirmed(MotionEvent e) {Log.d(TAG, "onSingleTapConfirmed-"+e.getX()+"-"+e.getY()+"-"+e.hashCode());return true;};public boolean onDoubleTapEvent(MotionEvent e) {Log.d(TAG, "onDoubleTapEvent-"+e.getX()+"-"+e.getY()+"-"+e.hashCode());return true;};public boolean onSingleTapUp(MotionEvent e) {Log.d(TAG, "onSingleTapUp-"+e.getX()+"-"+e.getY()+"-"+e.hashCode());return true;};};}
public class MyLinearLayout extends LinearLayout {private static final String TAG = MyLinearLayout.class.getSimpleName();public MyLinearLayout(Context context){this(context, null);}public MyLinearLayout(Context context, AttributeSet attrs) {super(context, attrs);Log.d(TAG, "MyLinearLayout");}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {Log.d(TAG, "onMeasure");super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {Log.d(TAG, "onLayout-"+changed+"-"+l+"-"+t+"-"+r+"-"+b);View view = getChildAt(0);Log.d(TAG, view.getWidth()+"|"+view.getHeight()+"|"+view.getMeasuredWidth()+"|"+view.getMeasuredHeight());view.layout(100, 100, view.getMeasuredWidth()+100, view.getMeasuredHeight()+100);}@Overrideprotected void onDraw(Canvas canvas) {Log.d(TAG, "onDraw");super.onDraw(canvas);}@Overridepublic void draw(Canvas canvas) {Log.d(TAG, "draw");super.draw(canvas);}@Overrideprotected boolean drawChild(Canvas canvas, View child, long drawingTime) {Log.d(TAG, "drawChild");return super.drawChild(canvas, child, drawingTime);}@Overrideprotected void dispatchDraw(Canvas canvas) {Log.d(TAG, "dispatchDraw");super.dispatchDraw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.d(TAG, "onTouchEvent");//View.onTouchEventreturn super.onTouchEvent(event);}}
public class MyScrollView extends ScrollView {private static final String TAG = MyScrollView.class.getSimpleName();public MyScrollView(Context context){this(context, null);}public MyScrollView(Context context, AttributeSet attrs) {super(context, attrs);Log.d(TAG, "MyScrollView");}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {Log.d(TAG, "onMeasure");super.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {Log.d(TAG, "onLayout-"+changed+"-"+l+"-"+t+"-"+r+"-"+b);super.onLayout(changed, l, t, r, b);}@Overrideprotected void onDraw(Canvas canvas) {//draw->onDraw->dispatchDraw->drawChildLog.d(TAG, "onDraw");super.onDraw(canvas);}@Overridepublic void draw(Canvas canvas) {Log.d(TAG, "draw");super.draw(canvas);}@Overrideprotected boolean drawChild(Canvas canvas, View child, long drawingTime) {Log.d(TAG, "drawChild");return super.drawChild(canvas, child, drawingTime);}@Overrideprotected void dispatchDraw(Canvas canvas) {Log.d(TAG, "dispatchDraw");super.dispatchDraw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.d(TAG, "onTouchEvent");//ScrollView.onTouchEventreturn super.onTouchEvent(event);}}
public class MainActivity extends Activity {private static final String TAG = MainActivity.class.getSimpleName();@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.println(Log.DEBUG, TAG, "onCreate");super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Log.d(TAG, "onTouchEvent");return super.onTouchEvent(event);}}
<?xml version="1.0" encoding="utf-8"?><com.qinuli.customviewtest.MyScrollView android:layout_width="match_parent" android:layout_height="300dp" xmlns:android="http://schemas.android.com/apk/res/android" android:background="#00ff00"> <com.qinuli.customviewtest.MyLinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="#0000ff"> <com.qinuli.customviewtest.MyView android:id="@+id/myView" android:layout_width="match_parent" android:layout_height="wrap_content"/></com.qinuli.customviewtest.MyLinearLayout></com.qinuli.customviewtest.MyScrollView>
2、分析
onTouchEvent的触发顺序为MyView->MyLinearLayout->MyScrollLayout->MainActivity
1)写一个扩展SimpleOnGestureListener的类。SimpleOnGestureListener是OnGestureListener, OnDoubleTapListener两个接口的缺省适配,GestureDetector的嵌套类。OnGestureListener, OnDoubleTapListener是GestureDetector的嵌套接口。
2)通过GestureDetector构造传参封装SimpleOnGestureListener,即new GestureDetector(Context,OnGestureListener)
3)在View.onTouchEvent方法调用实现触摸事件捕捉,即return mGestureDetector.onTouchEvent(event)
3、View自定义属性
1)在res/values/attrs.xml文件resources标签下添加子标签,format类型可以是string、integer、boolean等
<declare-styleable name="trendchart"> <attr name="showPrompt" format="boolean"/></declare-styleable>2)在使用该属性的xml文件设置值
3)在自定义View类中取值
private void init(AttributeSet attrs){TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.trendchart);showPrompt = ta.getBoolean(R.styleable.trendchart_showPrompt, false);ta.recycle();}
4、实现视图缩放
mScaleGestureDetector = new ScaleGestureDetector(this, mScaleGestureListener);//注册
@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//先Log.d(TAG, "dispatchTouchEvent-"+ev.getAction());return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent event) {//后Log.d(TAG, "onTouchEvent-"+event.getAction());if(mScaleGestureDetector!=null){mScaleGestureDetector.onTouchEvent(event);}return super.onTouchEvent(event);}SimpleOnScaleGestureListener mScaleGestureListener = new SimpleOnScaleGestureListener(){@Overridepublic boolean onScale(ScaleGestureDetector detector) {Log.d(TAG, detector.getCurrentSpan()+"/"+detector.getPreviousSpan());return super.onScale(detector);}public boolean onScaleBegin(ScaleGestureDetector detector) {return super.onScaleBegin(detector);};public void onScaleEnd(ScaleGestureDetector detector) {};};
- android.view.View及android.view.ViewGroup
- Android界面View及ViewGroup
- Android界面View及ViewGroup
- Android界面View及ViewGroup
- Android界面View及ViewGroup
- Android界面View及ViewGroup
- Android界面View及ViewGroup
- Android界面View及ViewGroup
- Android View、ViewGroup
- Android 之 View ViewGroup
- android view viewGroup 解析
- android自定义View(viewGroup)
- android view 以及 viewGroup
- Android View.ViewGroup.LayoutParams
- Android View和ViewGroup
- Android View和ViewGroup
- 【Android】View和ViewGroup
- android自定义View、ViewGroup
- 设计模式 ( 十四 ) 迭代器模式Iterator(对象行为型)
- 2014.12.28数据插入sql数据库1.0完整版
- C语言编程(练习2:循环,三大循环结构 )
- Android多点触控缩放拖拽实例
- Kubuntu kde 好用的 快捷键
- android.view.View及android.view.ViewGroup
- 关于在Eclipse中配置Tomcat
- java之httpclient的一些破事
- Karena barang-bara
- 俞敏洪:用“4B”精神,做“5B”的事情
- linux下的ln命令
- Android内存演示
- [leetcode]Unique Binary Search Trees II
- hdu3001