2016-10-13 6 views
1

ToogleButtonを継承するビューMyToggleButtonを作成しました。 TogglebuttonのonDrawメソッドを上書きして、ボタンに線を描画し、そのテキストを回転させます。私はのスクリーンショットを取得し、それを表示したいその後ToggleButtonキャンバス上に描画されたテキストと線は、スクリーンショットに表示されません。

package com.example.gl.myapplication; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.text.TextPaint; 
import android.widget.ToggleButton; 

public class MyToggleButton extends ToggleButton { 

    public float textRotation=0; 

    public MyToggleButton(Context context, float rotationValue) { 
     super(context); 

     textRotation=rotationValue; 
    } 

    @Override 
    protected void onDraw(Canvas canvas){ 

     TextPaint textPaint = getPaint(); 
     textPaint.setColor(getCurrentTextColor()); 
     textPaint.drawableState = getDrawableState(); 

     canvas.save(); 

     //paint 
     Paint paint = new Paint(); 
     paint.setColor(Color.BLACK); 
     paint.setStrokeWidth(7); 
     paint.setStrokeCap(Paint.Cap.ROUND); 

     canvas.drawLine(canvas.getWidth()/2, canvas.getHeight()/2, (float) (canvas.getHeight()/2 + 400), (canvas.getHeight()/2), paint); 

     canvas.rotate(textRotation, canvas.getWidth()/2, canvas.getHeight()/2); 

     getLayout().draw(canvas); 

     canvas.restore(); 

    } 


} 

をし、そのために私は、画面上の第三のボタンを押すことによって呼び出されたtakeScreenshot()メソッドを使用します。ここでは

MyToggleButtonです。スクリーンショットコードはHow to programmatically take a screenshot in Android?に基づいています。 stackoverflowの他の記事や、私が見つけたさまざまなサイトやチュートリアルでも同じアプローチが続いています。ここで

は、私が使用MainActivityである:ここでは

package com.example.gl.myapplication; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff; 
import android.graphics.PorterDuffXfermode; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AbsListView; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.RelativeLayout; 
import android.widget.Toast; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.util.Date; 

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     //add 3 buttons 
     addButtons(); 

    } 


    private void addButtons(){ 

     LinearLayout linear1= (LinearLayout) findViewById(R.id.vert1); 

     //MyToggleButton with rotated text 
     MyToggleButton btn1 = new MyToggleButton(this,0); 
     btn1.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
       LinearLayout.LayoutParams.WRAP_CONTENT)); 
     btn1.setTextOff("Button 1 not rotated"); 
     btn1.setTextOn("Button 1 not rotated"); 
     btn1.setText("Button 1 not rotated"); 
     linear1.addView(btn1); 

     //MyToggleButton with normal text 
     MyToggleButton btn2 = new MyToggleButton(this,50); 
     btn2.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
       LinearLayout.LayoutParams.WRAP_CONTENT)); 
     btn2.setTextOff("Button 2 rotated"); 
     btn2.setTextOn("Button 2 rotated"); 
     btn2.setText("Button 2 rotated"); 
     linear1.addView(btn2); 

     //button to create screenshot 
     Button btn3 = new Button(this); 
     btn3.setText("Create bitmap"); 
     btn3.setOnClickListener(new Button.OnClickListener() { 
      public void onClick(View v) { 
       takeScreenshot(); 

      } 
     }); 
     linear1.addView(btn3); 



    } 

    //Screenshotcreator 
     private void takeScreenshot() { 
      try { 
       View v1 = getWindow().getDecorView().getRootView(); 

       // create bitmap screen capture 
       v1.setDrawingCacheEnabled(true); 
       Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache()); 

       v1.setDrawingCacheEnabled(false); 

       ImageView imageView1 =(ImageView) findViewById(R.id.imageView1); 
       imageView1.setImageBitmap(bitmap); 


      } catch (Throwable e) { 
       e.printStackTrace(); 
      } 
     } 


    } 

MainActivityのレイアウトです:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.gl.myapplication.MainActivity" 
    android:id="@+id/relative1"> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:id="@+id/vert1"> 

     <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="250dp" 
      android:id="@+id/imageView1" /> 
    </LinearLayout> 
</RelativeLayout> 

問題はすべてが画面上でOKに見えますが、スクリーンショットのビットマップが欠けているということです回転されたテキストとを含む。ビットマップ内のその奇妙な結果の理由かもしれない何

You can see the problem here. Screen is OK, screenshot is not.

ステータスバー情報(時刻など)と同様に、デバイスのback-home-recentsボタンがスクリーンショットに表示されていないことに注意してください。私はこれが私の問題で何かをしなければならないとは思っていません。これらの要素は私のアプリには属していないので、私が得意とするビューには表示されないことが期待されていますv1 = getWindow().getDecorView().getRootView();しかし回転したテキストと線を描くキャンバスはそのビューに属します。

私の質問は:スクリーンショットに描かれた線や回転したテキストが表示されないのはなぜですか?また、スクリーンショットを取得するためにコードを変更するにはどうすればよいですか?

私はルートデバイスを必要としませんし、MediaProjection APIも使用できません。これはAPI 21で追加されたためですが、私のアプリもAndroid 4.4(API 19)でも実行されます。最後に、Android Screenshot Libraryやhttps://android-arsenal.com/details/1/2793などの外部ライブラリの存在を認識していますが、外部ライブラリを使用しないでください。

P.S.おそらくこれは関連しています:Surfaceview screenshot with line/ellipse drawn over it

答えて

1

問題は両方ともbtn1.isDrawingChaceEnabled()btn2.isDrawingChaceEnabled()が返信falseです。

RootViewでsetDrawingCacheEnabled(true)を呼び出した場合でも、彼のすべての子ビューで再現的にtrueに設定されていません(Log.dでテストしました)。
つまり、ToggleButtonの描画キャッシュは、android.view.View.getDrawingCache() javadocで説明されているように空になります。

/** 
* <p>Calling this method is equivalent to calling <code>getDrawingCache(false)</code>.</p> 
* 
* @return A non-scaled bitmap representing this view or null if cache is disabled. 
* 
* @see #getDrawingCache(boolean) 
*/ 

したがって、興味のあるビューごとにsetDrawingCacheEnabled(true)を設定してください。例えば
私はあなたのコードに次の行を追加しました:
MainActivity

btn1.setDrawingCacheEnabled(true); 
    btn2.setDrawingCacheEnabled(true); 

And it looks like this

関連する問題