简体   繁体   中英

Modify layout margin then generate an image from this layout

I have a weird problem,

I have an activity, within this activity I have a layout I want to make an image of it in order to share it on social networks. This layout contains differents dynamic images and texts. That's why I can't just store it on as a static image and share it on demand. I need to generate the image right when the user touch the share button.

The problem is that I need to adjust the layout before sharing, what I do ?

    ImageView profilPic = (ImageView)dashboardView.findViewById(R.id.profilePic); 
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)profilPic.getLayoutParams();
    params.setMargins(10, 62, 0, 0);
    profilPic.invalidate();
    profilPic.requestLayout();

First I modify the margin of my layout, then I make an image of it

Bitmap bitmap = null;   
        try {
            bitmap = Bitmap.createBitmap(dashboardView.getWidth(),
                    dashboardView.getHeight(), Bitmap.Config.ARGB_4444);
            dashboardView.draw(new Canvas(bitmap));
        } catch (Exception e) {
            // Logger.e(e.toString());
        }

        FileOutputStream fileOutputStream = null;
        File path = Environment
                .getExternalStorageDirectory();
        File file = new File(path, "wayzupDashboard" + ".png");
        try {
            fileOutputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
        bitmap.compress(CompressFormat.PNG, 100, bos);
        try {
            bos.flush();
            bos.close();
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

And finally I share it.

Basically it works, except that it captures the layout BEFORE redrawing the layout with modified layoutParams. I need to capture this layout once and only when the new layout parameters are took into account, after layout is redraw.

If I remove the capture code, well it works, when I touch the share button I see the layout moving. But when I have the capture code in place it just capture the layout before modifying margins.

How can I ensure that the layout is redraw before capturing it ?

For the record, to correctly capture the layout only once the view was setup I needed to first setup the view and then capture the layout in a delayed thread. This is the only way I found to make it works.

public void onShareButton() {
        dashboardController.setupViewBeforeSharing();

        new Timer().schedule(new TimerTask() {          
            @Override
            public void run() {
                Bitmap bitmap = null;   
                try {
                    bitmap = Bitmap.createBitmap(dashboardView.getWidth(),
                            dashboardView.getHeight(), Bitmap.Config.ARGB_4444);
                    dashboardView.draw(new Canvas(bitmap));
                } catch (Exception e) {
                    // Logger.e(e.toString());
                }

                FileOutputStream fileOutputStream = null;
                File path = Environment
                        .getExternalStorageDirectory();
                File file = new File(path, "wayzupDashboard" + ".png");
                try {
                    fileOutputStream = new FileOutputStream(file);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
                bitmap.compress(CompressFormat.PNG, 100, bos);
                try {
                    bos.flush();
                    bos.close();
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Intent share = new Intent(Intent.ACTION_SEND);
                share.setType("image/png");
                share.putExtra(Intent.EXTRA_TEXT, R.string.addPassengerButton);
                share.putExtra(Intent.EXTRA_STREAM,
                        Uri.parse("file://" + file.getAbsolutePath()));
                startActivity(Intent.createChooser(share, "Share image"));

                MainActivity.this.runOnUiThread(new Runnable() {
                    public void run() {
                        dashboardController.setupViewAfterSharing();   
                    }
                });

            }
        }, 300);
    }

An easier way, is to set-up a listener for layout pass on the dashboardView view.
Setting-up listener using View.addOnLayoutChangeListener() - addOnLayoutChangeListener .
Set the listener before changing the layout parameters and remove it after the image was saved to persistence.
Hope it'll add any improvement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM