Android将不显示的layout保存成图片,不需要setDrawingCacheEnabled

import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
 


object SaveBackgroundViewToImageUtil {

    private var mBitmapDoneListener: BitmapDoneListener? = null

    /**
     * view转bitmap
     *
     * @param v View
     * @return Bitmap
     */
    private fun viewConversionBitmap(v: View): Bitmap {
        val w = v.width
        val h = v.height
        Log.e("SaveImage", "width: $w height: $h")
        val bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        val c = Canvas(bmp)
        c.drawColor(Color.WHITE)
        /** 如果不设置canvas画布为白色,则生成透明  */
        v.layout(0, 0, w, h)
        v.draw(c)
        return bmp
    }

    fun createBitmap3(activity: Activity, listener: BitmapDoneListener): Bitmap? {

        mBitmapDoneListener = listener
        //将布局转化成view对象
        val v: View = LayoutInflater.from(activity).inflate(R.layout.layout_save_image_by_h5, null, false)

        val width = ScreenUtil.getWidthPixels()
        val height = ScreenUtil.getHeightPixels()

        //测量使得view指定大小
        val measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY)
        val measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
        v.measure(measuredWidth, measuredHeight)
        //调用layout方法布局后,可以得到view的尺寸大小
        v.layout(0, 0, v.measuredWidth, v.measuredHeight)

        val bmp = Bitmap.createBitmap(v.width, v.height, Bitmap.Config.ARGB_8888)
        val c = Canvas(bmp)
        c.drawColor(Color.WHITE)
        v.draw(c)

        if (mBitmapDoneListener != null) {
            mBitmapDoneListener?.bitmapDone(bmp);
        }
        return bmp
    }


    /**
     * 计算view的大小
     */
    fun onSave(url: String?, title: String, activity: Activity, listener: BitmapDoneListener) {
        this.mBitmapDoneListener = listener
        //将布局转化成view对象
        val viewBitmap: View = LayoutInflater.from(activity).inflate(R.layout.layout_save_image_by_h5, null, false)

        val width = ScreenUtil.getWidthPixels()
        val height = ScreenUtil.getHeightPixels()

        //然后View和其内部的子View都具有了实际大小,也就是完成了布局,相当与添加到了界面上。接着就可以创建位图并在上面绘制了:
        layoutView(viewBitmap, width, height, url, title, activity)
    }

    /**
     * 填充布局内容
     */
    fun layoutView(viewBitmap: View, width: Int, height: Int, url: String?, title: String?, context: Context?) {
        // 整个View的大小 参数是左上角 和右下角的坐标
        val measuredWidth: Int = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY)
        val measuredHeight: Int = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY)
        viewBitmap.measure(measuredWidth, measuredHeight)
        viewBitmap.layout(0, 0, viewBitmap.getMeasuredWidth(), viewBitmap.getMeasuredHeight())

        val tv: TextView = viewBitmap.findViewById(R.id.tv_title)
        tv.setText(title)
        val imageView: ImageView = viewBitmap.findViewById(R.id.iv_qrCode)

        //注意加载网络图片时一定要用SimpleTarget回调
        Glide.with(context!!).asBitmap().load(url).into(object : SimpleTarget<Bitmap?>() {
            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap?>?) {
                imageView.setImageBitmap(resource)
                viewSaveToImage(viewBitmap)
            }
        })
    }

    /**
     * 把view转成图片
     *
     * @param view
     */
    private fun viewSaveToImage(view: View): Bitmap? {
        // 把一个View转换成图片
        var cachebmp = viewToBitmap(view);
        if (mBitmapDoneListener != null) {
            mBitmapDoneListener?.bitmapDone(cachebmp);
        }
        return cachebmp;
    }


    /**
     * view转bitmap
     */
    private fun viewToBitmap(v: View): Bitmap? {
        val w = v.width
        val h = v.height
        if (w <= 0 || h <= 0) {
            Log.e("xx", "viewToBitmap")
            return null;
        }

        val bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        val c = Canvas(bmp)
        c.drawColor(Color.WHITE)
        /** 如果不设置canvas画布为白色,则生成透明  */
        v.layout(0, 0, w, h)
        v.draw(c)
        return bmp
    }

    interface BitmapDoneListener {
        fun bitmapDone(bitmap: Bitmap?)
    }
}

参考:https://www.cnblogs.com/taixiang/p/9575195.html

