19

私はアンドロイドアプリケーションに取り組んでいます。画面全体をビューで埋めるアクティビティ A があります。AI でボタンをクリックすると、別のアクティビティ B を開始したいとします。これにはいくつかのビューとコントロールもあります。アクティビティ B を offscreen にして、 A から B のスクリーンショットを撮りたいです。出来ますか?

注: 描画キャッシュをビットマップに保存することでページ A のスクリーンショットを撮ることに成功しましたが、オフスクリーン ページのスクリーンショットを撮るのに苦労しています。

4

4 に答える 4

14

はい、可能です...アクティビティ'A'でActivityGroupを拡張する必要があります。次に、ボタンクリックイベントでこれを行います...

 View view =getLocalActivityManager().startActivity("B",new Intent(this,B.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();

次に、そのビューをビットマップとして変換します。

これはあなたに役立つと思います...

于 2011-04-16T09:37:57.680 に答える
5

さて、私は私が望むものを達成しました。これらは私が使用した手順です。

  1. startActivity() の代わりに startActivityForResult() を使用してアクティビティ B を開始します。

    Intent bIntent = new Intent(A.this,B.class);
    startActivityForResult(bIntent,B_REQUEST_CODE);
    
  2. アクティビティ B の onCreate で、B の mainLayout を取得し、その描画キャッシュを有効にします

    final LinearLayout layout = (LinearLayout)
                         findViewById(R.id.app_parent_layout);
    layout.setDrawingCacheEnabled(true);
    layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
    
  3. アクティビティ B では、レイアウトが完全に描画されるまで待ちます (これは非常に重要です)。そのために、アクティビティ B の onCreate() で、B の mainLayout を取得し、ViewTreeObserver を使用して、そのレイアウトが完全に描画されたときにコールバックを取得します。

    ViewTreeObserver vto = layout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
      layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      getDrawingBitmap();
     }
    });
    
  4. レイアウトが完全に描画されると getDrawingBitmap() が呼び出されるようになりました。そこでスクリーンショットを撮ります。

    public void getDrawingBitmap(){
        LinearLayout mainLayout = (LinearLayout)
                            findViewById(R.id.app_parent_layout);
        Bitmap b = mainLayout.getDrawingCache();
    
        File file = saveBitmapAsFile(b);
    
        Intent resultIntent = new Intent();
        resultIntent.putExtra("FullFileName",file.getAbsolutePath());
        setResult(Activity.RESULT_OK,resultIntent);
        finish();
    }
    

    ここでは、ビットマップを取得してファイルとして保存し、結果コードとしてファイル名を返しています。ファイルとして保存してファイル名を送信するよりも、ビットマップを親アクティビティに送信するためのより良い方法があると確信しています。しかし、ビットマップをしばらく保存する必要があります。だから私にとってこれはより簡単な方法です。結果を設定した後、アクティビティを終了します。

  5. アクティビティ A onActivityResult() で、ファイル名を取得します。

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if(requestCode == B_REQUEST_CODE){
        if (resultCode == Activity.RESULT_OK) { 
          String newText = data.getStringExtra("FullFileName");
         File dir = new File (newText);
        } 
      }
    }
    
于 2013-09-19T07:16:21.807 に答える
1

これらのビューの描画方法を制御する方法がわからないため、そうするのは非常に難しいと思います。また、表示されない限り、Android OS もそれらを描画しません。

ただし、他のビューを短時間だけフォアグラウンドにして、その描画キャッシュを埋めることができる場合があります。スムーズな体験のために、実際にフォアグラウンドに合成される前に、OSがビューを画面外に描画するように見えるため、表示される前に再びバックグラウンドに戻すことができるかもしれません。

もう 1 つのトリックは、フォアグラウンド ビューを子ビューとしてバックグラウンドにアタッチし、非常にわずかなアルファ透明度を与えることです。たとえば、WebView はこの方法で非常にうまく重ね合わせることができ、実際には WebView とその背景の両方を強制的に描画します。多分これは他のビューでも機能します。

于 2011-04-15T00:42:26.087 に答える
0

この方法を使用するとうまく機能しますが、最初にスナップショットを撮るときに1つのレイアウトのスナップショットを撮るだけで正しい写真が得られますが、いくつかの変更を加えた後、もう一度スナップショットを撮ると以前のスナップショットが得られます。

RelativeLayout layout = (RelativeLayout)findViewById(R.id.mainview);
    layout.setDrawingCacheEnabled(true);
    layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
    layout.buildDrawingCache();
    Bitmap bitmap = layout.getDrawingCache();

          File file =  new File(Environment.getExternalStorageDirectory().toString() + "/sPenimg.png");
          FileOutputStream ostream;
          try {
              ostream = new FileOutputStream(file);
              bitmap.compress(CompressFormat.PNG, 100, ostream);
              ostream.flush();
              ostream.close();      
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

この問題は、((RelativeLayout)findViewById(R.id.mainview)).destroyDrawingCache(); を追加することで解決されます。

于 2012-07-24T09:50:53.487 に答える