最近有很多人问微信底部的变色卡片导航是怎么做的,我在网上看了好几个例子,都是效果接近,都存有一些差异,自己琢磨也做了一个,几乎99%的还原,效果还不错吧
仔细观察微信图片,发现他有两部分内容,外面的边框和里面的内容,内容的颜色由绿变为透明,这部分可以直接改变图片透明度,外面的边框,颜色在灰色和绿色之间变化,就不能简单的改变透明度了,ImageView的tint 为我们提供了可行方案,tint可以为图标着色,既可以在xml中,也可以在代码中设置,一共有16种颜色混合模式,分别为
按照我的理解简单解释下这16种模式,有两张图片,一张dst 目标图标,可以看做底部的背景,一张 src图片,可以看做上面的内容,clear:在底部中清除内容所在的区域,srcover:内容覆盖在背景之上,DstOver:背景覆盖在内容之上,SrcIn:显示src和dst相交的src区域,dstin:显示相交的dst区域,SrcOut:显示不相交的src区域,DstOut:显示不相交的Dst区域,SrcAtTop:显示dst所在的区域,相交区域显示Src,DstAtTop:显示src所在区域,相交区域显示Dst,Xor:异或,相交区域不显示,其他区域保留,darken,src覆盖在在dst之上,相交区域src以最暗显示,lighten:src覆盖在dst之上,相交区域src以最亮显示,Multiply:显示相交区域的混合,Screen:显示全部区域,相交区域以全色显示,即白色
在xml中设置:直接添加tint属性,选择tintMode模式
<ImageView
android:id="@+id/green"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@mipmap/green"
android:tint="@color/colorPrimary"
android:tintMode="src_in"/>
在java代码中设置
mGreenImageView.setColorFilter(color,mode) mode参数类型 PorterDuff.Mode
为了理解不同颜色,不同透明度的图片在设置不同tint模式、不同的颜色后的变化,写了一个demo,四个滑动条分别代表了颜色的alpha,R、G、B值,改变滑动位置,通过Color.argb(alpha,red,green,blue)动态组合出不同的颜色,通过Spinner选择不同的模式,给图像设置不同的模式和不同的tint颜色,展示不同的效果,观察结果,可以看到给imageview设置tint后,图标最后展示出来的颜色不仅和设置的模式相关,还和图像的原有颜色和透明度相关。具体是怎样的相关性,语言描述不清,请自行体会。
选了实心绿,透明白,实心紫红的三张图片进行测试验证
界面很简单,只是一些基本的控件,代码如下
public class SimpleActivity extends Activity {
private ImageView mGreenImageView;
private ImageView mTransparentImageView;
private ImageView mRedImageView;
//透明度滑动条
private SeekBar mTransparentSeekBar;
private Spinner mSpinner;
//红色滑动条
private SeekBar mRedSeekBar;
//绿色滑动条
private SeekBar mGreenSeekBar;
//蓝色滑动条
private SeekBar mBlueSeekBar;
private TextView mTextView;
private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener; //滑动条监听器
//PorterDuff.Mode 列表
private static final PorterDuff.Mode[] MODES = new PorterDuff.Mode[]{
PorterDuff.Mode.ADD,
PorterDuff.Mode.CLEAR,
PorterDuff.Mode.DARKEN,
PorterDuff.Mode.DST,
PorterDuff.Mode.DST_ATOP,
PorterDuff.Mode.DST_IN,
PorterDuff.Mode.DST_OUT,
PorterDuff.Mode.DST_OVER,
PorterDuff.Mode.LIGHTEN,
PorterDuff.Mode.MULTIPLY,
PorterDuff.Mode.OVERLAY,
PorterDuff.Mode.SCREEN,
PorterDuff.Mode.SRC,
PorterDuff.Mode.SRC_ATOP,
PorterDuff.Mode.SRC_IN,
PorterDuff.Mode.SRC_OUT,
PorterDuff.Mode.SRC_OVER,
PorterDuff.Mode.XOR
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple);
mGreenImageView = (ImageView) findViewById(R.id.green);
mTransparentImageView= (ImageView) findViewById(R.id.transparent);
mRedImageView= (ImageView) findViewById(R.id.red);
mTextView= (TextView) findViewById(R.id.text);
mTransparentSeekBar = (SeekBar) findViewById(R.id.alpha_seekbar);
mRedSeekBar= (SeekBar) findViewById(R.id.red_seekbar);
mGreenSeekBar= (SeekBar) findViewById(R.id.green_seekbar);
mBlueSeekBar= (SeekBar) findViewById(R.id.blue_seekbar);
mSpinner= (Spinner) findViewById(R.id.spinner);
SpinnerAdapter spinnerAdapter=ArrayAdapter.createFromResource(SimpleActivity.this,R.array.blend_modes, android.R.layout.simple_list_item_1);
mSpinner.setAdapter(