自定义控件三部曲之绘图篇(九)——Paint之setColorFilter

2024-02-28 09:08

本文主要是介绍自定义控件三部曲之绘图篇(九)——Paint之setColorFilter,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上篇给大家讲了在setColorFilter中使用ColorMatrix的过程,其实setColorFilter除了使用ColorMatrix还有其它的用法,这节我们就具体来看看setColorFilter的用法。

在本篇文章中,你将学到两个实例:

按钮点击时,动态加深图片色彩(简易方法)
可以学到针对不同主题动态设置不同色彩图片的方法(setTint())
一、setColorFilter
setColorFilter的完整声明为:
public ColorFilter setColorFilter(ColorFilter filter)
参数是传入ColorFilter的对象,其实ColorFilter是一个空对象,其中什么也没有:
public class ColorFilter {
    int native_instance;
 
    /**
     * @hide
     */
    public int nativeColorFilter;
 
    protected void finalize() throws Throwable {
        try {
            super.finalize();
        } finally {
            finalizer(native_instance, nativeColorFilter);
        }
    }
 
    private static native void finalizer(int native_instance, int nativeColorFilter);
}
但是ColorFilter派生了几个子类,分别是:

下面我们分别来讲讲各个子类的用法及效果

1、ColorMatrixColorFilter
这个是色彩矩阵颜色过滤器,该类只有两个函数,也都是构造函数:
ColorMatrixColorFilter(ColorMatrix matrix)
ColorMatrixColorFilter(float[] array)
在这里可以直接传入一个ColorMatrix对象,也可以直接传入一个色彩矩阵。我们知道ColorMatrix对应的也是一个色彩矩阵。 
上篇中我们在讲解ColorMatrix的用法时,也一直用到的是ColorMatrixColorFilter。 
这里在下面看下用法,具体就不再讲了,不理解的同学,请返回去看上一篇
canvas.drawBitmap(bitmap, null, new Rect(0, 0, 500, 500 * bitmap.getHeight() / bitmap.getWidth()), mPaint);
 
canvas.translate(510, 0);
// 生成色彩矩阵
ColorMatrix colorMatrix = new ColorMatrix(new float[]{
        1/2f,1/2f,1/2f,0,0,
        1/3f,1/3f,1/3f,0,0,
        1/4f,1/4f,1/4f,0,0,
        0,0,0,1,0
});
mPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
 
canvas.drawBitmap(bitmap, null, new Rect(0, 0, 500, 500 * bitmap.getHeight() / bitmap.getWidth()), mPaint);
效果图如下:

2、LightingColorFilter
前一篇,我们利用一篇的篇幅来讲解ColorMatrix的作用,所有需要完成色彩操作的都是可以利用ColorMatrix来完成的,只是有一点ColorMatrix纵然很强大,但太!过!难!用,所以Android为我们提供了一个简单过滤颜色和增强色彩的函数,就是LightingColorFilter 
这个叫做光照颜色过滤器,可以简单的完成色彩过滤和色彩增强功能。 
整个类就只有一个函数,还是构造函数:
public LightingColorFilter(int mul, int add)
这里有两个参数,mul是乘法multiply的缩写,add是加法的意思。mul和add取值都是0xRRGGBB,分别对应R、G、B颜色,注意哦,这里是没有透明度A的,透明度在这里是不起作用的,LightingColorFilter只针对RGB色值起作用 
比如,当前有一个颜色值为(r,g,b),对它应用LightingColorFilter(mul, add)效果后的颜色值为:
结果R值 = (r*mul.R+add.R)%255;
结果G值 = (g*mul.G+add.G)%255;
结果B值 = (b*mul.B+add.B)%255;
前面我们讲了mul和add的取值都是0xRRGGBB类型的值,即mul和add中都是包含了R、G、B分量的; 
在上面的公式中,三个颜色分量R、G、B值的方式都是一样的,我们只拿红色来讲:
结果R值 = (r*mul.R+add.R)%255;
作用LightingColorFilter(mul, add)效果后的R值等于,原来的r值乘以mul.R,然后再加上add.R做为最终结果。因为颜色值要的取值范围在0-255,所以要把结果对255取余,得到最终结果。 
所以从公式中可以看出mul.R是对当前红色值进行放大的倍数;而add.R则表示对当前红色增加的数值;它们对应ColorMatrix的位置如下:

