欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Study Material Design 八 之 玩转Palette调色板

程序员文章站 2022-05-30 22:17:17
...

LZ-Says: 大风把烈酒吹醒 方知拥有过的都是梦

Android Study Material Design 八 之 玩转Palette调色板


前言

Hello,伙伴们,大家好哈~

又到了LZ装逼时刻~

Android Study Material Design 八 之 玩转Palette调色板

今天继续为大家带来Material Design之Palette Study。

首先,还是老规矩,瞅一波效果图~


本文效果

千说百说,不如瞅下效果来的实际,如下:

Android Study Material Design 八 之 玩转Palette调色板


本文目标

阅读完本文,你能收获如下技能:

1) 通过阅读本文,掌握Palette用法;

2) 通过对实际开发中的拓展思考,希望对你撸码之路更上一层楼~

Palette简述及撸码实现

那么,到这里,你就会问了,Palette是什么鬼?它能干什么?

LZ这里简述下:

Palette,存在于v7包中,他主要作用就是可以为我们分析图片中色彩相关信息,例如:图片中鲜艳的颜色值、暗沉的颜色值等等等一系列相关属性。

那么这时候,小伙伴就会疑惑了,我特么的要他干嘛?没卵用啊?

伙计,话不要说太满哦~看我开车带你飞~

Android Study Material Design 八 之 玩转Palette调色板

首先,我们来介绍下,它提供的获取颜色值得Api所代表的含义:

1) int getDarkMutedColor(@ColorInt int defaultColor): 获取图片中较暗且较为柔和的颜色值,如果分析不出来,则返回设定的颜色值;

2) int getLightMutedColor(@ColorInt int defaultColor):获取图片中较为明亮且较为柔和的颜色值,同样如果分析不出来,则返回设定的颜色值;

3) int getDarkVibrantColor(@ColorInt int defaultColor):获取图片中较为暗且较为鲜艳(鲜活、明亮)颜色值,如分析失败,返回默认;

4) int getLightVibrantColor(@ColorInt int defaultColor):获取图片中较为明亮且较为鲜艳(鲜活、明亮)颜色值,如分析失败,返回默认;

5) int getMutedColor(@ColorInt int defaultColor):获取图片中较为鲜艳(鲜活、明亮)颜色值,如分析失败,返回默认。

以上五点,即为关键Api,下面,我们将依次为大家呈现几种不同的效果。

上面说过,Palette包含在v7包内,但实际使用时,我们依然需要单独引入Palette远程依赖,如下:

compile ‘com.android.support:palette-v7:23.0.0’

首先,布局方面的代码直接略过,没什么东西,我们直接来看具体如何使用:

第一步:拿到当前要分析的图片

    BitmapDrawable drawable = (BitmapDrawable) mImageView.getDrawable();
    Bitmap bitmap = drawable.getBitmap();

第二步:初始化Palette,开始进行图片分析

    Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
        @Override
        public void onGenerated(Palette palette) {
            //拿到分析后的结果 进行处理
        }

    });

关于初始化,以及拿到分析结果,我们看下源码里面,看看谷歌的工程师是如何思考问题,看看我们能不能有些属于我们的收获?

    public AsyncTask<Bitmap, Void, Palette> generate(final PaletteAsyncListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener can not be null");
        }

        return AsyncTaskCompat.executeParallel(
                new AsyncTask<Bitmap, Void, Palette>() {
                    @Override
                    protected Palette doInBackground(Bitmap... params) {
                        return generate();
                    }

                    @Override
                    protected void onPostExecute(Palette colorExtractor) {
                        listener.onGenerated(colorExtractor);
                    }
                }, mBitmap);
    }

AsyncTask,异步处理。这里大家想下,我分析一个问题,基本流程是,拿到问题后进行思考,思考完成后开始解决问题,那么相应的转化为这里,就是我们将图片提交给Palette,通知他去处理,处理过程中可能耗时1秒,也可能耗时10秒,那么这期间会不会阻塞UI线程呢?

