问题
I have tried many methods. I am able to take screenshot of whole screen BUT my requirement is to take screenshot of whole HorizontalScrollView and save it as an image file. Here is the sample XML layout I am using:
<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" >
<HorizontalScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/hsv" >
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:id="@+id/ll">
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:onClick="click"
android:id="@+id/b"
android:text="capture"
android:layout_margin="20dp"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/img1"
android:src="@drawable/plug1"
android:layout_margin="20dp"/>
<ImageView
android:layout_height="wrap_content"
android:layout_width="200dp"
android:id="@+id/img2"
android:src="@drawable/plug3"
android:layout_margin="20dp"/>
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
Activity Code:
Button b;
ImageView img1, img2;
LinearLayout ll; View v;
HorizontalScrollView s;
int h,w;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = (Button)findViewById(R.id.b);
img1 = (ImageView)findViewById(R.id.img1);
img2 = (ImageView)findViewById(R.id.img2);
ll = (LinearLayout)findViewById(R.id.ll);
s = (HorizontalScrollView) findViewById(R.id.hsv);
s.setDrawingCacheEnabled(true);
}
//Fired onClick of the button
public void click(View v) {
shoot();
}
// To capture layout, create a bitmap and replace an image with the resulting bitmap.
public void shoot() {
s.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
int totalHeight = s.getMeasuredHeight();
int totalWidth = s.getMeasuredWidth();
s.layout(0, 0, totalHeight, totalWidth);
s.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(s.getDrawingCache());
s.setDrawingCacheEnabled(false);
img1.setImageBitmap(b);
}
I don't get correct layout height and width if I don't use MeasureSpec.
OnClick of the button I am getting image of half button only. I think this is happening as I am not using ViewTreeObserver. But when i use ViewTreeObserver, I am not getting the result. Also, the application crashes when I click the button twice - NullPointerException in Bitmap.
I have tried nearly everything available on StackOverFlow. Please help me to find a way to do this. Is it even possible ?
回答1:
Found a SIMPLE way to do it.
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_gravity="center_vertical">
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:id="@+id/def"
>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="capture"
android:onClick="click"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/black"
android:id="@+id/img"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/a"/>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
Acivity Code:
public class CaptureBeyondActivity extends Activity {
/** Called when the activity is first created. */
LinearLayout def;
ImageView img;
HorizontalScrollView hsv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
def = (LinearLayout)findViewById(R.id.def);
img = (ImageView)findViewById(R.id.img);
}
public void click(View v) {
Bitmap bitmap;
def.setDrawingCacheEnabled(true);
def.buildDrawingCache(true);
bitmap = Bitmap.createBitmap(def.getWidth(), def.getHeight(),
Config.ARGB_8888);
def.layout(0, 0, def.getLayoutParams().width,
def.getLayoutParams().height);
Canvas c = new Canvas(bitmap);
def.draw(c);
def.setDrawingCacheEnabled(false);
if(bitmap!=null){
img.setImageBitmap(bitmap);
img.invalidate();
}
}}
Here I have placed some elements in a HorizontalScrollView. OnClick of the button a screenshot is taken and the second image is replaced by the screenshot taken. It takes screenshots of the offscreen elements also. You can further enhance the code and save the final bitmap image on SD card.
回答2:
it's the second time I see this same question (yes, here in stack overflow) and the simple answer is: There is no simple way to do it!
All the methods to save a screen shot uses the same principle of enabling the draw to the bitmap cache and obtaining this bitmap. But if the views are not on screen, they won't be drawn.
You could create a very complex system that would auto-scroll the Horizontal screen view, taking several screen shots and stitching the different bitmaps together. Or maybe a very complex system that would create an infinite width canvas and ask the layout to draw on it, but it's likely that you would run out of memory on this situation. But as I said, none of those is a simple task.
来源:https://stackoverflow.com/questions/14234371/capture-screenshot-of-a-horizontalscrollview-including-offscreen-elements