安卓开发中自定义View之onMeasure(),onLayout(),onDraw()讲解(二)

 自定义View之onLayout()(一)

 onLayout()方法,是ViewGroup放置子 View的布局方法,是View放置的位置,放置子View的时候只需重写onLayout方法,获取到子View的实例,调用它的方法layout进行布局,实际开发中,配合onMeasure使用,先测量子View的大小,再确定放在父容器的那个位置。

看看ViewGroup中,onLayout方法

@Override
protected abstract void onLayout(boolean changed,
            int l, int t, int r, int b);

View在父容器的放置,都是根据一个矩形区域来放置的,在看看这个方法,该方法定义为抽象方法,所以在继承该类的时候必须重写该抽象方法,里面的四个参数,int l,int t,int r,in b分别为放置父容器ViewGroup可用的矩形区域的左上角left、top和右下角right、bottom值,这个值刻印通过getLeft、getTop、getRight、getBottom方法获取。

再看看子View的layout方法

public void layout(int l, int t, int r, int b);
这个方法是子View的放置方法,在子View中实现,调用这个方法要传入四个放置子View的参数,分别为确定左上角的l和r值,还有确定右下角的r和b值,比如说layout(20,10,80,100),那么该子View占有空间区域的矩形区域相对父容器ViewGroup的位置是,左上角(20,10)处,右下角(80,100)处,该矩形区域的宽高分别为(单位为像素)80-20=60、100-10=90.

在自定义View中,onLayout配合onMeasure方法一起使用,可以实现自定义View的复杂布局。自定义View首先调用onMeasure进行测量,然后调用onLayout方法,动态获取子View和子View的测量大小,然后进行layout布局。

下面看一段项目中的实例

package com.suowei.appsuowei.myview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class StretchLinearLayout extends LinearLayout{
/**
*==========下拉可以拉升松开回弹的自定义LinearLayout容器==================
*在onTouchEvent中调用了该实例的layout进行动态布局
*/
	private int moveSum;
	private int move;
	private int yDown,yMove;
	private Boolean isIntercept=false;

	public StretchLinearLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO 自动生成的构造函数存根
	}

	public StretchLinearLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO 自动生成的构造函数存根
	}

	public StretchLinearLayout(Context context) {
		super(context);
		// TODO 自动生成的构造函数存根
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int y=(int) event.getY();//每次触摸的纵坐标位置赋值给y
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			yDown=y;//把down的纵坐标位置赋值给yDown
			break;

		case MotionEvent.ACTION_MOVE:

			yMove=y;//下来滑动的时候把滑动的当前纵坐标值赋值给yMove
			if(yMove-yDown>0){//判断如果滑动了
				move=yMove-yDown;//计算出这次滑动的距离
				moveSum+=move;//把滑动总的距离统计出来
				//调用该实例的layout进行动态布局,看到的实际效果就是跟随滑动,不断没拉升
				this.layout(getLeft(), getTop()+move, getRight(), getBottom()+move);
			}
			break;
		case MotionEvent.ACTION_UP:
			//当手指松开的时候,在调用layout进行布局,返回到原来的位置
			this.layout(getLeft(), getTop()-moveSum, getRight(), getBottom()-moveSum);
			moveSum=0;
			break;
		}
		//返回true,表示消费为这次触摸事件
		return true;
	}

}
上述实例就是调用layout方法进行动态布局,模拟下来拉升松开反弹的效果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值