【问题标题】:Load image into layer-list programatically以编程方式将图像加载到图层列表中
【发布时间】:2016-07-02 10:47:28
【问题描述】:

我正在尝试以编程方式将图像加载到图层列表中。我找到了一些解决方案,但不知何故它不起作用。这是我所做的:

layer_list.xml:(设置为RelativeLayout的背景)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/red" />
    <item
        android:id="@+id/replace"
        android:drawable="@drawable/placeholder" />
    <item
        android:bottom="-250dp"
        android:left="0dp"
        android:right="-250dp"
        android:top="250dp">
        <rotate
            android:fromDegrees="-10"
            android:pivotX="0%"
            android:pivotY="100%">
            <shape android:shape="rectangle">
                <solid android:color="@color/white" />
            </shape>
        </rotate>
    </item>
</layer-list>

将位图加载到图层列表的代码:

Drawable drawable = new BitmapDrawable(getResources(), bitmap);
LayerDrawable layerDrawable = (LayerDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.layer_list, null);
layerDrawable.setDrawableByLayerId(R.id.replace, drawable);

但不知何故,占位符图像永远不会被新的位图替换。我在这里做错了什么?

编辑:这是我加载图像的方式:

    private void loadImageIntoLayerList(Context context, String url) {
    // To get image using Fresco
    ImageRequest imageRequest = ImageRequestBuilder
            .newBuilderWithSource(Uri.parse(url))
            .setProgressiveRenderingEnabled(true)
            .build();

    ImagePipeline imagePipeline = Fresco.getImagePipeline();
    DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline
            .fetchDecodedImage(imageRequest, context);

    BaseBitmapDataSubscriber dataSubscriber = new BaseBitmapDataSubscriber() {
        @Override
        public void onNewResultImpl(@Nullable Bitmap bitmap) {
            // You can use the bitmap in only limited ways
            // No need to do any cleanup.
            if (bitmap != null) {
                Drawable drawable = new BitmapDrawable(getResources(), bmp);
                LayerDrawable layerDrawable = (LayerDrawable) ResourcesCompat.getDrawable
                        (getResources(), R.drawable.layer_list, null);
                if (layerDrawable != null) {
                    layerDrawable.setDrawableByLayerId(R.id.cover_image, drawable);
                    header.setBackground(layerDrawable);
                }
            }
        }

        @Override
        public void onFailureImpl(DataSource dataSource) {
            // No cleanup required here.
        }
    };
    dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance());

【问题讨论】:

  • stackoverflow.com/questions/8018435/…你看过这篇文章了吗?
  • 也许将 android:drawable="@drawable/placeholder" 替换为 并在您的代码中,将位图替换为: layerDrawable.draw(new画布(位图))
  • 两个都试过了,drawable还是没有被替换...
  • 将最后一行修改为 boolean check = layerDrawable.setDrawableByLayerId(R.id.replace, drawable);看看这部分代码是否有问题
  • 当记录检查它没有返回任何东西。

标签: android


【解决方案1】:

在末尾添加以下行:

myRelativeLayout.setBackground(layerDrawable);

看来您需要在更改可绘制对象后再次设置背景。

这是工作代码:

public class TestActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    final RelativeLayout RL = (RelativeLayout) findViewById(R.id.RL);
    Button btn = (Button) findViewById(R.id.btn);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.image7, null);
            LayerDrawable layerDrawable = (LayerDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.layer_list, null);
            layerDrawable.setDrawableByLayerId(R.id.replace, drawable);
            RL.setBackground(layerDrawable);

        }
    });
}
}

layer_list.xml 和你的一样,只是有不同的drawables。 activity_test.xml 只是一个RelativeLayout,中间有一个按钮。

【讨论】:

  • 你如何命名你的可绘制“图层列表”?名称中不得使用“-”。也许那是你的问题?因为我使用与您相同的代码,带有一个名为“layer_list”的可绘制对象,而我的现在正在工作。这个图片替换码怎么称呼?
  • 这是一个带下划线的名称,没有破折号。我正在使用 Fresco 图像管道从图像 url 中获取位图,并在回调中进行图像替换。
  • 所以首先尝试一些更简单的方法:在您的屏幕上添加一个简单的 RelativeLayout,然后使用您收到的位图简单地更改其背景。如果那行得通,那么您的位图就可以了。我将使用我拥有的工作代码编辑我的答案,因此您可以对其进行修改以解决问题。
  • 我添加了图片加载和替换的代码
  • 从未使用过 Fresco,因此无法再提供任何帮助。请注意,一旦我重新设置背景,我的工作代码就开始工作了。所以尝试解决这个问题。祝你好运。
【解决方案2】:

您不能为此使用在BaseBitmapDataSubscriber.onNewResultImpl(Bitmap) 中获得的位图。 如果您查看此方法的 Javadoc,您会看到 Bitmap 的内存将在不久之后被释放。

如果您直接在布局中使用SimpleDraweeView 会更好。它支持叠加层、背景和占位符,因此它可以为您处理一切。 您可以将图层列表拆分为单独的可绘制对象,例如背景和覆盖,并在 XML 或代码中设置它。 然后你可以通过draweeView.setImageURI(...) 来加载你的图片。

您也可以通过implement a custom view 获取可绘制对象(例如,将其设置为背景,因为您可以根据自定义视图指南使用Drawable drawable = mDraweeHolder.getTopLevelDrawable(); 获取可绘制对象本身)。

如果你真的要直接使用 imagepipeline,你还必须正确处理 Bitmap 的生命周期。你得到一个位图的CloseableReference,你必须手动释放它。 查看http://frescolib.org/docs/using-image-pipeline.html 了解更多信息。您还可以查看 PipelineDraweeControllerAbstractDraweeController 之类的类,了解如何实现(使用 SimpleDraweeView 时会发生这种情况)。

【讨论】:

    猜你喜欢
    • 2016-11-03
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多