【问题标题】:Programmatically setting ImageView resource not working以编程方式设置 ImageView 资源不起作用
【发布时间】:2019-11-11 14:05:54
【问题描述】:

我正在尝试实现一个功能,用户可以从存储中选择图像文件,并且该图像显示在缩略图大小的 ImageView 中。

文件选择部分似乎是正确的:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, GET_ATTACHMENT_RESULT); 

//...

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == GET_ATTACHMENT_RESULT){
        if (resultCode == RESULT_CANCELED){
            // Anything TODO here?
        } else if (resultCode == RESULT_OK){
            Uri uri = data.getData();

            addTimeFragment.onImageUrlReceived(uri);
        }
    }
}

返回的 Uri 似乎是一个内容 Uri,并且具有如下路径:

content://com.android.providers.media.documents/document/image%3A14702

调用 uri.getPath() 返回:

/document/image:14702

我尝试了许多不同的解决方案,这些解决方案在涉及 Picasso 的大量 Stack Overflow 帖子中找到(理想解决方案)、从各种方法创建位图、设置 ImageView Uri 等......

没有设置 ImageView 资源的编程方法有效 - 即使在位于我的可绘制对象中的 PNG 上也是如此。我只能在 XML 中成功设置 android:src

完整性检查:

  • ImageView 是可见的,被正确约束,并且具有适当的高度和宽度。
  • 我可以在 xml 中设置一个源图像,它就会出现。我还设置了背景颜色以确保它在屏幕上。 XML 中的一切都很好。
  • 我还可以成功地以编程方式设置 ImageView 背景颜色,因此我知道我在代码中引用了正确的 ImageView。

XML:

<ImageView
    android:id="@+id/thumbnail"
    android:layout_width="48dp"
    android:layout_height="48dp"
    app:layout_constraintTop_toBottomOf="@id/time_entry_spacer"
    app:layout_constraintStart_toStartOf="@id/camera_bg"
    android:layout_marginBottom="4dp"
    android:layout_marginStart="6dp"
    android:background="#220000FF"/> 

分配 ImageView:

//attachThumbnail is my ImageView
attachThumbnail = getActivity().findViewById(R.id.thumbnail);
attachThumbnail.setBackgroundColor(context.getResources().getColor(R.color.colorAccent));  // This works as a sanity check

onImageUrlReceived 方法的各种失败:

public void onImageUrlReceived(Uri uri){
        Log.d(APP_TAG, "URI: " + uri.toString());
        Log.d(APP_TAG, "URI: " + uri.getPath());

// Even loading a known drawable fails
// Picasso.with(context).load(R.drawable.calendar).fit().error(R.drawable.error).into(attachThumbnail);


// Picasso.with(context).load(uri).fit().error(R.drawable.error).into(attachThumbnail);


// Picasso.with(context).load(uri.getPath()).fit().error(R.drawable.error).into(attachThumbnail);


//        File imgFile = new  File(url);
//        if(imgFile.exists()){
//            Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
//
//            attachThumbnail.setImageBitmap(myBitmap);
//        }


//        attachThumbnail.setImageURI(uri);


//        Bitmap bitmap = null;
//        try {
//            bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        attachThumbnail.setImageBitmap(bitmap);


//        Bitmap b = BitmapFactory.decodeFile(uri.getPath());
//        attachThumbnail.setImageBitmap(b);


// See DownloadImage AsyncTask below
//        new DownloadImage(attachThumbnail).execute(uri.getPath());


// InputStream with scaling
//        try {
//            InputStream ims = getActivity().getContentResolver().openInputStream(uri);
//            Bitmap b = BitmapFactory.decodeStream(ims);
//            Bitmap b2 = Bitmap.createScaledBitmap(b, 50, 50, false);
//            attachThumbnail.setImageBitmap(b2);
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }


// InputStream without Scaling
//        Bitmap bitmap = null;
//        try {
//            bitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(uri));
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        }
//        attachThumbnail.setImageBitmap(bitmap);
    }

    public class DownloadImage extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImage(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap mIcon11 = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon11 = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.d("Error", e.getStackTrace().toString());

            }
            return mIcon11;
        }

        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }

这里的任何其他想法或见解非常感谢。我肯定在这个问题上撞到了墙上。

谢谢。

【问题讨论】:

  • 似乎从未调用过onImageUrlReceived(url)
  • @TaQuangTu 感谢您的评论。它在onActivityResult() 中调用。 onImageUrlReceived() 方法位于 Fragment 中。
  • 您是否尝试使用new DownloadImage(attachThumbnail).execute(uri.getPath()); 并得到不想要的结果?
  • 我确实尝试过。我想到了。我将在下面为遇到此问题的其他人留下答案。感谢您的努力@TaQuangTu

标签: java android image


【解决方案1】:

我发现了问题所在。

因为我的 ImageView 驻留在 Fragment 中,而不是直接在 Activity 中,所以我在 Fragment 上调用 onImageUrlReceived(Uri uri) 之前 onResume()onActivityResult 在 Fragment 恢复之前被调用。结果,ImageView 设置正确,但一瞬间,我在调用 onResume 时重新分配了 ImageView,因此看起来好像什么也没做。

因此,我现在将 Uri 作为 Fragment 成员存储在 onResume() 中:

attachThumbnail = getActivity().findViewById(R.id.thumbnail);

if (userAttachmentUri != null){
    Picasso.with(getContext()).load(userAttachmentUri).fit().into(attachThumbnail);
}```

【讨论】:

    猜你喜欢
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 2014-08-12
    相关资源
    最近更新 更多