I have a TextView in 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 is has a lot of text that's why is scrollable. I need to draw the current visible content in TextView to Bitmap. For testing purposes I display this bitmap in ImageView. I have the following code:
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());
}
}
The problem is that once I scroll TextView (trigger TouchEvent) the Bitmap doesn't reflect the current content of TextView and instead always has only the beginning content of TextView (it doesn't matter what's the current scroll position). I updated post to provide working code - maybe it will work on sb's other device.
UPDATE
I also tried to check WarrenFaith idea by overriding onDraw
in my custom TextView but it somehow still only draw the begining content of 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);
}
}
Try to override the onDraw()
method of the TextView
should work. There you can create a bitmap based on the canvas parameter. Details can be found in my tutorial: How to create and save a screenshot from a SurfaceView
Update:
I fixed your issue:
The activity (I changed the Handler usage and removed some methods. Basically I shrinked the code a bit).
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());
}
}
The custom textview: Important: the trick was to get the scrolling position!
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);
}
}
The xml: (I removed the ScrollView and let the TextView handle the scrolling)
<?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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With