Search code examples
androidviewdrag-and-dropsaveviewgroup

Save ViewGroup state : Android


Note: Here I am not talking about saving state of activity through onSaveInstanceState(...)

I am using https://github.com/eskim/android_drag_sample code to drag and drop views in my application. User can create multiple scenes in my application and to each scene, user can add multiple views and drag and drop them wherever they want. While switching scenes I am storing all scene information like number of children's added, their properties etc in a model object and its working fine. User can save scenes and send it through mail as pdf. Problem is that to prepare pdf I need images(am using iText library to convert images to pdf) but how can I convert other hidden scenes(which are not visible) to image? currently visible scene I can convert into image and store in SD card. I tried saving current scene in model object and converting it into image while preparing pdf but its overwriting all scenes to current scene. I dont know whether that approach is correct or not. So, any help or clue is greatly appreciated.

code to convert view into bitmap :

public static Bitmap getBitmapFromView(final View view) {
    if(view.getWidth() <= 0 && view.getHeight() <= 0)
        return null;

    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
    final Canvas canvas = new Canvas(returnedBitmap);

    Drawable bgDrawable = view.getBackground();
    if (bgDrawable != null) 
        bgDrawable.draw(canvas);
    else 
        canvas.drawColor(Color.WHITE);

    ((Activity) view.getContext()).runOnUiThread(new Runnable() {

        @Override
        public void run() {
            view.draw(canvas);
        }
    });

    return returnedBitmap;
}

Solution

  • After quite a long time, got solution for my problem. Idea is to whatever data is there in model object, adding that to any Layout and getting image from that. Below is the code.

    /** convert MySTScene(model object) into a View */
    public static View getView(Context context, MySTScene mySTScene) {
        RelativeLayout sceneView = new RelativeLayout(context);
        RelativeLayout.LayoutParams parms = new RelativeLayout.LayoutParams(Constants.PLAY_AREA_WIDTH_TAG, 
                LayoutParams.WRAP_CONTENT);
        parms.setMargins(100, 100, 100, 100);
    
        String sceneBackground = mySTScene.getThemeImageName();
        Drawable drawable = BitmapConverter.getDrawable(context, sceneBackground);
    
        sceneView.setBackgroundDrawable(drawable);
    
        for(MySTCharacter mySTCharacter : mySTScene.getCharacterList()) {
            int scale = mySTCharacter.getScale();
            ImageView image = new ImageView(context);
            String filePath = mySTCharacter.getCharacterName();
            int xPosition = (int) mySTCharacter.getCharacterPoint().x + 141;
            if(xPosition >= Constants.PLAY_AREA_WIDTH_TAG)
                xPosition -= 400;
            else if(xPosition > (Constants.PLAY_AREA_WIDTH_TAG / 2))
                xPosition -= 300;
            else
                xPosition -= 200;
            int yPosition = (int) mySTCharacter.getCharacterPoint().y;
            if(!mySTCharacter.getIsDialog())
                sceneView.addView(setImageProperties(image, scale, filePath, 
                        xPosition, yPosition, 0, 0));
            else {
                addDialog(mySTCharacter, sceneView, filePath, 
                        xPosition, yPosition);
            }
        }
    
        // add writing pad only if some text is added to it while creating/saving scene
        boolean isTrue = mySTScene.getStoryText() != null && mySTScene.getStoryText().length() != 0;
        if(isTrue) 
            addWritingPad(mySTScene, sceneView);
    
        sceneView.setLayoutParams(parms);
    
        return sceneView;
    }
    

    save view to sd card as image

    public static void saveViewToSD(getView(context, mySTScene)) {
    
        File fullSaveDir = FileUtils.createDirectory(FileUtils.PDF_IMAGES_DIRECTORY_TAG);
    
        File file = new File(fullSaveDir, ""+System.currentTimeMillis()+".PNG");
    
        Bitmap bitmap = null;
    
        try {
            if(file != null && !file.exists())
                file.createNewFile();
    
            FileOutputStream fileOutputStream = new FileOutputStream(file);
    
            bitmap = loadBitmapFromView(view);
    
    
            if(bitmap == null) {
                fileOutputStream.close();
                return;
            }
    
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(bitmap != null && !bitmap.isRecycled()) {
    
                bitmap.recycle();
                bitmap = null;
            }
        }
    }
    

    load bitmap from view

    public static Bitmap loadBitmapFromView(View view) throws IllegalArgumentException {
    
        if (view.getMeasuredHeight() <= 0) 
            view.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    
        Bitmap bitmap = Bitmap.createBitmap( Constants.PLAY_AREA_WIDTH_TAG, Constants.PLAY_AREA_HEIGHT_TAG, 
                Bitmap.Config.ARGB_8888);  
        Canvas canvas = new Canvas(bitmap);
    
        Drawable bgDrawable = view.getBackground();
    
        Bitmap bitmapbg = ((BitmapDrawable)bgDrawable).getBitmap();
        canvas.drawBitmap(bitmapbg, view.getLeft(), view.getTop(), null);
    
        view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
        view.draw(canvas);
    
        return bitmap;
    }