沉浸式设计之Palette应用

Palette是一个类似调色板的工具类,根据传入的bitmap,提取出主题颜色,使得图片和颜色更加搭配,界面更加协调,Palette可以从一张图片中提取颜色,我们可以把提取的颜色融入到APP UI中,可以使UI风格更加美观融合,比如,我们可以从图片中提取颜色设置给ActionBar做背景颜色,这样ActionBar的颜色就会随着显示的图片变化而变化,一些产品,例如,网易音乐,微信和支付宝银行卡列表页面,都应用到了palette。如下图,列表中的item背景都是根据不同银行的图表颜色进行设置


图片发自简书App


方法介绍

palette可以提取的颜色如下:

Vibrant(有活力的),Vibrant dark(有活力 暗色),Vibrant light(有活力 亮色),

Muted(柔和的),Muted dark(柔和的 暗色),Muted light(柔和 亮色)


使用

一.首先我们要引入 palette的包,在app下的build文件中添加compile 'com.android.support:palette-v7:23.4.0'

二.我们需要通过一个Bitmap对象来生成一个对应的Palette对象。

Palette generate(Bitmap bitmap)

Palette generate(Bitmap bitmap, int numColors)

generateAsync(Bitmap bitmap, PaletteAsyncListener listener)

generateAsync(Bitmap bitmap, int numColors, final PaletteAsyncListener listener)

不难看出,生成方法分为generate(同步)和generateAsync(异步)两种,如果图片过大使用generate方法,可能会阻塞主线程,我们更倾向于使用generateAsync的方法,其实内部就是创建了一个AsyncTask。generateAsync方法需要一个PaletteAsyncListener对象用于监听生成完毕的回调。除了必须的Bitmap参数外,还可以传入一个numColors参数指定颜色数,默认是 16。

三,得到Palette对象后,就可以拿到提取到的颜色值

Palette.getVibrantSwatch()

Palette.getDarkVibrantSwatch()

Palette.getLightVibrantSwatch()

Palette.getMutedSwatch()

Palette.getDarkMutedSwatch()

四.使用颜色,上面get方法中返回的是一个Swatch 样本对象,这个样本对象是Palette的一个内部类,它提供了一个最终获取方法

getPopulation();//样本中的像素数量

getRgb();//颜色的RGB值

getHsl();//颜色的HSL值(hsl指的的是颜色的 色相(H)、饱和度(S)、明度(L))

getBodyTextColor();//主题文字的颜色值

getTitleTextColor();//标题文字的颜色值

通过getRgb()可以得到最终的颜色值并应用到app UI中getBodyTextColor()和getTitleTextColor()可以得到此颜色下文字适合的颜色,这样我们就很方便的设置文字的颜色,使文字看起来更加舒服

代码奉上:

MainActivity

packagepattle.changting.com.tablayoutpattle;

importandroid.graphics.Bitmap;

importandroid.graphics.BitmapFactory;

importandroid.graphics.Color;

importandroid.os.Build;

importandroid.support.design.widget.TabLayout;

importandroid.support.v4.app.Fragment;

importandroid.support.v4.app.FragmentManager;

importandroid.support.v4.app.FragmentPagerAdapter;

importandroid.support.v4.view.ViewPager;

importandroid.support.v4.widget.DrawerLayout;

importandroid.support.v7.app.ActionBarDrawerToggle;

importandroid.support.v7.app.AppCompatActivity;

importandroid.os.Bundle;

importandroid.support.v7.graphics.Palette;

importandroid.support.v7.widget.Toolbar;

importandroid.view.Menu;

importandroid.view.View;

importandroid.view.Window;

public classMainActivityextendsBaseActivity {

TabLayouttabLayout;

ViewPagerviewPager;

Toolbartoolbar;

DrawerLayoutdrawerLayout;

private finalString[]titels= {"分类","主页","热门推荐","热门收藏","本月热榜","今日热榜","专栏","随机"};

private int[]drawbles= {R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e,R.drawable.f,R.drawable.g,R.drawable.h};

MyAdapter myAdapter;

Viewnav;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tabLayout= (TabLayout) findViewById(R.id.tablayout);

viewPager= (ViewPager) findViewById(R.id.viewpager);

toolbar= (Toolbar) findViewById(R.id.toolbar);

drawerLayout= (DrawerLayout) findViewById(R.id.drawer);

nav=(View)findViewById(R.id.nav);

toolbar.setTitle("沉浸式之palette应用");

setSupportActionBar(toolbar);

ActionBarDrawerToggle actionBarDrawerToggle =new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.open,R.string.close);

myAdapter=new MyAdapter(getSupportFragmentManager());

viewPager.setAdapter(myAdapter);

//设置联动

tabLayout.setupWithViewPager(viewPager);

colorChage(0);//设置第一个

viewPager.addOnPageChangeListener(newViewPager.OnPageChangeListener() {

@Override

public voidonPageScrolled(intposition, floatpositionOffset, intpositionOffsetPixels) {

}

@Override

public void onPageSelected(intposition) {

colorChage(position);

}

@Override

public void onPageScrollStateChanged(intstate) {

}

});

}

//如果页面发生切换  根据Bitmap改变toolBar颜色

private void colorChage(int position) {

Bitmap bitmap = BitmapFactory.decodeResource(getResources(),drawbles[position]);

//从bitmap中统计获取颜色块需要耗费一定的时间,所以用异步进行处理

Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {

@Override

public void onGenerated(Palette palette) {

//拿到鲜艳的颜色

Palette.Swatch vibreant = palette.getVibrantSwatch();

if(vibreant ==null) {

for(Palette.Swatch swatch : palette.getSwatches()) {

vibreant = swatch;

break;

}

}

viewPager.setBackgroundColor(vibreant.getRgb());

tabLayout.setSelectedTabIndicatorColor(vibreant.getRgb());

toolbar.setBackgroundColor(vibreant.getRgb());

setToolBarStyle(toolbar,nav,colorBurn(vibreant.getRgb()),vibreant.getRgb());

}

});

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.main,menu);

