Android View ScrollView等转为BitMap包含不可见部分的解决办法

APP 0 883
00224176
00224176 版主 - APP 关注 2021年7月22日 15:42 编辑
<pre><code>package com.cfs.app.utils;<br> <br>import android.content.Context;<br>import android.content.Intent;<br>import android.graphics.Bitmap;<br>import android.graphics.Canvas;<br>import android.graphics.Color;<br>import android.graphics.Paint;<br>import android.graphics.drawable.ColorDrawable;<br>import android.graphics.drawable.Drawable;<br>import android.net.Uri;<br>import android.os.Environment;<br>import android.util.LruCache;<br>import android.view.View;<br>import android.widget.ListAdapter;<br>import android.widget.ListView;<br>import android.widget.ScrollView;<br>import android.widget.Toast;<br> <br>import androidx.recyclerview.widget.RecyclerView;<br> <br>import java.io.File;<br>import java.io.FileNotFoundException;<br>import java.io.FileOutputStream;<br>import java.io.IOException;<br>import java.util.ArrayList;<br>import java.util.List;<br> <br>public class SimpleUtils {<br> <br> /**<br> * 将 Bitmap 保存到SD卡<br> * @param context<br> * @param mybitmap<br> * @param name<br> * @return<br> */<br> public static boolean saveBitmapToSdCard(Context context, Bitmap mybitmap, String name){<br> boolean result = false;<br> //创建位图保存目录<br> String path = Environment.getExternalStorageDirectory() + "/1000ttt/";<br> File sd = new File(path);<br> if (!sd.exists()){<br> sd.mkdir();<br> }<br> <br> File file = new File(path+name+".jpg");<br> FileOutputStream fileOutputStream = null;<br> if (!file.exists()){<br> try {<br> // 判断SD卡是否存在,并且是否具有读写权限<br> if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){<br> fileOutputStream = new FileOutputStream(file);<br> mybitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream);<br> fileOutputStream.flush();<br> fileOutputStream.close();<br> <br> //update gallery<br> Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);<br> Uri uri = Uri.fromFile(file);<br> intent.setData(uri);<br> context.sendBroadcast(intent);<br> Toast.makeText(context, "保存成功", Toast.LENGTH_SHORT).show();<br> result = true;<br> }<br> else{<br> Toast.makeText(context, "不能读取到SD卡", Toast.LENGTH_SHORT).show();<br> }<br> <br> } catch (FileNotFoundException e) {<br> e.printStackTrace();<br> } catch (IOException e) {<br> e.printStackTrace();<br> }<br> }<br> return result;<br> }<br> <br> <br> /**<br> * 手动测量摆放View<br> * 对于手动 inflate 或者其他方式代码生成加载的View进行测量,避免该View无尺寸<br> * @param v<br> * @param width<br> * @param height<br> */<br> public static void layoutView(View v, int width, int height) {<br> // validate view.width and view.height<br> v.layout(0, 0, width, height);<br> int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);<br> int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);<br> <br> // validate view.measurewidth and view.measureheight<br> v.measure(measuredWidth, measuredHeight);<br> v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());<br> }<br> <br> <br> public static int px2dip(Context context, float pxValue) {<br> final float scale = context.getResources().getDisplayMetrics().density;<br> return (int) (pxValue / scale + 0.5f);<br> }<br> <br> <br> <br> /**<br> * 获取一个 View 的缓存视图<br> * (前提是这个View已经渲染完成显示在页面上)<br> * @param view<br> * @return<br> */<br> public static Bitmap getCacheBitmapFromView(View view) {<br> final boolean drawingCacheEnabled = true;<br> view.setDrawingCacheEnabled(drawingCacheEnabled);<br> view.buildDrawingCache(drawingCacheEnabled);<br> final Bitmap drawingCache = view.getDrawingCache();<br> Bitmap bitmap;<br> if (drawingCache != null) {<br> bitmap = Bitmap.createBitmap(drawingCache);<br> view.setDrawingCacheEnabled(false);<br> } else {<br> bitmap = null;<br> }<br> return bitmap;<br> }<br> <br> /**<br> * 对ScrollView进行截图<br> * @param scrollView<br> * @return<br> */<br> public static Bitmap shotScrollView(ScrollView scrollView) {<br> int h = 0;<br> Bitmap bitmap = null;<br> for (int i = 0; i &lt; scrollView.getChildCount(); i++) {<br> h += scrollView.getChildAt(i).getHeight();<br> scrollView.getChildAt(i).setBackgroundColor(Color.parseColor("#ffffff"));<br> }<br> bitmap = Bitmap.createBitmap(scrollView.getWidth(), h, Bitmap.Config.RGB_565);<br> final Canvas canvas = new Canvas(bitmap);<br> scrollView.draw(canvas);<br> return bitmap;<br> }<br> <br> <br> /**<br> * 对ListView进行截图<br> * http://stackoverflow.com/questions/12742343/android-get-screenshot-of-all-listview-items<br> */<br> public static Bitmap shotListView(ListView listview) {<br> <br> ListAdapter adapter = listview.getAdapter();<br> int itemscount = adapter.getCount();<br> int allitemsheight = 0;<br> List&lt;Bitmap&gt; bmps = new ArrayList&lt;Bitmap&gt;();<br> <br> for (int i = 0; i &lt; itemscount; i++) {<br> <br> View childView = adapter.getView(i, null, listview);<br> childView.measure(<br> View.MeasureSpec.makeMeasureSpec(listview.getWidth(), View.MeasureSpec.EXACTLY),<br> View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));<br> <br> childView.layout(0, 0, childView.getMeasuredWidth(), childView.getMeasuredHeight());<br> childView.setDrawingCacheEnabled(true);<br> childView.buildDrawingCache();<br> bmps.add(childView.getDrawingCache());<br> allitemsheight += childView.getMeasuredHeight();<br> }<br> <br> Bitmap bigbitmap =<br> Bitmap.createBitmap(listview.getMeasuredWidth(), allitemsheight, Bitmap.Config.ARGB_8888);<br> Canvas bigcanvas = new Canvas(bigbitmap);<br> <br> Paint paint = new Paint();<br> int iHeight = 0;<br> <br> for (int i = 0; i &lt; bmps.size(); i++) {<br> Bitmap bmp = bmps.get(i);<br> bigcanvas.drawBitmap(bmp, 0, iHeight, paint);<br> iHeight += bmp.getHeight();<br> <br> bmp.recycle();<br> bmp = null;<br> }<br> <br> return bigbitmap;<br> }<br> <br> <br> /**<br> * 对RecyclerView进行截图<br> * https://gist.github.com/PrashamTrivedi/809d2541776c8c141d9a<br> */<br> public static Bitmap shotRecyclerView(RecyclerView view) {<br> RecyclerView.Adapter adapter = view.getAdapter();<br> Bitmap bigBitmap = null;<br> if (adapter != null) {<br> int size = adapter.getItemCount();<br> int height = 0;<br> Paint paint = new Paint();<br> int iHeight = 0;<br> final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);<br> <br> // Use 1/8th of the available memory for this memory cache.<br> final int cacheSize = maxMemory / 8;<br> LruCache&lt;String, Bitmap&gt; bitmaCache = new LruCache&lt;&gt;(cacheSize);<br> for (int i = 0; i &lt; size; i++) {<br> RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));<br> adapter.onBindViewHolder(holder, i);<br> holder.itemView.measure(<br> View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),<br> View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));<br> holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),<br> holder.itemView.getMeasuredHeight());<br> holder.itemView.setDrawingCacheEnabled(true);<br> holder.itemView.buildDrawingCache();<br> Bitmap drawingCache = holder.itemView.getDrawingCache();<br> if (drawingCache != null) {<br> <br> bitmaCache.put(String.valueOf(i), drawingCache);<br> }<br> height += holder.itemView.getMeasuredHeight();<br> }<br> <br> bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);<br> Canvas bigCanvas = new Canvas(bigBitmap);<br> Drawable lBackground = view.getBackground();<br> if (lBackground instanceof ColorDrawable) {<br> ColorDrawable lColorDrawable = (ColorDrawable) lBackground;<br> int lColor = lColorDrawable.getColor();<br> bigCanvas.drawColor(lColor);<br> }<br> <br> for (int i = 0; i &lt; size; i++) {<br> Bitmap bitmap = bitmaCache.get(String.valueOf(i));<br> bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);<br> iHeight += bitmap.getHeight();<br> bitmap.recycle();<br> }<br> }<br> return bigBitmap;<br> }<br>}</code></pre><pre><code>private View inviteView;<br>private ScrollView scrollView;<br>inviteView = getLayoutInflater().inflate(R.layout.component_invite,null);<br>ImageView iv_QRCodeHide = inviteView.findViewById(R.id.iv_QRCodeHide);<br>scrollView = inviteView.findViewById(R.id.sl_content);<br>TextView tv_title = inviteView.findViewById(R.id.tv_title);<br>Glide.with(getContext()).load(bitmap).into(iv_QRCodeHide);<br>tv_title.setText("好友"+o.getPlain().getDetails().getUserName()+"邀请你一起来赚外快!");<br>asyncBitmap(scrollView);</code></pre><pre><code>private void asyncBitmap(ScrollView view){<br> <br> layoutView(view,getWindowManager().getDefaultDisplay().getWidth(),getWindowManager().getDefaultDisplay().getHeight());<br> Bitmap bitmap = SimpleUtils.shotScrollView(view);<br> boolean isSaveSuccess = saveImageToGallery(ShareAppActivity.this, bitmap, "shareYwf.png");<br> if (isSaveSuccess) {<br> showToastshort(getString(R.string.share_success));<br> } else {<br> showToastshort(getString(R.string.share_fail));<br> }<br> }<br>}<br> <br> /**<br> * 保存图片到指定路径<br> *<br> * @param context<br> * @param bitmap 要保存的图片<br> * @param fileName 自定义图片名称<br> * @return<br> */<br> public static boolean saveImageToGallery(Context context, Bitmap bitmap, String fileName) {<br> // 保存图片至指定路径<br> String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + System.currentTimeMillis() + File.separator+"";<br> File appDir = new File(storePath);<br> if (!appDir.exists()) {<br> appDir.mkdir();<br> }<br> File file = new File(appDir, fileName);<br> try {<br> FileOutputStream fos = new FileOutputStream(file);<br> //通过io流的方式来压缩保存图片(80代表压缩20%)<br> boolean isSuccess = bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);<br> fos.flush();<br> fos.close();<br> <br> //发送广播通知系统图库刷新数据<br> Uri uri = Uri.fromFile(file);<br> context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));<br> if (isSuccess) {<br> return true;<br> } else {<br> return false;<br> }<br> } catch (IOException e) {<br> e.printStackTrace();<br> }<br> return false;<br> }</code></pre><p>//发送广播通知系统图库刷新数据<br>Uri uri = Uri.fromFile(file);<br>context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));<br>华为手机相册收到广播可能会提示 xx图片删除 不友好,,所以如果想脱离手机的管控,这个广播也可以不发。</p>
赞(0) 收藏(0)  分享
相关标签:
0个回复
  • 消灭零回复
Vaptcha启动中...