Android:在什么时候活动完全加载并呈现自己?

时间:2013-12-23 00:01:39

标签: android animation android-activity

我想要一件非常简单的事情 - 知道我的活动什么时候完全加载并在屏幕上呈现自己 - 就在我想要一段代码运行的时候。这段代码首先截取屏幕截图并在其上运行一些动画。我在 onResume()中编写了该代码,在正常启动期间一切正常,但是当我旋转设备时,屏幕截图取自之前的方向,尽管所有显示参数转储显示方向是已经改变了。看起来系统重新创建,重新运行并且重新绘制我的Activity仍然在物理上显示先前的状态,然后它在2个状态之间运行系统旋转动画,最后显示我的Activity。这也意味着任何在 onResume 中启动任何动画的Android应用程序都会因为系统旋转动画而失去它的前X毫秒(X可以是3个不同的值,具体取决于旋转)。我尝试了40多个 on ...()函数,例如 onAttachedToWindow(),但它们都被称为过早。在启动之前等待一段时间并不好,因为在正常启动期间我会有延迟并且等待时间没有明确定义。

由于我是系统的一部分,我有一个解决方案,在窗口管理器中添加一些代码,我可以询问系统旋转动画是否正在运行,但它不优雅,不是任何“正常”的解决方案“app。我也想保留旋转动画。只是想知道公共API中是否有事件或函数可供使用。

1 个答案:

答案 0 :(得分:2)

我会尝试使用OnGlobalLayoutListener的ViewTreeObserver,如下所述:How can you tell when a layout has been drawn?

编辑:我创建了一个示例工作实现。正如您所要求的那样,它会在方向更改后捕获屏幕。

无法获取没有root的状态栏:(android development)how to implement screen grab with status bar in code

但是,可以删除状态栏所在的空白处:Android screenshot of activity with actionbar

public class MainActivity extends Activity
{
    private static int counter = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final View root = getWindow().getDecorView();
        ViewTreeObserver vto = root.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout()
            {
                root
                .getViewTreeObserver()
                .removeOnGlobalLayoutListener(this);

                takeScreenShot(root);
                ++counter;
            }

        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private void takeScreenShot(View view)
    {
        String mPath = Environment.getExternalStorageDirectory().toString() 
                + "/" + "rotation" + String.valueOf(counter);   

        // create bitmap screen capture
        Bitmap bitmap;

        view.setDrawingCacheEnabled(true);
        bitmap = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);

        OutputStream fout = null;
        File imageFile = new File(mPath);

        try {
            fout = new FileOutputStream(imageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
            fout.flush();
            fout.close();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }   
}