捕获Horizo​​ntalScrollView的屏幕截图,包括屏幕外元素

时间:2013-01-09 11:37:51

标签: android screen-capture horizontalscrollview

我尝试了很多方法。我可以截取整个屏幕截图但我的要求是截取整个Horizo​​ntalScrollView并将其保存为图像文件。这是我正在使用的示例XML布局:

<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>

活动代码:

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);     
    }

如果我不使用MeasureSpec,我的布局高度和宽度都不正确。

点击按钮我只得到半按钮的图像。我认为这是因为我没有使用ViewTreeObserver。但是当我使用ViewTreeObserver时,我没有得到结果。此外,当我单击按钮两次时,应用程序崩溃 - 位图中的NullPointerException。

我已经尝试了StackOverFlow上几乎所有可用的东西。请帮我找到一种方法来做到这一点。它甚至可能吗?

2 个答案:

答案 0 :(得分:1)

找到了一种简单的方法。

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>

活动代码:

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();
}
}}

这里我在Horizo​​ntalScrollView中放置了一些元素。单击该按钮可获取屏幕截图,第二个图像将替换为所拍摄的屏幕截图。 它还截取了屏幕外元素的屏幕截图。您可以进一步增强代码并将最终位图图像保存在SD卡上。

答案 1 :(得分:0)

这是我第二次看到同样的问题(是的,这里是堆栈溢出),简单的答案是:没有简单的方法可以做到这一点!

保存屏幕截图的所有方法都使用相同的原则来启用绘图到位图缓存并获取此位图。 但如果视图不在屏幕上,则不会被绘制。

你可以创建一个非常复杂的系统,它可以自动滚动水平屏幕视图,拍摄几个屏幕截图并将不同的位图拼接在一起。或者可能是一个非常复杂的系统,它会创建一个无限宽度的画布并要求布局绘制它,但是在这种情况下你可能会耗尽内存。但正如我所说,这些都不是一项简单的任务。