【踩坑】如何获得Toolbar上原生的返回按钮

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 效果图

这里写图片描述
这里写图片描述

以假乱真。啊哈哈哈~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值