Android自定义View之自绘

目录

1.简单实现

2.使用自绘View,写一个简单的交通灯程序(斑马线上的那种)

3.源码下载


1.简单实现

自绘View实现其实很简单,可以简单总结为三步:

1.继承View;

2.创建Paint;

3.在onDraw()里面画。

例子:

public class DrawView extends View
{

    private Paint paint;

    public DrawView(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.GREEN);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, paint);
    }

}

将paint的flage设置为Paint.ANTI_ALIAS_FLAG,意思是设置成抗锯齿模式。什么是抗锯齿?我在网上看到的答案:

当然你设置成别的flag也完全OK

设置paint的颜色设置为Color.GREEN

最后在onDraw里面用canvas.drawCircle()绘制圆,前两个参数为圆心的x,y坐标,第三个参数为半径,最后一个为绘制这个圆所使用的颜料就是指paint

使用:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <com.view.customview.DrawView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_centerInParent="true"></com.view.customview.DrawView>

</RelativeLayout>

运行效果:

还有一点就是invalidate()方法会让View重新绘制一次,也就是会重新回调一次onDraw()

例子:

我们将这个View设置为点击一下,更换颜色成蓝色


public class DrawView extends View implements View.OnClickListener
{
    private Paint paint;

    public DrawView(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        setOnClickListener(this);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.GREEN);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, paint);
    }

    @Override
    public void onClick(View v)
    {
        paint.setColor(Color.BLUE);
        invalidate();
    }
}

点击事件触发将paint改成蓝色,再调用invalidate(),回调onDraw重绘此View

2.使用自绘View,写一个简单的交通灯程序(斑马线上的那种)

我的需求:

1.红灯先常亮10s,之后黄灯常亮3s,之后绿灯常亮10s,最后黄灯常亮3s,以此循环;

2.灯的熄灭状态设置为亮灰色;

3.他们倒计时的时间需要显示的灯上。

自定义交通灯LightView

public class LightView extends View
{
    private Paint paint;

    private Rect bounds; //用于获取文字的高度

    private int count = 0; //倒计时的时间

    private int color = Color.LTGRAY;

    private boolean isShowCount = false;

    private CountDownTimer countDownTimer; //计时器

    public LightView(Context context, @Nullable AttributeSet attrs)
    {
        super(context, attrs);
        bounds = new Rect();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    /**
     * 绘制代码写在onDraw()
     *
     * @param canvas 靠他来画
     */
    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);

        paint.setColor(color);
        //绘制圆
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, paint);

        if (isShowCount)
        {
            paint.setColor(Color.BLACK);
            paint.setTextSize(100);

            String showText = String.valueOf(count);
            //这里获取showText文字的宽度和高度
            paint.getTextBounds(showText, 0, showText.length(), bounds);
            float textWidth = bounds.width();
            float textHeight = bounds.height();

            //绘制倒计时文字
            canvas.drawText(showText, getWidth() / 2 - textWidth / 2, getHeight() / 2 + textHeight / 2, paint);
        }
    }

    /**
     * 设置开关灯
     *
     * @param isOpen      是否打开
     * @param color       打开什么颜色
     * @param isShowCount 是否显示倒计时
     * @param count       显示时间的长度
     */
    public void setSwitchLight(boolean isOpen, int color, boolean isShowCount, int count)
    {
        if (isOpen)
        {
            this.color = color;
            this.isShowCount = isShowCount;
            this.count = count;
            countDownTimer = new CountDownTimer(count * 1000, 1000)
            {
                @Override
                public void onTick(long millisUntilFinished)
                {
                    invalidate();
                    LightView.this.count--;
                }

                @Override
                public void onFinish()
                {

                }
            };
            countDownTimer.start();
        } else
        {
            this.color = Color.LTGRAY;
            this.isShowCount = false;
        }
        invalidate();
    }
}

这里我们使用CountDownTimer来计时,从而刷新灯上的数字。

activity_light.xml的编写

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.view.customview.LightView
        android:id="@+id/dv_red_light"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_above="@+id/dv_yellow_light"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:visibility="visible" />

    <com.view.customview.LightView
        android:id="@+id/dv_yellow_light"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        android:visibility="visible" />

    <com.view.customview.LightView
        android:id="@+id/dv_green_light"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@+id/dv_yellow_light"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:visibility="visible" />
</RelativeLayout>
LightActivity.java

public class LightActivity extends AppCompatActivity
{
    private LightView redLight;

    private LightView yellowLight;

    private LightView greenLight;

    private static final int RED = 0;

    private static final int YELLOW = 1;

    private static final int GREEN = 2;

    private Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case RED:
                    redLight.setSwitchLight(true, Color.RED, true, 10);
                    yellowLight.setSwitchLight(false, Color.LTGRAY, false, 0);
                    greenLight.setSwitchLight(false, Color.LTGRAY, false, 0);
                    break;
                case YELLOW:
                    yellowLight.setSwitchLight(true, Color.YELLOW, true, 3);
                    redLight.setSwitchLight(false, Color.LTGRAY, false, 0);
                    greenLight.setSwitchLight(false, Color.LTGRAY, false, 0);
                    break;
                case GREEN:
                    greenLight.setSwitchLight(true, Color.GREEN, true, 10);
                    redLight.setSwitchLight(false, Color.LTGRAY, false, 0);
                    yellowLight.setSwitchLight(false, Color.LTGRAY, false, 0);
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_light);
        initData();
        initView();
        setListener();
    }

    private void initData()
    {

    }

    private void initView()
    {
        redLight = findViewById(R.id.dv_red_light);
        yellowLight = findViewById(R.id.dv_yellow_light);
        greenLight = findViewById(R.id.dv_green_light);
    }

    private void setListener()
    {
        /**
         * step1.先亮红灯3s
         * step2.再亮黄灯1s
         * step3.最后亮绿灯3s
         * step4.循环1-3
         * */
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                while (true)
                {
                    try
                    {
                        handler.sendEmptyMessage(RED);
                        Thread.sleep(10 * 1000);
                        handler.sendEmptyMessage(YELLOW);
                        Thread.sleep(3 * 1000);
                        handler.sendEmptyMessage(GREEN);
                        Thread.sleep(10 * 1000);
                        handler.sendEmptyMessage(YELLOW);
                        Thread.sleep(3 * 1000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

编译运行:

3.源码下载

https://github.com/messiwangzi/LightView

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值