G、B的原理类似,就不再缀述了。 
利用mul进行颜色值放大并不好控制,所以更多的是用来过滤颜色,即当对应的颜色值取0时,就不会将对应的颜色显示出来,而把要显示出来的颜色对应的mul值设置为ff,即255;从公式中可以知道设置为255不会对原始的这个颜色分量产生任何影响。所以这样就可以把想要的颜色给显示出来,把不想要的颜色给过滤掉 
比如,下面这个蓝色按钮:


我们可以在点击时让它变成绿色,这要怎么做呢?直接使用LightingColorFilter把其它颜色都过滤掉,只显示绿色就可以了:

public class MyView extends View {
    private Paint mPaint;
    private Bitmap mBmp;
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
 
        mBmp = BitmapFactory.decodeResource(getResources(),R.drawable.btn);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
 
        int width  = 500;
        int height = width * mBmp.getHeight()/mBmp.getWidth();
 
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
        canvas.translate(0,550);
        mPaint.setColorFilter(new LightingColorFilter(0x00ff00,0x000000));
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
    }
}
这段代码中最重要的就是这句:
mPaint.setColorFilter(new LightingColorFilter(0x00ff00,0x000000));
这里把mul参数设置为0x00ff00,即把绿色显示出来,把R和B过滤掉。而add参数全部设置为0,即没有对原始图像色彩做任何改变 
效果图如下:

好像这样会有点问题,因为普通我们在点击按钮的时候,不可能会直接把它改变成另一个颜色,而只是增加它的颜色深浅值。比如下面我们增强颜色的蓝色值,将整个图片变得更蓝

protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);
   mPaint.setAntiAlias(true);
 
   int width  = 500;
   int height = width * mBmp.getHeight()/mBmp.getWidth();
   canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
   canvas.translate(550,0);
   mPaint.setColorFilter(new LightingColorFilter(0xffffff,0x0000f0));
   canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
}
我们在设置LightingColorFilter使用了:
mPaint.setColorFilter(new LightingColorFilter(0xffffff,0x0000f0));
mul参数设置为0xffffff,即没有对颜色做任何改变;add参数设置为0x0000f0,即在每个像素的蓝色值在原来基础上增加0xf0,让原来的图像变得更蓝;这样会显得整个图片的颜色更深。更像按压后的效果。 
效果图如下:

3、PorterDuffColorFilter
这个叫PorterDuff颜色滤镜,也叫图形混合滤镜;其名称是Tomas Proter和Tom Duff两个人名的缩写,他们提出的图形混合的概念极大地推动了图形图像学的发展。 
这个颜色滤镜的声明如下:
public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode)
其中有两个参数:
int srcColor:0xAARRGGBB类型的颜色值。
PorterDuff.Mode mode:表示混合模式,枚举值有18个,表示各种图形混合模式,有:
Mode.CLEAR
Mode.SRC
Mode.DST
Mode.SRC_OVER
Mode.DST_OVER
Mode.SRC_IN
Mode.DST_IN
Mode.SRC_OUT
Mode.DST_OUT
Mode.SRC_ATOP
Mode.DST_ATOP
Mode.XOR
Mode.DARKEN
Mode.LIGHTEN
Mode.MULTIPLY
Mode.SCREEN
Mode.OVERLAY
Mode.ADD
有关这些混合模式,这里我们只简单的讲解一下具体效果,详细的算法会在后面详细讲解。 
大家看到这么多的效果估计都蒙B了,其实在这里跟我们相关的只有六个:Mode.ADD(饱和度相加),Mode.DARKEN(变暗),Mode.LIGHTEN(变亮),Mode.MULTIPLY(正片叠底),Mode.OVERLAY(叠加),Mode.SCREEN(滤色) 
我们拿正片叠底来试下效果:
public class MyView extends View {
    private Paint mPaint;
    private Bitmap mBmp;
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
 
