android自定义View学习二

1.设置padding
Margin属性不需要定义,padding属性需要自己在onDraw()方法里面把padding考虑进去
直接设置padding是没有效果的,如图,设置了Top和Left的padding。
在这里插入图片描述
需要在你的onDraw()方法里面设置padding

@Override
    protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);
        int paddingLeft = getPaddingLeft();
        int paddingRight = getPaddingRight();
        int paddingTop = getPaddingTop();
        int paddingBottom = getPaddingBottom();
        int width=getWidth()-paddingLeft-paddingRight;
        int height=getHeight()-paddingTop-paddingBottom;
        canvas.drawCircle(width/2+paddingLeft,height/2+paddingTop,width/2,paint);
    }

我这也不对,只是有效果了,先不管了。
在这里插入图片描述
2.View的滑动
通过重写onTouchEvent()方法,然后用 layout()方法来移动。

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x= (int) event.getX();
        int y= (int) event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:  //记录最开始的位置
                lastX=x;
                lastY=y;
                break;
                case  MotionEvent.ACTION_MOVE:  //算出偏移量,然后再用layout移动view
                    int offestX=x-lastX;
                    int offestY=y-lastY;
                    layout(getLeft()+offestX,getTop()+offestY,getRight()+offestX,getBottom()+offestY);
                    break;
        }
        return true;
  //返回true 和 false的效果是有区别的:
  //setOnTouchListener 单独使用的时候返回值需要为true,这样才能保证移动的时候能后获取相应的监听,而非一次监听(即每次只有一个按下的事件)
  //setOnTouchListener 和 setOnClickListener 同时使用时,onTouch 的返回值要设为 false,这样既可以保证按下移动抬起事件可以被监听,并且点击事件也会被监听。

    }

效果图:
在这里插入图片描述
还有好几种其他的滑动方式
3.自定义属性
在values目录下创建attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RectView">
        <attr name="color_pc" format="color"/>
        //.....更多你想要的属性
    </declare-styleable>
</resources>

然后在RectView的构造方法中解析这些属性

 public RectView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.RectView);
        color=typedArray.getColor(R.styleable.RectView_color_pc,Color.RED);
        typedArray.recycle();
        init();  //在xml中调用的,所以在这里初始化
    }

在这里插入图片描述
4.onMeasure方法
这个方法主要是实现wrap_content属性

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int withSpecMode=MeasureSpec.getMode(widthMeasureSpec);
        int heightSpecMode=MeasureSpec.getMode(heightMeasureSpec);
        int withSpecSize=MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);
        if (withSpecMode== ViewGroup.LayoutParams.WRAP_CONTENT &&heightSpecMode==ViewGroup.LayoutParams.WRAP_CONTENT){
            setMeasuredDimension(200,200);
        }
        if (withSpecMode==ViewGroup.LayoutParams.WRAP_CONTENT){
            setMeasuredDimension(200,heightSpecSize);
        }
        if (heightSpecMode==ViewGroup.LayoutParams.WRAP_CONTENT){
            setMeasuredDimension(withSpecSize,200);
        }
    }

若果把判断条件改为withSpecMode==MeasureSpec.AT_MOST,存在一定的错误,详解见为什么你的自定义View wrap_content不起作用?文末第5点的特别注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值