Dibujar contenido de TextView actual en Bitmap

Tengo un TextView en ScrollView:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parentLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ScrollView android:id="@+id/textAreaScroller" android:layout_width="400px" android:layout_height="200px" android:layout_x="0px" android:layout_y="25px" android:fadeScrollbars="false" android:scrollbarSize="3px" android:scrollbarStyle="insideOverlay" > <TextView android:id="@+id/scrapbook" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="" /> </ScrollView> <Button android:id="@+id/upBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Up" /> <Button android:id="@+id/downBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Down" /> <ImageView android:id="@+id/imageView" android:layout_width="400px" android:layout_height="200px" /> </LinearLayout> 

TextView tiene un montón de texto por eso es desplazable. Necesito dibujar el contenido visible actual en TextView a Bitmap. Para propósitos de prueba, muestro este mapa de bits en ImageView. Tengo el siguiente código:

 public class TextviewToImageActivity extends Activity { private TextView textView; private ScrollView textAreaScroller; private ImageView imageView; private Handler mHandler; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mHandler = new Handler(); imageView = (ImageView) findViewById(R.id.imageView); textAreaScroller = (ScrollView) findViewById(R.id.textAreaScroller); textView = (TextView) findViewById(R.id.scrapbook); textView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { imageView.setImageBitmap(loadBitmapFromView(textAreaScroller)); return false; } }); Button upBtn = (Button) findViewById(R.id.upBtn); Button downBtn = (Button) findViewById(R.id.downBtn); upBtn.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { scheduleScroller(upScroller); imageView.setImageBitmap(loadBitmapFromView(textView)); } else if (event.getAction() == MotionEvent.ACTION_UP) { mHandler.removeMessages(1); } return true; } }); downBtn.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { scheduleScroller(downScroller); imageView.setImageBitmap(loadBitmapFromView(textView)); } else if (event.getAction() == MotionEvent.ACTION_UP) { mHandler.removeMessages(1); } return true; } }); loadDoc(); } private Runnable downScroller = new Runnable() { public void run() { textAreaScroller.scrollBy(0, 10); scheduleScroller(downScroller); } }; private Runnable upScroller = new Runnable() { public void run() { textAreaScroller.scrollBy(0, -10); scheduleScroller(upScroller); } }; private void scheduleScroller(Runnable scrollerJob) { Message msg = Message.obtain(mHandler, scrollerJob); msg.what = 1; mHandler.sendMessageDelayed(msg, 10); } private static Bitmap loadBitmapFromView(View v) { Bitmap b = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); v.draw(c); return b; } private void loadDoc() { String s = ""; for (int x = 0; x <= 100; x++) { s += "Line: " + String.valueOf(x) + "\n"; } textView.setText(s); textView.setMovementMethod(new ScrollingMovementMethod()); } } 

El problema es que una vez que desplazo TextView (trigger TouchEvent) el mapa de bits no refleja el contenido actual de TextView y en su lugar siempre tiene sólo el contenido inicial de TextView (no importa cuál es la posición de desplazamiento actual). He puesto al día la publicación para proporcionar código de trabajo – tal vez va a trabajar en el otro dispositivo sb.

ACTUALIZAR

También intenté comprobar la idea de onDraw anulando onDraw en mi TextView personalizado, pero de alguna manera todavía sólo dibujar el contenido de inicio de TextView:

 public class MyTextView extends TextView { private Bitmap mBitmap; public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); } public MyTextView(Context context) { super(context); } public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public Bitmap getBitmap() { return mBitmap; } @Override protected void onDraw(Canvas canvas) { mBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight() , Bitmap.Config.ARGB_8888); Canvas c = new Canvas(mBitmap); super.onDraw(canvas); super.onDraw(c); } } 

Intente anular el método onDraw() de TextView debería funcionar. Allí puede crear un mapa de bits basado en el parámetro canvas. Los detalles se pueden encontrar en mi tutorial: Cómo crear y guardar una captura de pantalla de un SurfaceView

Actualizar:
Solucioné tu problema:

La actividad (cambié el uso del manejador y quité algunos métodos. Básicamente encogí el código un poco).

 import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.text.method.ScrollingMovementMethod; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageView; /** * @author WarrenFaith */ public class TextToImageActivity extends Activity { private MyTextView textView; private ImageView imageView; private boolean mRepeatDrawing = false; private Handler mHandler; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.textview); mHandler = new Handler(); imageView = (ImageView) findViewById(R.id.imageView); textView = (MyTextView) findViewById(R.id.scrapbook); Button upBtn = (Button) findViewById(R.id.upBtn); Button downBtn = (Button) findViewById(R.id.downBtn); upBtn.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mRepeatDrawing = true; mHandler.post(upScroller); } else if (event.getAction() == MotionEvent.ACTION_UP) { mRepeatDrawing = false; } return false; } }); downBtn.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { mRepeatDrawing = true; mHandler.post(downScroller); } else if (event.getAction() == MotionEvent.ACTION_UP) { mRepeatDrawing = false; } return false; } }); loadDoc(); } private Runnable downScroller = new Runnable() { public void run() { textView.scrollBy(0, 10); imageView.setImageBitmap(textView.getBitmap()); if (mRepeatDrawing) { mHandler.postDelayed(this, 10); } } }; private Runnable upScroller = new Runnable() { public void run() { textView.scrollBy(0, -10); imageView.setImageBitmap(textView.getBitmap()); if (mRepeatDrawing) { mHandler.postDelayed(this, 10); } } }; private void loadDoc() { String s = ""; for (int x = 0; x <= 100; x++) { s += "Line: " + String.valueOf(x) + "\n"; } textView.setText(s); textView.setMovementMethod(new ScrollingMovementMethod()); } } 

El texto personalizado: Importante: ¡el truco era conseguir la posición de desplazamiento!

 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.util.AttributeSet; import android.widget.TextView; /** * @author WarrenFaith */ public class MyTextView extends TextView { private Bitmap mBitmap; public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); } public MyTextView(Context context) { super(context); } public MyTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public Bitmap getBitmap() { return mBitmap; } @Override protected void onDraw(Canvas canvas) { mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(mBitmap); c.translate(0, -getScrollY()); super.onDraw(c); super.onDraw(canvas); } } 

El xml: (Quité el ScrollView y dejar que el TextView manejar el desplazamiento)

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/parentLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <com.testproject.MyTextView android:id="@+id/scrapbook" android:layout_width="400px" android:layout_height="200px" android:scrollbars="vertical" android:scrollbarSize="3px" android:text="" android:background="#0000ff" /> <Button android:id="@+id/upBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Up" /> <Button android:id="@+id/downBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Down" /> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 
  • Texto de Android alrededor de error de imagen
  • Android: singleLine de TextView es nolonger en el "Deprecated"?
  • Animación del tamaño de texto de TextView
  • Sobreponiendo problema en Android TextView
  • Android setMovementMethod en un TextView dentro de un ListView
  • Cómo hacer que TextView se desplace en Android
  • Android enlaza sin primer carácter
  • Cómo configurar el estilo de fuente en negrita, cursiva y subrayado en un Android TextView?
  • Cómo cambiar el texto de textView de fragmento de la actividad
  • Android y mostrar texto de múltiples líneas en un TextView en un TableRow
  • Haga que el contenido de textview contenga texto en negrita y regular
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.