简体   繁体   English

修改布局边距,然后从该布局生成图像

[英]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. 基本上,它可以工作,除了它在使用修改过的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. 一种更简单的方法是为dashboardView视图视图上的布局传递设置侦听器。
Setting-up listener using View.addOnLayoutChangeListener() - addOnLayoutChangeListener . 使用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. 希望它将增加任何改进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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