0

I'm trying to create a bitmap out of ListView items. I am using the Greendroid library (if that makes any difference). I initially had this working for lists where # of items is < 7 (since you can only see 6 items on the screen). I am now trying to build each view item individually, before getting the drawing cache. In the code bellow, I get a null pointer exception at childView.buildDrawingCache(). Am I calling getView() correctly? Are there any other simple solutions to this problem?

try {

                Bitmap main = BitmapFactory.decodeResource(getResources(),R.drawable.dummy);
                Bitmap dummy = BitmapFactory.decodeResource(getResources(),R.drawable.dummy);
                Bitmap view;
                Bitmap temp;
                Canvas canvas = new Canvas();
                Paint paint = new Paint();
                Matrix matrix = new Matrix();
                paint.setFilterBitmap(true);
                File pic = new File(getFilesDir(),"txtabot.jpg");
                //(ViewGroup) (getListView().getParent());
                //((LinearLayout) getListView().getParent()).setDrawingCacheEnabled(true);

                ListView lView = (ListView) getListView();

                for (int i = 0; i<lView.getCount();i++) {
                    lView.setSelectionFromTop(i, 0);
                    View childView = adapter.getView(i, null ,lView );
                    childView.setDrawingCacheEnabled(true);
                    childView.buildDrawingCache(true);
                    view = childView.getDrawingCache().copy(Bitmap.Config.ARGB_8888, true);

                    //ItemView iView = ((ItemView)lView.getItemAtPosition(i));
                    //lView.getChildAt(i).setDrawingCacheEnabled(true);
                    //lView.getChildAt(i).buildDrawingCache(true);
                    //view = lView.getChildAt(i).getDrawingCache().copy(Bitmap.Config.ARGB_8888, true);
                    temp = Bitmap.createScaledBitmap(dummy, view.getWidth(), main.getHeight()+view.getHeight(), true);
                    temp = temp.copy(Bitmap.Config.ARGB_8888, true);
                    canvas.setBitmap(temp);
                    canvas.drawBitmap(main, matrix, paint);
                    //matrix.preTranslate(0, main.getHeight()-view.getHeight());
                    matrix.postTranslate(0, main.getHeight());
                    canvas.drawBitmap(view, matrix, paint);
                    matrix.reset();
                    main = temp.copy(Bitmap.Config.ARGB_8888, true);    
                }
                //getListView().getChildAt(getListView().getCount());
                //Bitmap main = getListView().getDrawingCache().copy(Bitmap.Config.ARGB_8888, true);
                main.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(pic));

                Log.i("TAG", "ofter FOS.CLOSE()");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

And this is the stack trace:

10-05 10:46:51.101: D/AndroidRuntime(16836): Shutting down VM
10-05 10:46:51.101: W/dalvikvm(16836): threadid=1: thread exiting with uncaught exception (group=0x40a481f8)
10-05 10:46:51.140: E/AndroidRuntime(16836): FATAL EXCEPTION: main
10-05 10:46:51.140: E/AndroidRuntime(16836): java.lang.NullPointerException
10-05 10:46:51.140: E/AndroidRuntime(16836):    at com.gigabites.smsbot.LogActivity.onHandleActionBarItemClick(LogActivity.java:153)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at greendroid.app.GDActivity$1.onActionBarItemClicked(GDActivity.java:387)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at greendroid.widget.ActionBar$1.onClick(ActionBar.java:396)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at android.view.View.performClick(View.java:3511)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at android.view.View$PerformClick.run(View.java:14105)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at android.os.Handler.handleCallback(Handler.java:605)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at android.os.Handler.dispatchMessage(Handler.java:92)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at android.os.Looper.loop(Looper.java:137)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at android.app.ActivityThread.main(ActivityThread.java:4575)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at java.lang.reflect.Method.invokeNative(Native Method)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at java.lang.reflect.Method.invoke(Method.java:511)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-05 10:46:51.140: E/AndroidRuntime(16836):    at dalvik.system.NativeStart.main(Native Method)
10-05 10:46:51.710: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:51.718: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:52.226: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:52.230: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:52.726: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:52.730: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:53.230: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:53.230: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:53.730: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:53.753: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:54.238: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:54.253: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:54.730: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:54.738: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:55.230: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:55.234: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:55.742: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:55.742: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:56.234: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:56.238: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:57.074: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:57.082: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:57.238: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:57.253: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:57.738: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:57.742: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:58.250: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:58.250: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:58.750: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:58.750: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:59.238: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:59.242: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:46:59.746: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:46:59.746: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:47:00.246: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:47:00.257: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:47:00.742: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:47:00.753: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:47:01.582: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:47:01.585: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'
10-05 10:47:02.105: I/dalvikvm(16836): threadid=3: reacting to signal 3
10-05 10:47:02.113: I/dalvikvm(16836): Wrote stack traces to '/data/anr/traces.txt'

