自定义View绘制图像与移动字体

自定义View在开发中是经常遇到的,例如一个跑马灯的效果、或者自定义一个转盘来显示下载进度的百分百比。今天把实现方式写下来,下面是源码部分:

MainActivity:没变动

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

主布局:只增加了一个自定义View

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.myview.MineView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
    </com.example.myview.MineView>

</RelativeLayout>

自定义View:

import java.util.Random;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;

public class MineView extends View {

    /**
     * 字体移动的X坐标
     */
    private int rx = 0;
    /**
     * 画笔工具
     */
    private Paint paint;
    /**
     * 创建线程对象,用于循环延迟执行命令
     */
    private MyThread t;
    /**
     * 0表示圆的left,60表示圆的top,100表示圆的right,160表示圆的bottom
     */
    private RectF rectF = new RectF(0, 60, 100, 160);
    /**
     * 表示区间角度
     */
    private float sweepAngle;
    /**
     * 创建随机数对象
     */
    private Random random;
    /**
     * isdestroy表示该Activity是否已经结束
     */
    private boolean isdestroy = false;

    public MineView(Context context, AttributeSet attrs) {
        super(context, attrs);
        System.out.println("构造器");
        paint = new Paint();
        random = new Random();
        //抗锯齿,否则图像会很难看
        paint.setAntiAlias(true);
        if (t == null) {
            t = new MyThread();
            t.start();
        }
    }

    public MineView(Context context) {
        super(context);
        System.out.println("构造器");
        paint = new Paint();
        paint.setAntiAlias(true);
        if (t == null) {
            t = new MyThread();
            t.start();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setTextSize(30);
        // rx表示移动字体的x坐标
        canvas.drawText("移动字体", rx, 30, paint);
        // rectF表示圆的对象,0表示起始角度,sweepAngle表示区间角度,true和false表示绘制过程的方式,paint表示画笔对象
        canvas.drawArc(rectF, 0, sweepAngle, true, paint);
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            while (true) {
                rx += 5;
                // 如果字体移动出屏幕以外,就让字体从头开始
                if (rx > getWidth()) {
                    rx = (int) (0 - paint.measureText("移动字体"));
                }

                sweepAngle += 5;
                // 如果角度大于360就让圆从0度开始重新绘制
                if (sweepAngle > 360) {
                    sweepAngle = 0;
                }
                // 让颜色从0-255随机选择
                int r = random.nextInt(256);
                int g = random.nextInt(256);
                int b = random.nextInt(256);
                // 分别表示:透明度(0~255)、红、绿、蓝
                paint.setARGB(255, r, g, b);
                /**
                 * 判断Activity是否已经退出,如果退出则isdestroy为true,那么立刻让线程对象与画笔对象为空,并且break,
                 * 否则会造成内存溢出,此办法必须在此处使用,否则会造成空指针的BUG。
                 */
                if (isdestroy) {
                    if (t != null) {
                        t = null;
                    }
                    if (paint != null) {
                        paint = null;
                    }
                    break;
                }
                // 睡眠
                SystemClock.sleep(50);
                // 可以让ondraw方法重新执行
                postInvalidate();
                // invalidate();分线程无效,要在主线程使用
            }
        }
    }

    /**
     * 当窗口销毁的时候会调用此方法,用于关闭资源
     */
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isdestroy = true;
        System.out.println("onDetachedFromWindow");

    }

}

运行效果:运行起来是动态的,我不会上传动态效果,想看效果的自己跑起来就可以了。

注意:这里的跑马灯效果只是一种非常笨的方式,有更简单的办法,我以后会介绍!

时间: 2024-11-03 05:29:50

自定义View绘制图像与移动字体的相关文章

Android应用自定义View绘制方法手册

