ListView To Bitmap
来源:互联网 发布:caffe怎么用model 编辑:程序博客网 时间:2024/05/22 14:40
公司有需求,需要将listview的全部内容生成一组图片,于是有了以下代码
public class ListViewToBitmap { private ListView mListView; private ListAdapter mAdapter; private int childCount; // 每页的项目数, 默认情况下,只是一页,但是极有可能导致oom异常 private int countPerPage = Integer.MAX_VALUE; // 默认情况下,只是保存在文件中,不保存在内存中 private boolean inMemory = false; private InMemoryCallBack inMemoryCallBack; private boolean inFile = true; private InFileCallBack inFileCallBack; private Handler uiThreadHandler; private static final int MEMORY_HANDLED = 1; private static final int FILE_HANDLED = 2; private List<Bitmap> memoryDatas = new ArrayList<>(); private List<String> filePaths = new ArrayList<>(); // 图片文件目录 private File filesDir; private ListViewToBitmap(ListView listView) { this(listView, Integer.MAX_VALUE); } private ListViewToBitmap(ListView listView, int count_per_page) { mListView = listView; mAdapter = mListView.getAdapter(); childCount = mAdapter.getCount(); countPerPage = count_per_page; Context context = listView.getContext(); filesDir = context.getExternalCacheDir(); if (filesDir == null) { filesDir = context.getCacheDir(); } } protected void setInMemory(InMemoryCallBack callBack) { inMemory = true; inMemoryCallBack = callBack; } protected void setInFile(InFileCallBack callBack) { inFile = true; inFileCallBack = callBack; } public void start() { if (uiThreadHandler == null) { uiThreadHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { case MEMORY_HANDLED:{ if (inMemory && inMemoryCallBack!= null) { inMemoryCallBack.onSuccess(memoryDatas); } break; } case FILE_HANDLED:{ if (inFile && inFileCallBack != null) { inFileCallBack.onSuccess(filePaths); } break; } } } }; } new Thread() { @Override public void run() { // 计算有多少页 int page = childCount / countPerPage; if (childCount % countPerPage > 0) { page += 1; } for (int pageIndex = 0; pageIndex < page; ++pageIndex) { Bitmap bitmap = getBitmap(pageIndex); if (inFile) { String filepath = bitmapToFile(bitmap); filePaths.add(filepath); } // 需要保存在内存中(非常容易出现oom) if (inMemory) { memoryDatas.add(bitmap); } else { // 及时清理内存才是正途 bitmap.recycle(); } } if (inFile) { uiThreadHandler.sendEmptyMessage(FILE_HANDLED); } if (inMemory) { uiThreadHandler.sendEmptyMessage(MEMORY_HANDLED); } } }.start(); } private String bitmapToFile(Bitmap bitmap) { try { File file = getFile(); file.createNewFile(); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 30, bos); bos.flush(); bos.close(); return file.getAbsolutePath(); } catch (Exception e) { e.printStackTrace(); return null; } } private File getFile() { File file = new File(filesDir, System.currentTimeMillis() + ".jpg"); if (file.exists()) { return getFile(); } else { return file; } } /** * 获取每一页的bitmap * @param page * @return */ private Bitmap getBitmap(int page) { int pageStart = page * countPerPage; int pageEnd = pageStart + countPerPage > childCount ? childCount : pageStart + countPerPage; View child; int everyChildWidthMeasureSpec = View.MeasureSpec.makeMeasureSpec(mListView.getWidth(), View.MeasureSpec.EXACTLY); int childHeightMeasureSpec; int itemsHeight = 0; List<Bitmap> itemBitmaps = new ArrayList<>(); // 获取到一页中,每个item的bitmap for (int i = pageStart; i < pageEnd; ++i) { child = mAdapter.getView(i, null, mListView); childHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); child.measure(everyChildWidthMeasureSpec, childHeightMeasureSpec); child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight()); child.setDrawingCacheEnabled(true); child.buildDrawingCache(); itemBitmaps.add(child.getDrawingCache()); itemsHeight += child.getMeasuredHeight(); } // 创建一个大的空白的bitmap, 用来保存一页的内容 Bitmap pageBitmap = Bitmap.createBitmap(mListView.getWidth(), itemsHeight, Bitmap.Config.RGB_565); Canvas pageCanvas = new Canvas(pageBitmap); Paint pagePaint = new Paint(); int x = 0; int y = 0; Bitmap bitmap; // 逐步将一页的内容画进大的bitmap中 for (int i = 0; i < itemBitmaps.size(); ++i) { bitmap = itemBitmaps.get(i); pageCanvas.drawBitmap(bitmap, x, y, pagePaint); y += bitmap.getHeight(); // 及时回收每一个item的内存 bitmap.recycle(); } return pageBitmap; } public static class Builder { private ListView listView; private int count_per_page = Integer.MAX_VALUE; private boolean inMemory; private boolean inFile; private InMemoryCallBack inMemoryCallBack; private InFileCallBack inFileCallBack; public Builder(ListView list) { listView = list; } public Builder countPerPage(int cpp) { count_per_page = cpp; return this; } public Builder inMemory(InMemoryCallBack callBack) { inMemory = true; inMemoryCallBack = callBack; return this; } public Builder inFile(InFileCallBack callBack) { inFile = true; inFileCallBack = callBack; return this; } public ListViewToBitmap build() { ListViewToBitmap listViewToBitmap = new ListViewToBitmap(listView, count_per_page); if (inMemory) { listViewToBitmap.setInMemory(inMemoryCallBack); } if (inFile) { listViewToBitmap.setInFile(inFileCallBack); } return listViewToBitmap; } } public interface InMemoryCallBack { void onSuccess(List<Bitmap> bitmaps); } public interface InFileCallBack { void onSuccess(List<String> filePaths); }}
主要目的是在工作线程里面执行分页操作,及时释放内存,避免oom
使用方法:
ListViewToBitmap listViewToBitmap = new ListViewToBitmap.Builder(lv) .countPerPage(30) .inFile(inFileCallBack) .build(); listViewToBitmap.start();
1 0
- ListView To Bitmap
- ListView中显示bitmap
- Android ListView添加Bitmap
- ListView 或是 GridView中。Canvas: trying to use a recycled bitmap 异常
- Bitmap to BitmapSource
- view to bitmap
- Bitmap to YUV
- Drawable to bitmap
- drawable to bitmap
- ListView中显示Bitmap图像
- 整个listview 转换成 bitmap
- Picasso使用时,ImageView做ListView的Item出现异常Canvas: trying to use a recycled bitmap
- Picasso使用时,ImageView做ListView的Item时出现异常Canvas: trying to use a recycled bitmap
- Copying a bitmap to clipboard
- 关于bitmap conversion to ROWID
- bitmap convert to RGB565 display
- bitmap convert to RGB565 display
- Icon to Bitmap Conversion【zz】
- 浏览谷歌网站的方法
- QtUI设计:设置控件透明
- TCP/IP Socket Http UDP
- 解决ListView加载错乱问题
- 求两个数的最大公约数,最小公倍数
- ListView To Bitmap
- LooperExecutor简单注释
- android auto 学习分享
- 【函数式】纯函数与替代模型
- Linux挂载iscsi存储的方式
- Eclipse 的 Workspace 下边有一个 .metadata 的目录,是做什么用的?
- mahout源码目录说明(转)
- 正则表达式限制输入框只能输入数字
- String、StringBuffer与StringBuilder之间区别