return super.onCreateOptionsMenu(menu);

}

//获取加深颜色

private int   colorBurn(intrgb) {

intred = rgb >>16&0xFF;

intgreen = rgb >>8&0xFF;

intblue = rgb &0xFF;

red = (int) Math.floor(red * (1-0.2));

green = (int) Math.floor(green * (1-0.2));

blue = (int) Math.floor(blue * (1-0.2));

returnColor.rgb(red,green,blue);

}

class  MyAdapter   extends    FragmentPagerAdapter {

public  MyAdapter(FragmentManager fm) {

super(fm);

}

@Override

public   Fragment  getItem(intposition) {

Fragment fragment =new   ImageFragment();

Bundle bundle =newBundle();

bundle.putInt("id",drawbles[position]);

fragment.setArguments(bundle);

return    fragment;

}

@Override

public int    getCount() {

return    drawbles.length;

}

@Override

public   CharSequence    getPageTitle(intposition) {

return     titels[position];

}

}

}

BaseActivity

importandroid.os.Build;

importandroid.os.Bundle;

importandroid.support.annotation.Nullable;

importandroid.support.annotation.RequiresApi;

importandroid.support.v7.app.AppCompatActivity;

importandroid.support.v7.widget.Toolbar;

importandroid.util.DisplayMetrics;

importandroid.util.Log;

importandroid.view.Display;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.view.WindowManager;

/**

* Created by Administrator on 2017/7/10 0010.

*/

public class   BaseActivity   extends     AppCompatActivity {

@Override

protected   void       onCreate(@NullableBundle savedInstanceState) {

super.onCreate(savedInstanceState);

//setContentView之前  全屏

if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.KITKAT&&

Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP) {

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

}

}

/**

* 5.0  4.4

*

*@paramtoolbar

*@paramstatusStyleColor状态栏的颜色,导航栏的颜色

*/

public    void      setToolBarStyle(Toolbar toolbar,View bottomView, intstatusStyleColor,intnavStyleColor) {

//        5.0  4.4

if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.KITKAT

&& Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP) {

if(toolbar !=null) {

//                ViewGroup.LayoutParams layoutParams=topView.getLayoutParams();

//                getResources().getDimension(android.R.dimen.s)

int     statusHeight = getStatusHeight();

Log.i("tuch","  statusHeight  "+ statusHeight);

//

//                layoutParams.height=statusHeight;

//                topView.setBackgroundColor(Color.GREEN);

//第二种

toolbar.setPadding(0,toolbar.getPaddingTop() + statusHeight,0,0);

//下面的导航栏

if(haveNavgtion()) {

ViewGroup.LayoutParams layoutParams = bottomView.getLayoutParams();

layoutParams.height+= getNavigationHeight();

Log.i("tuch","getNavigationHeight  "+ getNavigationHeight());

bottomView.setLayoutParams(layoutParams);

bottomView.setBackgroundColor(navStyleColor);

}

}

}else if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.LOLLIPOP) {

getWindow().setStatusBarColor(statusStyleColor);

getWindow().setNavigationBarColor(navStyleColor);

}else{

//没救了

}

}

private int    getNavigationHeight() {

intheight = -1;

try{

Class clazz = Class.forName("com.android.internal.R$dimen");

Object object = clazz.newInstance();

String heightStr = clazz.getField("navigation_bar_height").get(object).toString();

height = Integer.parseInt(heightStr);

//dp--px

height = getResources().getDimensionPixelSize(height);

}catch(ClassNotFoundException e) {

e.printStackTrace();

}catch(InstantiationException e) {

e.printStackTrace();

}catch(IllegalAccessException e) {

e.printStackTrace();

}catch(NoSuchFieldException e) {

e.printStackTrace();

}

returnheight;

}

@RequiresApi(api= Build.VERSION_CODES.JELLY_BEAN_MR1)

private boolean    haveNavgtion() {

//屏幕的高度  真实物理的屏幕

Display display = getWindowManager().getDefaultDisplay();

DisplayMetrics displayMetrics =newDisplayMetrics();

display.getRealMetrics(displayMetrics);

int    heightDisplay = displayMetrics.heightPixels;

//为了防止横屏

int     widthDisplay = displayMetrics.widthPixels;

DisplayMetrics contentDisplaymetrics =newDisplayMetrics();

display.getMetrics(contentDisplaymetrics);

int    contentDisplay = contentDisplaymetrics.heightPixels;

int    contentDisplayWidth = contentDisplaymetrics.widthPixels;

//屏幕内容高度  显示内容的屏幕

int    w = widthDisplay - contentDisplayWidth;

//哪一方大于0  就有导航栏

int     h = heightDisplay - contentDisplay;

return   w >0|| h >0;

}

private int   getStatusHeight() {

int   height = -1;

try{

Class clazz = Class.forName("com.android.internal.R$dimen");

Object object = clazz.newInstance();

String heightStr = clazz.getField("status_bar_height").get(object).toString();

height = Integer.parseInt(heightStr);

//dp--px

height = getResources().getDimensionPixelSize(height);

}catch(ClassNotFoundException e) {

e.printStackTrace();

}catch(InstantiationException e) {

e.printStackTrace();

}catch(IllegalAccessException e) {

e.printStackTrace();

}catch(NoSuchFieldException e) {

e.printStackTrace();

}

return  height;

}

}



palette的介绍到此结束,应用效果如下

图片发自简书App
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容