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

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

Android Study Material Design 八 之 玩转Palette调色板_第1张图片


前言

Hello,伙伴们,大家好哈~

又到了LZ装逼时刻~

Android Study Material Design 八 之 玩转Palette调色板_第2张图片

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

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


本文效果

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


本文目标

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

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

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

Palette简述及撸码实现

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

LZ这里简述下:

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

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

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

Android Study Material Design 八 之 玩转Palette调色板_第3张图片

首先,我们来介绍下,它提供的获取颜色值得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 generate(final PaletteAsyncListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("listener can not be null");
        }

        return AsyncTaskCompat.executeParallel(
                new AsyncTask() {
                    @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调色板_第4张图片

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

很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调色板_第5张图片

先为大家讲述下思路:

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调色板_第6张图片

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

首先,银行的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调色板_第7张图片

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

Android Study Material Design 八 之 玩转Palette调色板_第8张图片

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


GitHub查看地址

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


赞赏

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

Android Study Material Design 八 之 玩转Palette调色板_第9张图片


The End

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

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

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

border="0" width="330" height="86" src="//music.163.com/outchain/player?type=2&id=32507038&auto=1&height=66">

你可能感兴趣的:(Android,Love,and,Hatred,Material,Design,Study)