        mBmp = BitmapFactory.decodeResource(getResources(),R.drawable.dog);
    }
 
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
        drawPorterDuffFilter(canvas);
    }
 
    private void drawPorterDuffFilter(Canvas canvas){
        int width  = 500;
        int height = width * mBmp.getHeight()/mBmp.getWidth();
 
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
        canvas.translate(550,0);
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY));//变暗
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
    }
}
效果图如下:

左侧是原图,右侧是与纯红色正片叠底后的效果。这些效果在PhotoShop中都是存在的 
首先,准备两张图片

效果图如下:

在录相中给大家演示了通过Photoshop来改变混合模式的过程,录相中分别更改了Mode.DARKEN(变暗),Mode.LIGHTEN(变亮),Mode.MULTIPLY(正片叠底),Mode.OVERLAY(叠加),Mode.SCREEN(滤色)这五种效果,大家可以尝试,我们通过代码得到的效果是与PhotoShop中的模式相同的。但PhotoShop中要比我们中强大的多,除了这些模式以外,还有其它的一些模式是我们所没有的;当然,PhotoShop中的所有这些效果都是可以通过ColorMetrix完成的,但前提是数学和色彩设计知识都要很棒才行哦。但Mode.ADD(饱和度)相加在Photoshop中是没有的。 
下面我通过代码把这几个效果给大家分别画出来: 
效果图如下:

对应代码如下:

public class MyView extends View {
    private Paint mPaint;
    private Bitmap mBmp;
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
 
        mBmp = BitmapFactory.decodeResource(getResources(),R.drawable.dog);
    }
 
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setAntiAlias(true);
 
        drawPorterDuffFilter(canvas);
    }
 
    private void drawPorterDuffFilter(Canvas canvas){
        int width  = 500;
        int height = width * mBmp.getHeight()/mBmp.getWidth();
 
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.ADD));//饱和度相加
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
 
        canvas.translate(550,0);
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DARKEN));//变暗
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
        canvas.translate(-550,550);
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.LIGHTEN));//变亮
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
        canvas.translate(550,0);
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY));//正片叠底
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
        canvas.translate(-550,550);
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.OVERLAY));//叠加
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
        canvas.translate(550,0);
        mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SCREEN));//滤色
        canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
    }
}
在这里大家不必理解PorterDuff.Mode的具体算法,只需要知道应用哪个模式,对应效果是怎样的就可以了。 
除了上面的六个Mode,还有其它的三组Mode,由于每组Mode的效果都是相同的,所以我们分组来讲 
第一组:清空模式 
Mode.CLEAR和Mode.XOR他们在这里的效果是完成一致的,就是把图像清空,所以一旦应用他们两个中的任何一个,所得到的结果图像就是一个空图
private void drawPorterDuffFilter(Canvas canvas){
    int width  = 500;
    int height = width * mBmp.getHeight()/mBmp.getWidth();
 
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.CLEAR));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(-550,550);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.XOR));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
}
得到的效果图如下:

在效果图中,只画出了原始图,另外两个图连个毛也没看到,没看到就对了,因为在应用Mode.CLEAR和Mode.XOR后,图像就会被完全清空了,当然什么也不会看到 
第二组:目标图像模式 
在Mode模式中,有一组DST相关的模式,DST所代表的意义就是被应用模式的图像,即我们这里的小狗图片。这些模式有:Mode.DST、Mode.DST_IN、Mode.DST_OUT、Mode.DST_OVER、Mode.DST_ATOP下面我们来看看他们的效果:

private void drawPorterDuffFilter(Canvas canvas){
    int width  = 500;
    int height = width * mBmp.getHeight()/mBmp.getWidth();
 
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DST));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(-550,550);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DST_IN));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DST_OUT));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(-550,550);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DST_OVER));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.DST_ATOP));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);

效果图如下:

