如何将Android一个Activity的ImageView图片设为另一个Activity背景?
如何将一个Activity的背景设置为另一个Activity中ImageView的图片
我开发的Android应用包含两个Activity,希望将其中一个Activity的背景设置为另一个Activity内ImageView展示的图片,尝试实现但未达预期效果,以下是我的代码,请帮忙审核并指导正确实现方式:
获取ImageView的Activity(GallerySaver)代码:
using Android.App; using Android.Content; using Android.OS; using Android.Provider; using Android.Runtime; using Android.Views; using Android.Widget; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using Android.Graphics; using SQLite; namespace HAMANIA_APP { [Activity(Label = "GallerySaver")] public class GallerySaver : Activity { Button camera, save, uploadPhoto; ImageView pic; Bitmap bitmap; bool mExternalStorageAvailable = false; bool mExternalStorageWriteable = false; public static readonly int imageid = 1000; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Phone_Gallery_Saver); camera = FindViewById<Button>(Resource.Id.btnCamera); save = FindViewById<Button>(Resource.Id.btnSave); pic = FindViewById<ImageView>(Resource.Id.gallery); save.Click += Save_Click; camera.Click += Camera_Click; // Create your application here } private void Save_Click(object sender, EventArgs e) { Intent inte = new Intent(); inte.SetType("image/*"); inte.SetAction(Intent.ActionGetContent); StartActivityForResult(Intent.CreateChooser(inte, "Select Picture"), imageid); Toast.MakeText(Application.Context, "Image saved to gallery", ToastLength.Long).Show(); } private void Camera_Click(object sender, EventArgs e) { Intent intent = new Intent(MediaStore.ActionImageCapture); StartActivityForResult(intent, 0); } protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == 0)//coming from camera { if (resultCode == Result.Ok) { Bundle extras = data.Extras; bitmap = (Bitmap)extras.Get("data"); pic.SetImageBitmap(bitmap); //bitmap = (Android.Graphics.Bitmap)data.Extras.Get("data"); // pic.SetImageBitmap(bitmap); } }else { if ((requestCode == imageid) && (resultCode == Result.Ok) && (data != null)) { Android.Net.Uri uri = data.Data; bitmap = MediaStore.Images.Media.GetBitmap(ContentResolver, uri); pic.SetImageBitmap(bitmap); var image = (Bitmap)data.Extras.Get("data"); } } } } }
需要设置背景的Activity(MenuActivity)代码:
using Android.App; using Android.Content; using Android.Graphics; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using System; using System.Collections.Generic; using System.Linq; using System.Text; using Xamarin.Essentials; using Android.Provider; using Java.IO; using System.IO; using Android.Net; using AndroidX.Core.Content; using Android.Graphics.Drawables; namespace HAMANIA_APP { [Activity(Label = "MenuActivity")] public class MenuActivity : Activity { Button camera, gallery, control; BroadcastBattery broadcastBattery; TextView tv; protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Menu); camera = FindViewById<Button>(Resource.Id.BLUETOOTH); tv = FindViewById<TextView>(Resource.Id.tv); broadcastBattery = new BroadcastBattery(tv); control = FindViewById<Button>(Resource.Id.control); control.Click += Control_Click; gallery = FindViewById<Button>(Resource.Id.gallery); camera.Click += Camera_Click; } public static string BackgroundImagePath { get; set; } private void Control_Click(object sender, EventArgs e) { Intent intent = new Intent(this, typeof(ControlCenter)); StartActivity(intent); } private void Camera_Click(object sender, EventArgs e) { Intent intent2 = new Intent(this, typeof(GallerySaver)); StartActivity(intent2); } } }
正确实现方案
核心思路是将GallerySaver中选中/拍摄的图片传递给MenuActivity,推荐使用保存图片到应用私有目录+传递文件路径的方式,避免Bitmap直接传递的内存限制问题,具体步骤如下:
1. 改造GallerySaver,保存图片并返回路径
在GallerySaver类中添加保存Bitmap到本地的方法:
// 保存Bitmap到应用私有图片目录 private string SaveBitmapToFile(Bitmap bitmap) { var dir = Application.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures); if (!dir.Exists) dir.Mkdirs(); var fileName = $"bg_{DateTime.Now.Ticks}.png"; var filePath = Path.Combine(dir.AbsolutePath, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream); stream.Flush(); } return filePath; }
修改OnActivityResult方法,在设置ImageView后保存图片并将路径返回给MenuActivity:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); string imagePath = null; if (requestCode == 0)// 相机返回 { if (resultCode == Result.Ok) { Bundle extras = data.Extras; bitmap = (Bitmap)extras.Get("data"); pic.SetImageBitmap(bitmap); imagePath = SaveBitmapToFile(bitmap); } } else if ((requestCode == imageid) && (resultCode == Result.Ok) && (data != null))// 相册返回 { Android.Net.Uri uri = data.Data; bitmap = MediaStore.Images.Media.GetBitmap(ContentResolver, uri); pic.SetImageBitmap(bitmap); imagePath = SaveBitmapToFile(bitmap); } // 返回路径给MenuActivity if (!string.IsNullOrEmpty(imagePath)) { Intent resultIntent = new Intent(); resultIntent.PutExtra("BackgroundPath", imagePath); SetResult(Result.Ok, resultIntent); Finish(); // 关闭当前Activity回到MenuActivity } }
2. 改造MenuActivity,接收路径并设置背景
修改MenuActivity中启动GallerySaver的方式,改用StartActivityForResult:
private void Camera_Click(object sender, EventArgs e) { Intent intent2 = new Intent(this, typeof(GallerySaver)); StartActivityForResult(intent2, 1001); // 自定义请求码 }
重写OnActivityResult接收路径并设置背景:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); if (requestCode == 1001 && resultCode == Result.Ok && data != null) { string imagePath = data.GetStringExtra("BackgroundPath"); if (!string.IsNullOrEmpty(imagePath)) { Bitmap bitmap = BitmapFactory.DecodeFile(imagePath); Drawable background = new BitmapDrawable(Resources, bitmap); Window.DecorView.SetBackground(background); // 保存路径,下次启动自动加载 BackgroundImagePath = imagePath; } } }
如果需要启动时自动加载上次设置的背景,在OnCreate中添加:
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Menu); // ... 原有初始化代码 // 加载保存的背景 if (!string.IsNullOrEmpty(BackgroundImagePath)) { Bitmap bitmap = BitmapFactory.DecodeFile(BackgroundImagePath); if (bitmap != null) { Drawable background = new BitmapDrawable(Resources, bitmap); Window.DecorView.SetBackground(background); } } }
注意事项
- 相机默认返回的是缩略图,若需要原图,建议通过指定文件路径的方式调用相机。
- 使用应用私有存储目录无需申请外部存储权限,适配Android 10+的权限规则。
- 处理完Bitmap后可调用
bitmap.Recycle()释放内存,避免泄漏。
内容的提问来源于stack exchange,提问作者Rom Yannay
相关产品推荐
相关产品推荐