UPDATE: Now i'm inflating a view and drawing it to canvas(bitmap) and doing the same but everything is kind of weird. I don't really understand the itemView.measure() and itemView.layout methods. This is the code that kind of works:

try {
                // Prepare Utilities
                Bitmap main = BitmapFactory.decodeResource(getResources(),R.drawable.dummy);
                Bitmap dummy = BitmapFactory.decodeResource(getResources(),R.drawable.dummy);
                Bitmap view;
                Bitmap temp;
                //Canvas tempCanvas = new Canvas();
                Canvas canvas = new Canvas();
                Paint paint = new Paint();
                Matrix matrix = new Matrix();
                paint.setFilterBitmap(true);
                File pic = new File(getFilesDir(),"txtabot.jpg");


                final ListView lView = (ListView) getListView();
                //for (int i = 0; i<lView.getChildCount();i++) {
                for (int i = 0; i<3;i++) {

                    //View itemView = lView.getAdapter().getView(i, null, lView);
                    //itemView = lView.getChildAt(i);
                    //itemView.setDrawingCacheEnabled(true);
                    //itemView.draw(tempCanvas);
                    //final int viewheight = lView.getChildAt(lView.getFirstVisiblePosition()).getHeight();
                    View itemView = lView.getAdapter().getView(i, null, lView);
                    itemView.setLayoutParams(new LayoutParams(
                            LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
                    itemView.measure(
                            MeasureSpec.getSize(itemView.getMeasuredWidth()),
                            MeasureSpec.getSize(itemView.getMeasuredHeight())
                            );
                    itemView.layout(0, 0,itemView.getMeasuredWidth() , itemView.getMeasuredHeight());
                    view = Bitmap.createScaledBitmap(dummy,itemView.getMeasuredWidth(),itemView.getMeasuredHeight(),true);
                    canvas.setBitmap(view);
                    itemView.draw(canvas);
                    //iew.setSelectionFromTop(i, 0);
                    //View itemView = lView.getChildAt(i);
                    //itemView.setDrawingCacheEnabled(true);
                    //view = itemView.getDrawingCache().copy(Bitmap.Config.ARGB_8888, true);

                    temp = Bitmap.createScaledBitmap(dummy, view.getWidth(), main.getHeight()+view.getHeight(), true);
                    //temp = temp.copy(Bitmap.Config.ARGB_4444, true);
                    canvas.setBitmap(temp);
                    canvas.drawBitmap(main, matrix, paint);
                    matrix.postTranslate(0, main.getHeight());
                    canvas.drawBitmap(view, matrix, paint);
                    matrix.reset();
                    main = temp.copy(Bitmap.Config.ARGB_8888, true);    
                }
                main.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(pic));

                Log.i("TAG", "ofter FOS.CLOSE()");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

It manages to iterate through the list items but the output is all black with some visible view icons.

8oh8
  • 1,247
  • 5
  • 19
  • 35
  • Please add the stacktrace with the full exception. If the `NullPointerException` would be at the line `childView.buildDrawingCache(true);` that would mean the `childView` is `null`, which can't be true as the exception would have been thrown a line above at `childView.setDrawingCahceEnabled()`. – user Oct 05 '12 at 07:43
  • I've attached the stacktrace to my first attempt. I hope it helps. I've also put up some code of a workaround, but I'm having trouble inflating the view and setting the right parameters. Ideally I would want to just build and get drawing cache of all listview items even those out of visibility portal. – 8oh8 Oct 05 '12 at 18:08
  • I guess line `153` is `childView.buildDrawingCache(true);` in your code? If yes, I just don't see why that line would throw a `NullPointerException`. I doubt the workaround will work because you are trying to setup the row view outside of the `ListView` and generally this fails. Also, the first snippet of code will not work because getting the row views outside of the `ListView` directly from the adapter with `getView` will return a `View` with width/height == `0`. What exactly are you tying to do with the rows bitmaps? – user Oct 05 '12 at 18:32
  • I'm trying to append them one after the other. The listview holds sms messages and it kinda looks like ICS sms app with an icon in each row. I'm trying to get a bitmap with all the items on it because my app has a share button so you can post the conversation to facebook as a picture. I know the other way is just to draw text manually on canvas, but it would really misrepresent the look and feel of my app. – 8oh8 Oct 05 '12 at 18:47
  • 1
    Hey I've seen this question http://stackoverflow.com/questions/12742343/android-get-screenshot-of-all-listview-items and I remembered yours , see if this helps you in some way. – user Oct 07 '12 at 14:51
  • Thanks! Although I had already approached the problem this way, the link really helps. I was using the wrong parameters for childView.measure() Submit the link as an answer and I will pick it. – 8oh8 Oct 08 '12 at 06:41
  • Link only answers aren't allowed on stackoverflow. Anyway, you should post your working code as an answer and accept it, so it will help future users that might be looking for this. – user Oct 09 '12 at 07:58

0 Answers0