从效果图中可以看到,除了Mode.DST_OUT显示完全透明图片以外,其它全部显示目标图像; 
所以这几个模式在PorterDuffColorFilter的实际应用中,并没什么用。 
第三组:源图模式 
在Mode模式中,有一组SRC相关的模式,SRC表示的颜色值所代表的图像,这些模式有:Mode.SRC、Mode.SRC_IN、Mode.SRC_OUT、Mode.SRC_OVER、Mode.SRC_ATOP下面我们来看看他们的效果:

private void drawPorterDuffFilter(Canvas canvas){
    int width  = 500;
    int height = width * mBmp.getHeight()/mBmp.getWidth();
 
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(-550,550);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_OUT));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(-550,550);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_OVER));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(550,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
}
同样是通过位移把相关的模式所对应的图像一个个画出来,效果图如下:

从效果图中可以看出,除了Mode.SRC_OUT显示完全透明图片以外,其它全部显示源图像; 
利用这个特性,我们可以在不同情况下,改变一个纯色图标的颜色。这个也是V4包中DrawableCompat类添加的一个setLint()函数所使用实现方法

setTint(Drawable drawable, int tint)
这个函数用于将一个图像设指为指定的颜色,比如下面的效果:

即最左边是一原图,后面都是指定的各个颜色,利用setTint就可以把一个图片渲染为不同的颜色,这样就可以支持多主题,在不同的风格和不同的情境下使用不同的颜色的图片。由于仅使用一个图片就可以实现多个主题,就不必再引入多个颜色的切图,就可以在一定程度上缩小包的大小。 
我们不必引入V4包,仅仅通过PorterDuffColorFilter就可以实现setTint的功能:

private void drawPorterDuffFilter(Canvas canvas){
    int width  = 100;
    int height = width * mBmp.getHeight()/mBmp.getWidth();
 
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(150,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(0xffff00ff, PorterDuff.Mode.SRC));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(150,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(0xff00f0ff, PorterDuff.Mode.SRC_ATOP));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(150,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(0xfff0f0ff, PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
    canvas.translate(150,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(0xffffff00, PorterDuff.Mode.SRC_OVER));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
 
 
    canvas.translate(150,0);
    mPaint.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.SRC_ATOP));
    canvas.drawBitmap(mBmp,null,new Rect(0,0,width,height),mPaint);
}
效果图如下:

从效果图中可以看到,SRC相关的模式,只有Mode.SRC_ATOP和SRC_IN能够实现SetTint的功能,其它的是不行的。这里先记着就可以了,后面地讲原理时会具体讲原因。 
所以这里的一个应用就是通过PorterDuffColorFilter的Mode.SRC_ATOP或SRC_IN模式实现SetTint()的功能; 
有些同学可能会讲,这个功能是不是可以通过ColorMatrix来实现?当然是可以的,比如我们要将原图标改成第三个效果,即颜色为0xff00f0ff,所对应的矩阵为:

ColorMatrix matrix = new ColorMatrix(new float[]{
        0,0,0,0,0,
        0,0,0,0,240,
        0,0,0,0,255,
        0,0,0,1,0
});
可不可以看出其中的门道?把原图像中的R、G、B全部置为0,然后我们通过每行最后的那个位移参数来指定我们想指定的RGB色。 
我们下面对PorterDuffColorFilter进行总结下:
1、PorterDuffColorFilter只能实现与一个特定颜色值的合成。 
2、通过Mode.ADD(饱和度相加),Mode.DARKEN(变暗),Mode.LIGHTEN(变亮),Mode.MULTIPLY(正片叠底),Mode.OVERLAY(叠加),Mode.SCREEN(滤色)可以实现与指定颜色的复合。 
3、通过Mode.SRC、Mode.SRC_IN、Mode.SRC_ATOP能够实现setTint()的功能,可以改变纯色图标的颜色。

 

这篇关于自定义控件三部曲之绘图篇(九)——Paint之setColorFilter的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

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

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

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

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

目录 一. 结构体的内存对齐 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