所以,这里我们需要思考的问题就是,如果让你去写这么一个东西,你会如何写?这些细节能想到么?

没关系,让我们慢慢来,一口吃不成胖子~继续走起


当Palette分析完图片颜色信息后,我们进行详细处理,也就是设置我们TextView背景色。

    // 分析图片中 较暗、柔和的颜色
    // 分析不出来显示默认
    int darkMutedColor = palette.getDarkMutedColor(Color.BLUE);
    // 分析图片中 比较暗、柔和的颜色
    int lightMutedColor = palette.getLightMutedColor(Color.BLUE);
    // 分析图片中 比较暗、鲜艳的颜色
    int darkVibrantColor = palette.getDarkVibrantColor(Color.BLUE);
    // 分析图片中 比较亮、鲜艳的颜色
    int lightVibrantColor = palette.getLightVibrantColor(Color.BLUE);
    // 柔和
    int mutedColor = palette.getMutedColor(Color.BLUE);
    // 载体
    Palette.Swatch lightVibrantSwatch = palette.getLightMutedSwatch();
    // 获取谷歌提供推荐颜色 RGB
    int rgb = lightVibrantSwatch.getRgb();
    // 谷歌推荐作为 图片标题颜色(基于图片对比度所呈现的颜色值)
    int titleColor = lightVibrantSwatch.getTitleTextColor();
    // 谷歌推荐作为 图片中间文字颜色
    int bodyColor = lightVibrantSwatch.getBodyTextColor();
    // 颜色向量
    float[] hsl = lightVibrantSwatch.getHsl();
    // 分析颜色在图片所占的像素值
    int population = lightVibrantSwatch.getPopulation();

关于代码中载体部分,这里简单为大家描述下:

载体,说白了就是Palette中一个内部类,此类的作用就是为我们封装了一些谷歌推荐的内容,简单附上部分常量。

private final int mRed, mGreen, mBlue;
private final int mRgb;
private final int mPopulation;

private boolean mGeneratedTextColors;
private int mTitleTextColor;
private int mBodyTextColor;

private float[] mHsl;

鉴名其意,不比多说,下面简单看下效果:

Android Study Material Design 八 之 玩转Palette调色板

观察上图,有个半透明颜色值,这个该如何实现呢?

很easy,思路就是,拿到分析出的rgb以及需要透明的度数,通过改变alpha值去改变实际透明度。

    /**
     * 1101 0111 1000 1011
     * 依次代表 a r g b 通过位移 得出实际结果
     *
     * @param percent 百分比 比例
     * @param rgb
     * @return
     */
    private int getTranslucentColor(float percent, int rgb) {
        // 方式一:使用谷歌推荐方式 效率更高
        // 关于运算 可以直接源码查看
//        int alpha = rgb >>> 24;
//        int red = rgb >> 16 & 0xff;
//        int green = rgb >> 8 & 0xff;
//        int blue = rgb & 0xff;

        // 方式二:使用提供Api
        int alpha = Color.alpha(rgb);
        int blue = Color.blue(rgb);
        int red = Color.red(rgb);
        int green = Color.green(rgb);

        alpha = Math.round(alpha * percent);
        return Color.argb(alpha, red, green, blue);
    }

而基于以上内容,我们如何实现如下图效果呢?

Android Study Material Design 八 之 玩转Palette调色板

先为大家讲述下思路:

1. 拿到Palette对图片分析结果,动态设置颜色值即可。

嗯哼,就是这么esay:

private void initImg1() {
    ImageView iv = (ImageView) findViewById(R.id.id_image_test1);
    BitmapDrawable drawable = (BitmapDrawable) iv.getDrawable();
    Bitmap bitmap = drawable.getBitmap();
    // 拿到图片 生成调色板
    Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
        @Override
        public void onGenerated(Palette palette) {
            // 载体
            Palette.Swatch lightVibrantSwatch = palette.getLightMutedSwatch();
            TextView tv = (TextView) findViewById(R.id.id_text1);
            tv.setTextColor(lightVibrantSwatch.getTitleTextColor());
            tv.setBackgroundColor(getTranslucentColor(0.5f, palette.getLightVibrantColor(Color.BLUE)));
        }

    });
}

而关于Palette调色板介绍到此结束,下面开启新篇章。


实际项目拓展

不知道大家还对微信、支付宝等等设置到绑定银行卡的界面还有没有印象?

为大家手绘一图,较为恶心,勿吐槽~

Android Study Material Design 八 之 玩转Palette调色板

这个界面,大家想想怎么做?

首先,银行的Logo是我们后台返回,因为我们本地不可能保存所有银行的Logo;
其次,当前item的背景色和当前的Logo中颜色相近,而我们首先想到的就是,后台继续返回。

最后,我们基于本文,重新回顾下,现在的我们,拿到这个界面的时候,是如何玩转。

通过获取到当前item的银行Logo,我们调用Palette进行分析其中包含颜色值,最后拿到分析结果,赋值item背景即可。

关于代码设置圆角弧度以及渐变,提供如下方式:

    /**
     * 设置圆角弧度以及渐变
     *
     * @param startRGB
     * @param endRGB
     * @return
     */
    private Drawable getImageViewShape(int startRGB, int endRGB) {
        GradientDrawable shape = new GradientDrawable(GradientDrawable.Orientation.TL_BR
                , new int[]{startRGB, endRGB});
        shape.setShape(GradientDrawable.RECTANGLE);
        shape.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        shape.setCornerRadius(8);
        return shape;
    }

部分代码如下:

    private void initZS() {
        ImageView iv=(ImageView) findViewById(R.id.iv_zs);
        Bitmap bitmap = ((BitmapDrawable) iv.getDrawable()).getBitmap();
        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                // 载体
                Palette.Swatch lightVibrantSwatch = palette.getLightMutedSwatch();
                LinearLayout ll = (LinearLayout) findViewById(R.id.ll_zs);
                ((TextView) findViewById(R.id.tv_zs)).setTextColor(lightVibrantSwatch.getTitleTextColor());
                ll.setBackgroundColor(palette.getDarkVibrantColor(Color.BLUE));
            }

        });
    }

    private void initYZ() {
        BitmapDrawable drawable = (BitmapDrawable) ((ImageView) findViewById(R.id.iv_yz)).getDrawable();
        Bitmap bitmap = drawable.getBitmap();
        Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
            @Override
            public void onGenerated(Palette palette) {
                // 载体
                Palette.Swatch lightVibrantSwatch = palette.getLightMutedSwatch();
                LinearLayout ll = (LinearLayout) findViewById(R.id.ll_yz);
                ((TextView) findViewById(R.id.tv_yz)).setTextColor(lightVibrantSwatch.getTitleTextColor());
                ll.setBackgroundColor(palette.getDarkVibrantColor(Color.BLUE));
            }

        });
    }

那么一起来看下效果:

Android Study Material Design 八 之 玩转Palette调色板

其实,该给个间距的,不过这些对于老铁们简直分分钟,是吧?

Android Study Material Design 八 之 玩转Palette调色板

这样做的好处在于一点,避免apk包含无用图标从而占用不必要的资源大小。


GitHub查看地址

https://github.com/HLQ-Struggle/MaterialDesignStudy/tree/master/app/src/main/java/com/materialdesignstudy/paletter


赞赏

阅读到此,如觉得有所收获,不妨请LZ喝瓶水,一分也是爱呀~

Android Study Material Design 八 之 玩转Palette调色板


The End

当年,刚刚撸码时,我们想的会写就好~

而今,撸了一次又一次码,我们想的如何写的更好~

未来,没有准确性,但是,只要努力,加油,未来,不会亏待~