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