网上大都说先layout后,再setDrawingCacheEnabled,可我那样实现保存的图片为空白。

<think> 我们正在回答用户的问题:"我想了解在Android活动页面显示图片的方法" 根据提供的引用,我们可以总结出几种在Android活动中显示图片的方法: 方法1:通过布局文件设置背景图片(引用[2]) - 在XML布局文件中,使用`android:background`属性为View或布局设置背景图片 - 示例:`android:background="@drawable/ic_launcher"`,其中ic_launcher是放在drawable目录下的图片 方法2:通过ImageView控件显示图片 - 在布局文件中添加ImageView控件,然后通过代码或XML设置图片资源 - XML中:`android:src="@drawable/my_image"` - 代码中:`imageView.setImageResource(R.drawable.my_image);` 方法3:将布局转换为图片(引用[1]) - 通过开启View的绘图缓存,将布局保存为Bitmap,然后显示在ImageView中 - 步骤: 1. 设置View启用绘图缓存:`view.setDrawingCacheEnabled(true);` 2. 获取绘图缓存:`Bitmap bitmap = view.getDrawingCache();` 3. 将bitmap设置给ImageView显示 方法4:从网络加载图片(需要网络权限和异步加载) - 使用Glide、Picasso等第三方库 - 示例(使用Glide): ```java Glide.with(context).load("http://example.com/image.jpg").into(imageView); ``` 此外,关于页面跳转(引用[3][4]): - 我们可以通过Intent实现页面跳转,跳转后的页面也可以展示图片 下面我们详细说明两种常用方法(XML设置和代码设置)的步骤: ### 方法一:通过XML布局文件设置图片(静态设置) 步骤: 1. 将图片资源(如jpg, png)放入`res/drawable`目录(注意:同分辨率可以放入对应的drawable目录,如drawable-hdpi) 2. 在布局文件中,为某个View(如ImageView或布局)设置图片 示例(ImageView): ```xml <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/my_image" /> ``` 3. 在Activity的onCreate方法中加载布局 ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 假设布局文件名为activity_main.xml } ``` ### 方法二:通过Java/Kotlin代码动态设置图片 步骤: 1. 同样将图片放入drawable目录 2. 在布局文件中放置一个ImageView(但设置src属性) ```xml <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> ``` 3. 在Activity中获取ImageView并设置图片 ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView = findViewById(R.id.imageView); // 设置图片资源 imageView.setImageResource(R.drawable.my_image); } ``` ### 方法三:将布局转换为图片显示(引用[1]) 步骤: 1. 在布局中放置两个View:一个是要转换图片的布局(假设id为layoutToCapture),另一个是用于显示生成图片的ImageView(假设id为capturedImageView) 2. 在某个事件(例如按钮点击)中,将布局转换为Bitmap并显示在ImageView中 ```java // 假设layoutToCapture是我们要转换的布局 View layoutToCapture = findViewById(R.id.layoutToCapture); layoutToCapture.setDrawingCacheEnabled(true); layoutToCapture.buildDrawingCache(); // 确保绘图缓存被构建 Bitmap bitmap = Bitmap.createBitmap(layoutToCapture.getDrawingCache()); layoutToCapture.setDrawingCacheEnabled(false); // 禁用绘图缓存 ImageView capturedImageView = findViewById(R.id.capturedImageView); capturedImageView.setImageBitmap(bitmap); ``` ### 方法四:从网络加载图片 步骤(使用Glide库): 1. 在build.gradle中添加依赖:`implementation 'com.github.bumptech.glide:glide:4.12.0'` 2. 在布局中放置ImageView 3. 在代码中: ```java ImageView imageView = findViewById(R.id.imageView); String imageUrl = "http://example.com/image.jpg"; Glide.with(this).load(imageUrl).into(imageView); ``` 注意事项: - 需要网络权限:在AndroidManifest.xml中添加`<uses-permission android:name="android.permission.INTERNET" />` ### 总结 在Android活动页面中显示图片有多种方法,最常用的是通过ImageView控件加载本地图片资源,也可以通过代码将布局转换为图片显示,或者从网络加载图片。开发者可以根据实际需求选择合适的方法。 以下是一个完整的示例,展示在Activity中通过XML和代码两种方式显示图片: #### 布局文件(activity_main.xml) ```xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 方法1:XML中直接设置图片 --> <ImageView android:id="@+id/imageView1" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/ic_launcher" /> <!-- 方法2:留空,通过代码设置图片 --> <ImageView android:id="@+id/imageView2" android:layout_width="200dp" android:layout_height="200dp" /> <!-- 用于显示从布局转换的图片 --> <ImageView android:id="@+id/capturedImageView" android:layout_width="match_parent" android:layout_height="200dp" /> </LinearLayout> ``` #### Activity代码(MainActivity.java) ```java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 方法2:代码设置图片 ImageView imageView2 = findViewById(R.id.imageView2); imageView2.setImageResource(R.drawable.my_image); // 方法3:将整个布局转换为图片显示(这里转换的是整个Activity的根布局,实际中可能需要指定某个子布局) View rootView = getWindow().getDecorView().getRootView(); rootView.setDrawingCacheEnabled(true); rootView.buildDrawingCache(); Bitmap bitmap = Bitmap.createBitmap(rootView.getDrawingCache()); rootView.setDrawingCacheEnabled(false); ImageView capturedImageView = findViewById(R.id.capturedImageView); capturedImageView.setImageBitmap(bitmap); } } ``` 注意:上面的方法3中转换整个根布局可能会包含状态栏等,实际应用中可能需要指定特定的布局。 以上就是在Android活动页面显示图片的几种常用方法[^1][^2]。 §§相关问题§§ 1. 如何从Android设备的相册中选择图片显示在Activity中? 2. 在Android中如何压缩图片以避免内存溢出(OOM)? 3. 如何使用Glide库实现圆形图片图片裁剪? 4. 在Android中如何实现图片的异步加载? </think> ### Android活动页面显示图片的实现方法 在Android开发中,活动(Activity)页面显示图片主要通过以下四种方式实现: #### 1. XML布局文件设置背景图(引用[2]) ```xml <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/ic_launcher" > <!-- 其他控件 --> </LinearLayout> ``` **实现原理**: - 使用`android:background`属性直接设置根布局背景 - 图片资源需放在`res/drawable`目录下 - 支持JPG/PNG等常见图片格式[^2] #### 2. ImageView控件显示图片 ```xml <ImageView android:id="@+id/imageView" android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/sample_image" /> ``` **Java代码控制**: ```java ImageView imageView = findViewById(R.id.imageView); imageView.setImageResource(R.drawable.dynamic_image); // 动态切换图片 imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); // 图片缩放模式 ``` #### 3. 布局转图片显示(引用[1]) ```java // 开启视图缓存 view.setDrawingCacheEnabled(true); view.buildDrawingCache(); // 获取位图 Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache()); // 显示在ImageView imageView.setImageBitmap(bitmap); // 保存到本地 saveBitmapToFile(bitmap, "layout_snapshot.jpg"); ``` **适用场景**: - 将复杂布局转换为图片分享 - 生成视图快照上传服务器 - 实现页面截图功能[^1] #### 4. 页面跳转传图(引用[3][4]) **发送图片数据**: ```java Intent intent = new Intent(MainActivity.this, ImageActivity.class); intent.putExtra("image_res", R.drawable.target_image); startActivity(intent); ``` **接收显示图片**: ```java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image); ImageView iv = findViewById(R.id.imageView); int resId = getIntent().getIntExtra("image_res", 0); if(resId != 0) { iv.setImageResource(resId); } } ``` ### 关键注意事项 1. **图片优化**: - 大图需压缩避免OOM:`BitmapFactory.Options.inSampleSize` - 使用WebP格式减少体积 2. **内存管理**: ```java @Override protected void onDestroy() { super.onDestroy(); imageView.setImageDrawable(null); // 防止内存泄漏 } ``` 3. **分辨率适配**: - 提供多套资源:`drawable-hdpi`, `drawable-xhdpi`等 - 使用矢量图(SVG/VectorDrawable)适配同屏幕 4. **网络图片加载**: ```java // 使用Glide库示例 Glide.with(this) .load("https://example.com/image.jpg") .placeholder(R.drawable.loading) .into(imageView); ``` ### 性能优化建议 - 使用`RecyclerView`+`Glide`实现图片列表 - 启用硬件加速:`android:hardwareAccelerated="true"` - 异步加载:`AsyncTask`或`RxJava` - 缓存策略:内存缓存(LruCache)+磁盘缓存 以上方法可根据实际需求选择使用,简单图片展示推荐XML方式,动态内容推荐布局转位图,跨页面传图推荐Intent方式[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值