SeekBar:从 Drawable 获取空位图,直到将其设置为 ImageView 或如何从 9patch 获取结果位图

Posted

技术标签:

【中文标题】SeekBar:从 Drawable 获取空位图,直到将其设置为 ImageView 或如何从 9patch 获取结果位图【英文标题】:SeekBar: getting empty bitmap from Drawable until set it to ImageView OR how to get resulting Bitmap from 9patch 【发布时间】:2015-03-01 16:56:05 【问题描述】:

所以我想将一个从drawable 创建的位图设置为SeekBar 的进度。我做到了:

    Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Drawable drawable = getResources().getDrawable(R.drawable.seekbar_bg_full);
    Canvas canvas = new Canvas(bmp);
    drawable.setBounds(0, 0, width, height);
    drawable.draw(canvas); // I assume here drawable must be drawn but its not
    // canvas.drawBitmap(bmp, 0 , 0, null); // does nothing as 4 me
    // encode/decode to detach bitmap from 9patch
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bmp.compress(CompressFormat.PNG, 0, baos);
    final byte[] bytes = baos.toByteArray();
    bmp.recycle();
    bmp = BitmapFactory.decodeByteArray(bytes,0,bytes.length);
    // ClipDrawable is intented to be used as progressDrawable in SeekBar
    ClipDrawable progressDrawable = new ClipDrawable(new BitmapDrawable(getResources(),bmp), Gravity.LEFT, ClipDrawable.HORIZONTAL);
    // if not set this drawable to an ImageView then no progress will be shown by SeekBar at all
    //ImageView imgFake = (ImageView) findViewById(R.id.fakeImageView);
    //imgFake.setImageDrawable(progressDrawable);
    mySeekBar.setProgressDrawable(progressDrawable);

widthheight 是此处的有效值(如 460 和 30)。如您所见,注释了关于ImageView 的两行代码。这个ImageView 保留在布局上,它的可见性是不可见的。如果我像显示的那样评论这 2 行,那么将没有可见的进度,例如 drawable 是空的或透明的。看起来像这样 ImageView 使 drawable 真正绘制自己。但我不喜欢使用假的ImageView 只是为了让“魔术”发生,所以问题是 - 如何在没有这个假的ImageView 的情况下使其工作。 请不要建议我如何正确设置SeekBar 进度,例如:

ClipDrawable progressDrawable = new ClipDrawable(getResources().getDrawable(R.drawable.seekbar_bg_full), Gravity.LEFT, ClipDrawable.HORIZONTAL);
mySeekBar.setProgressDrawable(progressDrawable);

或 xml 选择器方式或任何替代方式,因为我已经知道它并且我的问题并不是真的关于它。我只需要让它按我的方式工作。 我只需要制作我的位图或画布或任何真正绘制的东西。 如果您愿意,可以提供更多详细信息(可选阅读)。问题是关于可绘制的seekbar_bg_full - 它是一个 9-patch png。所有需要的是获得一个非 NinePatchDrawable 链接的结果位图。假设我有一个 460x30px 的视图,其中 9patch 图像设置为 src 或背景,并且 9patch 图像被拉伸,就像它应该做的那样。所以我需要得到一个这个视图包含的位图,这个位图不应该以某种方式链接到 9patch。这就是为什么我将位图编码为字节数组,然后将其解码回来——它只是为了摆脱 9patch。如果有更简单的方法可以从 9patch(NinePatchDrawable 周围的一些魔法)获取生成的位图 - 我想知道。

【问题讨论】:

【参考方案1】:

好的,我想出了如何摆脱假 ImageView 并让 drawable 自己绘制:我所要做的就是在 drawable 上调用 setBounds() 方法:

ClipDrawable progressDrawable = new ClipDrawable(new BitmapDrawable(getResources(),bmp), Gravity.LEFT, ClipDrawable.HORIZONTAL);
progressDrawable.setBounds(0, 0, width, height);
mySeekBar.setProgressDrawable(progressDrawable);

现在我终于不用使用 ImageView了! 然而,我的代码是一个非常长的故事,以摆脱 drawable 中的 9patch 功能。

【讨论】:

以上是关于SeekBar:从 Drawable 获取空位图,直到将其设置为 ImageView 或如何从 9patch 获取结果位图的主要内容,如果未能解决你的问题,请参考以下文章

一起Talk Android吧(第四百六十一回:再谈从drawable中获取Bitmap)

SeekBar源码分析

android studio怎么修改seekbar样式

androd中怎么替换android seekbar 刻度的系统滑块图标

android seekbar 4.0样式 怎么出来2.3

带文字的seekbar : 自定义progressDrawable/thumb :解决显示不全