0 获得返回按钮的图标
出于一个很蠢的原因需要这个返回按钮的图标。
起初,想法是获取这个图标的Drawable对象或者Bitmap对象,把它存到手机SD卡中,取出来。
1 企图将返回键图标存到SD卡
1.1 取得Drawable对象
查看源码后发现,可以取得它的Drawable对象:
intTypedArray a = TintTypedArray.obtainStyledAttributes(this,
null, android.support.v7.appcompat.R.styleable.ActionBar, android.support.v7.appcompat.R.attr.actionBarStyle, 0);
Drawable drawable = a.getDrawable(android.support.v7.appcompat.R.styleable.ActionBar_homeAsUpIndicator);
已知有Bitmap存到本地SD卡的方法:
private static void save(Context context, File appDir, Bitmap bmp){
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
Toast.makeText(context,"保存成功!",Toast.LENGTH_SHORT).show();
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
现在只需要将这个Drawable转换为Bitmap的办法就能完成了。
1.2 寻找Drawable转换为Bitmap的办法
在网上搜寻的过程中发现一个看上去还算靠谱的办法:
/**
* Drawable 转 bitmap
* @param drawable
* @return
*/
public static Bitmap drawable2Bitmap(Drawable drawable){
if(drawable instanceof BitmapDrawable){
return ((BitmapDrawable)drawable).getBitmap() ;
}else if(drawable instanceof NinePatchDrawable){
Bitmap bitmap = Bitmap
.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}else{
return null ;
}
}
但是这个方法有点问题。看它的意思是只能转BitmapDrawable和NinePatchDrawable类型的Drawable对象为Bitmap对象。我抱着试一试的态度进行了尝试,果然我取得的返回按钮的Drawable对象并不是这两种类型。
本来想继续找找Drawable转Bitmap的其他方法,直到看到这个,就觉得没戏了。
不愿意点链接的,我就简述一下:
A bitmap is a Drawable. A Drawable is not necessarily a bitmap. Like all thumbs are fingers but not all fingers are thumbs.
Bitmap是Drawable . Drawable不一定是Bitmap .就像拇指是指头,但不是所有的指头都是拇指一样.
上面这篇文章了也就说到这两种Drawable可以转为Bitmap。
线索看上去断了。但是我有又想到,既然能取到对象,那就直接使用就好了,反正ImageView可以setImageDrawable(Drawable drawable)。
2 直接使用获得的Drawable对象
2.1 不试试怎么知道
先用Toast弹出来看看
final TintTypedArray a = TintTypedArray.obtainStyledAttributes(this,
null, android.support.v7.appcompat.R.styleable.ActionBar, android.support.v7.appcompat.R.attr.actionBarStyle, 0);
Drawable drawable = a.getDrawable(android.support.v7.appcompat.R.styleable.ActionBar_homeAsUpIndicator);
ImageView imageView = new ImageView(this);
imageView.setImageDrawable(drawable);
imageView.setDrawingCacheEnabled(true);
Toast toast = new Toast(this);
toast.setView(imageView);
toast.setDuration(Toast.LENGTH_SHORT);
toast.show();
如果没看到的话,有两种可能:1 Toast没弹;2 没取到Drawable;可能1可以通过设置图文并存的Toast来解决(看不到图片,我还看不到文字不成?)
LinearLayout ll = new LinearLayout(this);
ImageView iv = new ImageView(this);
iv.setImageDrawable(drawable);
TextView tv = new TextView(this);
tv.setText("123");
ll.addView(iv);
ll.addView(tv);
//设置要显示的内容
toast.setView(ll);
2.2 那就设置上去看看
结果试着设置上去:
刚才Toast显示时间短,没特别注意。但是现在,你看那颜色啊!我要白色啊!!!
好像又到了一个卡壳点。不过好像只要能设置这个图标的颜色就行了。然后去查Drawable设置颜色。。。。
2.3 意外发现
反正Drawable没有直接设置颜色的方法。反倒是找到一个GradientDrawable有一个setColor的方法。但是……我取下来的这个Drawable会是这个类型吗?
折腾ing……
事实证明,并不是啊!
Caused by: java.lang.ClassCastException:
android.graphics.drawable.VectorDrawable cannot be cast to android.graphics.drawable.GradientDrawable
虽然并不是,但是起码让我知道了这是个VectorDrawable啊。不过想想也对,Toolbar支持v21及以上,一起发布的还有VectorDrawable,矢量图标。想来也是极有道理的。
那么接下来就是找VectorDrawable设置颜色的方法咯~~
2.4 是不是忘了什么?
找来找去也没找到类似的方法。
百无聊赖的我又去找父类Drawable的方法,找到一个setColorFilter的方法,也不知道有什么用。一查才知道,我要找的还真的就是这个方法。这叫啥?远在天边,近在眼前啊。
最后只需要这样,就可以了:
TintTypedArray a = TintTypedArray.obtainStyledAttributes(this,
null, android.support.v7.appcompat.R.styleable.ActionBar, android.support.v7.appcompat.R.attr.actionBarStyle, 0);
Drawable drawable = a.getDrawable(android.support.v7.appcompat.R.styleable.ActionBar_homeAsUpIndicator);
drawable.setColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY);
imageView.setImageDrawable(drawable);
3 效果图
以假乱真。啊哈哈哈~