背景 这篇迟迟难产的文章算是对2015前半年的一个交代吧,那时候有一哥们要求来一发Android Canvas相关总结,这哥们还打赏了,实在不好意思,可是这事一放就给放忘了,最近群里小伙伴催着说没更新博客,坐等更新啥的,随先有这么一篇Android应用开发超级基础的文章诞生了(因为这种文章最好写哈,就是用熟了就行).不得不说下这么久为何一直没更新博客的原因了,首先遇上了过年,我个人崇尚过节就该放下一切好好陪陪亲人,珍惜在一起的时光:其次今年开年很是蛋疼,不是不顺当就是深深的觉得被坑,所以心情也就

Android自定义View绘制闹钟

Android自定义View绘制闹钟 本文简单实现了一个闹钟,扩展View,Canvas绘制 效果如下: 代码如下: package com.gaofeng.mobile.clock_demo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.gr

android自定义View绘制圆形头像与椭圆头像

要实现这两种效果,需要自定义View,并且有两种实现方式. 第一种: public class BitmapShaders extends View { private  BitmapShader bitmapShader = null; private Bitmap bitmap = null; private Paint paint = null; private ShapeDrawable shapeDrawable = null; private int BitmapWidth  = 0

Android UI设计之&lt;十二&gt;自定义View,实现绚丽的字体大小控制控件FontSliderBar

转载请注明出处:http://blog.csdn.net/llew2011/article/details/51668407 了解iOS的同学应该知道在iOS中有个UISliderBar控件,在iPhone手机中的设置文字大小中使用了该控件.近来产品提的需求中有一个是更改APP中部分字体大小,虽然技术难度不大但工作量还是有的,思路是利用LayoutInflater.Factory实现的(如果你对LayoutInflater.Factory不熟悉可以阅读之前写的Android 源码系列之<四>从

自定义View绘制字符串

1 import android.app.Activity; 2 import android.os.Bundle; 3 import android.view.Display; 4 import android.view.View; 5 import android.content.Context; 6 import android.graphics.Canvas; 7 import android.graphics.Color; 8 import android.graphics.Paint

Android软件开发之盘点自定义View界面大合集(二)

Android软件开发之盘点自定义View界面大合集(二) - 雨松MOMO的程序世界 - 51CTO技术博客 雨松MOMO带大家盘点Android 中的自定义View界面的绘制 今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧. 1.自定义view绘制字符串 相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便 省内存 我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要 而且使用它还可以带来一个更重要的好处就是很方

Android View绘制及实践

概述 整个View树的绘图流程是在ViewRoot.java类的performTraversals()函数展开的,该函数做的执行过程可简单概况为: - 判断是否需要重新计算视图大小(measure) - 判断是否重新需要安置视图的位置(layout) - 判断是否需要重绘(draw) 其整个流程图如下: 图片来自:Android 开源项目源码解析 公共技术点中的 View 绘制流程 在Android中View的整个生命周期,调用invalidate和requestLayout会触发一系列的方法,

为什么你的自定义View wrap_content不起作用?

前言 自定义View是Android开发中非常常用的知识 可是,在使用过程中,有些开发者会发现:为什么自定义View 中设置的wrap_content属性不起作用(与match_parent相同作用)? 今天,我将全面分析上述问题并给出解决方案. 目录 1. 问题描述 在使用自定义View时,View宽 / 高的wrap_content属性不起自身应有的作用,而且是起到与match_parent相同作用. wrap_content与match_parent区别: 1. wrap_content:

Path类的最全面详解 - 自定义View应用系列

前言 自定义View是Android开发者必须了解的基础:而Path类的使用在自定义View绘制中发挥着非常重要的作用 网上有大量关于自定义View中Path类的文章,但存在一些问题:内容不全.思路不清晰.简单问题复杂化等等 今天,我将全面总结自定义View中Path类的使用,我能保证这是市面上的最全面.最清晰.最易懂的 文章较长,建议收藏等充足时间再进行阅读 阅读本文前请先阅读自定义View基础 - 最易懂的自定义View原理系列 目录 1. 简介 定义:路径,即无数个点连起来的线 作用:设置