【达内课程】自定义控件(奔跑的阿狸)

2024-05-12 09:32

本文主要是介绍【达内课程】自定义控件(奔跑的阿狸),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这一节要的效果如图
在这里插入图片描述
新建AnimationView

public class AnimationView extends View {Bitmap[] bitmapArray = new Bitmap[4];int currentIndex = 0;int viewWidth, viewHeight;int sleepTime = 1000;boolean isRunning = true;Thread thread;public AnimationView(Context context, AttributeSet attrs) {super(context, attrs);bitmapArray[0] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo1);bitmapArray[1] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo2);bitmapArray[2] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo3);bitmapArray[3] = BitmapFactory.decodeResource(getResources(), R.mipmap.logo4);thread = new Thread(new MyRunnable());thread.start();}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Rect rect = new Rect(0, 0, viewWidth, viewHeight);Paint paint = new Paint();paint.setColor(Color.CYAN);canvas.drawRect(rect, paint);Bitmap bitmap = bitmapArray[currentIndex];int imageX = (viewWidth - bitmap.getWidth()) / 2;int imageY = (viewHeight - bitmap.getHeight()) / 2;canvas.drawBitmap(bitmap, imageX, imageY, paint);}/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {viewWidth = w;viewHeight = h;super.onSizeChanged(w, h, oldw, oldh);}class MyRunnable implements Runnable {@Overridepublic void run() {while (isRunning) {try {currentIndex++;if (currentIndex > (bitmapArray.length - 1)) {currentIndex = 0;}//只能在主线程中调用invalidate()//工作线程中调onDrawpostInvalidate();Thread.currentThread().sleep(sleepTime);} catch (InterruptedException e) {e.printStackTrace();}}}}
}

在布局中使用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@mipmap/first_bg"><com.example.xx.allrun.widget.AnimationViewandroid:id="@+id/animationView"android:layout_width="match_parent"android:layout_height="match_parent" /></LinearLayout>

素材图片如下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
增加自定义属性

res下增加attrs.xml,这里我们定义了2个属性,sleep_time用来控制休眠时间,是个浮点类型;images用来控制图片,是个引用类型

<resources><declare-styleable name="AnimationView"><attr name="sleep_time" format="float"/><attr name="images" format="reference"/></declare-styleable>
</resources>

xml使用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:AnimationView="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.xx.animationview.AnimationViewandroid:id="@+id/animationView"android:layout_width="match_parent"android:layout_height="match_parent"AnimationView:sleep_time="1000"/></LinearLayout>

这里用了我们刚才自定义的属性,就行android中自带的属性会有android:前缀,我们自定义的属性要想使用自定义的前缀,需要增加声明。例如,我们使用AnimationView:前缀,我们需要增加xmlns:AnimationView="http://schemas.android.com/apk/res-auto",这行代码

AnimationView的构造方法中可以拿到这些属性

    public AnimationView(Context context, AttributeSet attrs) {super(context, attrs);//读取自定义属性//attrs里放的是属性//数组里放的是sleep_time和images属性TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AnimationView);sleepTime = (int)typedArray.getFloat(R.styleable.AnimationView_sleep_time,0);......}

现在我们来用属性控制图片

res下新建arrays.xml

<resources><string-array name="animationImages"><item>@mipmap/logo1</item><item>@mipmap/logo2</item><item>@mipmap/logo3</item><item>@mipmap/logo4</item></string-array>
</resources>

xml中使用

    <com.xx.animationview.AnimationViewandroid:id="@+id/animationView"android:layout_width="match_parent"android:layout_height="match_parent"AnimationView:sleep_time="5000"AnimationView:images="@array/animationImages"/>

AnimationView构造方法中读取图片属性,之前存放图片的 Bitmap[] bitmapArray 指定了大小为4,这里去掉这个限制,设置其大小为图片的个数

public class AnimationView extends View {Bitmap[] bitmapArray;......public AnimationView(Context context, AttributeSet attrs) {super(context, attrs);......//读取float和读取数组是不一样的Resources resources = context.getResources();TypedArray typedArrayImages = resources.obtainTypedArray(R.array.animationImages);int length = typedArrayImages.length();bitmapArray = new Bitmap[length];for(int i=0;i<length;i++){//从数组中读取图的Id//第二个参数是默认值int imageResId = typedArrayImages.getResourceId(i,0);//创建BitmapBitmap bitmap = BitmapFactory.decodeResource(context.getResources(),imageResId);bitmapArray[i] = bitmap;}......}
}

设置控件宽高

现在控件是全屏的,现在设置控件大小为最大的图片宽高

布局中设置控件宽高为wrap_content

<com.xx.animationview.AnimationViewandroid:id="@+id/animationView"android:layout_width="wrap_content"android:layout_height="wrap_content"AnimationView:sleep_time="500"AnimationView:images="@array/animationImages"/>

AnimationView中定义最大宽高,然后重写onMeasure方法

public class AnimationView extends View {......//图片最大宽高int imageMaxWidth,imageMaxHeight;public AnimationView(Context context, AttributeSet attrs) {super(context, attrs);......for(int i=0;i<length;i++){//从数组中读取图的Id//第二个参数是默认值int imageResId = typedArrayImages.getResourceId(i,0);//创建BitmapBitmap bitmap = BitmapFactory.decodeResource(context.getResources(),imageResId);//得图的最大宽高if(bitmap.getWidth()>imageMaxWidth){imageMaxWidth = bitmap.getWidth();}if(bitmap.getHeight()>imageMaxHeight){imageMaxHeight = bitmap.getHeight();}bitmapArray[i] = bitmap;}thread = new Thread(new MyRunnable());thread.start();}//设置控件的大小@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(imageMaxWidth,imageMaxHeight);}......
}

下载地址

https://download.csdn.net/download/u010356768/11151293

这篇关于【达内课程】自定义控件(奔跑的阿狸)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/982247

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

Oracle type (自定义类型的使用)

oracle - type   type定义: oracle中自定义数据类型 oracle中有基本的数据类型,如number,varchar2,date,numeric,float....但有时候我们需要特殊的格式, 如将name定义为(firstname,lastname)的形式,我们想把这个作为一个表的一列看待,这时候就要我们自己定义一个数据类型 格式 :create or repla

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d

一步一步将PlantUML类图导出为自定义格式的XMI文件

一步一步将PlantUML类图导出为自定义格式的XMI文件 说明: 首次发表日期:2024-09-08PlantUML官网: https://plantuml.com/zh/PlantUML命令行文档: https://plantuml.com/zh/command-line#6a26f548831e6a8cPlantUML XMI文档: https://plantuml.com/zh/xmi

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在

小程序button控件上下边框的显示和隐藏

问题 想使用button自带的loading图标功能,但又不需要button显示边框线 button控件有一条淡灰色的边框,在控件上了样式 border:none; 无法让button边框隐藏 代码如下: <button class="btn">.btn{border:none; /*一般使用这个就是可以去掉边框了*/} 解决方案 发现button控件有一个伪元素(::after

鸿蒙开发中实现自定义弹窗 (CustomDialog)

效果图 #思路 创建带有 @CustomDialog 修饰的组件 ,并且在组件内部定义controller: CustomDialogController 实例化CustomDialogController,加载组件,open()-> 打开对话框 , close() -> 关闭对话框 #定义弹窗 (CustomDialog)是什么? CustomDialog是自定义弹窗,可用于广告、中