自定义view小结

1.自定义view分类

自定义view主要分为:
自定义view小结_第1张图片

第一种方式:继承View,View是android中界中最基础的元素,也就是说是基类,所有控件或者布局都是view的子类。

第二种方式:继承View的子类,比如说TextView,ImageView,Button之类的。。

第三种方式:继承ViewGroup,这种实现方式也比较复杂,与继承View相信,如果使用用这种方式,我们必须在onMeasure()和onLayout中处理margin,padding之类的工作。

第四种方式:继承ViewGroup的子类(Linearlayout,Relativelayout),ViewGroup是View的子类,而ViewGroup又是所有layout的基类。

2.时钟案例

首先画出员盘的位置,在画出盘上的数字,然后画出时针分针秒针,设计时针分针秒针的时间用变量表示,主线程获得当前时间,传递给自定义view的一个方法,方法里把主线程获得当前时间赋值给时针分针秒针的时间用变量,再用invalidate()刷新;再开启子线程,让主线程每过一秒得到系统的秒的变量加一,然后给handler传递一个消息,handler继续调用view的一个方法传递时间变量。
代码如下:

package com.example.lianxi;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;


import java.util.Calendar;

public class MyView extends View {

    private ObjectAnimator objectAnimator;
    private int hour=0;
    private int minute=0;
    private int seconds=0;
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint=new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);
        canvas.save();
        RectF rectF=new RectF(getWidth()/4,getHeight()/2-getWidth()/4,getWidth()/4*3,getHeight()/2+getWidth()/4);
        Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.mipmap.biaopan);

        canvas.drawBitmap(bitmap,null,rectF,paint);
        canvas.restore();
        for (int i=1;i<13;i++){
            canvas.save();
            canvas.rotate(30*i,getWidth()/2,getHeight()/2);
            canvas.drawText(i+"",getWidth()/2-17,getHeight()/2-getWidth()/4+30,paint);
            canvas.restore();
        }
        canvas.save();
        canvas.drawLine(getWidth()/2,getHeight()/2, getWidth()/2,getHeight()/2-getWidth()/4+40,paint);
        paint.setStrokeWidth(4);
        canvas.rotate(6*seconds,getWidth()/2,getHeight()/2);
        canvas.restore();
        canvas.save();
        paint.setColor(Color.RED);
        canvas.drawLine(getWidth()/2,getHeight()/2, getWidth()/2,getHeight()/2-getWidth()/4+60,paint);
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(6);
        canvas.rotate(minute*6,getWidth()/2,getHeight()/2);
        canvas.restore();
        canvas.save();
        canvas.drawLine(getWidth()/2,getHeight()/2, getWidth()/2,getHeight()/2-getWidth()/4+80,paint);
        canvas.rotate(hour*30+minute*30/60,getWidth()/2,getHeight()/2);paint.setStrokeWidth(8);
        canvas.restore();
        for(int x=1;x<=60;x++){
            canvas.save();
            if(x%5==0){
                paint.setStrokeWidth(8);
                canvas.drawLine(getWidth()/2,getHeight()/2-getWidth()/4, getWidth()/2,getHeight()/2-getWidth()/4+25,paint);
            }else {
                paint.setStrokeWidth(4);
                canvas.drawLine(getWidth()/2,getHeight()/2-getWidth()/4, getWidth()/2,getHeight()/2-getWidth()/4+20,paint);
            }
            canvas.restore();
        }
    }
    void refresh(int h, int m, int s){
        this.hour=h;
        this.minute=h;
        this.seconds=h;
        invalidate();
    }
package com.example.lianxi;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.util.Calendar;

public class MyViewActivity extends AppCompatActivity {
    private int hour;
    private int minute;
    private int second;
    private MyView myView;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            myView.refresh(msg.arg2,msg.arg1,msg.what);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_view);
        Calendar calendar = Calendar.getInstance();
        hour = calendar.get(Calendar.HOUR_OF_DAY); //时
        minute = calendar.get(Calendar.MINUTE); //分
        second = calendar.get(Calendar.SECOND); //秒
        myView=findViewById(R.id.my_view);
        myView.refresh(hour,minute,second);
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        while(true){
                        second++;
                        if (second==60){
                            second=0;
                            minute++;
                        }
                        if (minute==60){
                            hour++;
                            minute=0;
                        }
                        if (hour==12){
                            hour=0;
                        }
                        Message message=handler.obtainMessage();
                        message.what=second;
                        message.arg1=minute;
                        message.arg2=hour;
                        handler.sendMessage(message);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }}
        ).start();
    }
}

3.获得圆形图片

我这里是用传递一个bitmap和半径代码如下

 private Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
        Bitmap sbmp;
        //比较初始Bitmap宽高和给定的圆形直径,判断是否需要缩放裁剪Bitmap对象
        if (bmp.getWidth() != radius || bmp.getHeight() != radius)
            sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
        else
            sbmp = bmp;
        Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f,
                sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint);
        //核心部分,设置两张图片的相交模式,在这里就是上面绘制的Circle和下面绘制的Bitmap
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(sbmp, rect, rect, paint);
        return output;
    }

你可能感兴趣的:(初级安卓开发)