【问题标题】:Taking a "screenshot" of a specific layout in Android在 Android 中拍摄特定布局的“屏幕截图”
【发布时间】:2012-05-18 09:29:02
【问题描述】:

我有两个密切相关的主要问题。我是从程序化的角度来看待这些问题的。

(1) - 我希望截取特定布局的内容,即嵌套在 LinearLayout 中的 ScrollView

(2) - 由于ScrollView 的内容会溢出屏幕(因此可以滚动),我如何确保屏幕截图包含屏幕上不可见的元素?

这是我当前使用的代码块。它可以截取屏幕截图,但仅适用于整个屏幕。 即使R.id.bossScrollView 的ID 而不是主要的LinearLayout

View view = findViewById(R.id.boss);
View v = view.getRootView();// this does not seem to make a difference
v.setDrawingCacheEnabled(true);                                                
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());    
v.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());             
v.setDrawingCacheEnabled(false);

提前致谢。

编辑:

我犯了一些错误。我使用了R.id.boss,这是错误的资源。我现在可以单独截取滚动视图的屏幕截图,而不是屏幕外部分。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/boss"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="top"
android:orientation="vertical" >

    <TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="F"
    android:textAppearance="?android:attr/textAppearanceMedium" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Analyze via image URL"
        android:textAppearance="?android:attr/textAppearanceSmall" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
             >

                        <EditText
                            android:id="@+id/mUrl"
                            android:layout_width="fill_parent"
                            android:layout_height="wrap_content"
                            android:layout_weight="0.7"
                            android:text="http://" >

                            <requestFocus />
                        </EditText>

                        <ImageView
                            android:id="@+id/call"
                            android:layout_width="75dp"
                            android:layout_height="50dp"
                            android:layout_weight="0.3"
                            android:text="ABC"
                            android:src="@drawable/run" />

        </LinearLayout>

     <TextView
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:text="ABC"
         android:textAppearance="?android:attr/textAppearanceSmall" />

     <LinearLayout
         android:layout_width="fill_parent"
         android:layout_height="wrap_content" >

         <EditText
             android:id="@+id/filepath"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_weight="0.55" />

         <ImageView
             android:id="@+id/cam"
             android:layout_width="75dp"
             android:layout_height="50dp"
             android:layout_weight="0.15"
             android:src="@drawable/cam" />

         <ImageView
             android:id="@+id/browse"
             android:layout_width="75dp"
             android:layout_height="50dp"
             android:layout_weight="0.15"
             android:src="@drawable/folder"
             android:text="B" />

         <ImageView
             android:id="@+id/upload"
             android:layout_width="75dp"
             android:layout_height="50dp"
             android:layout_weight="0.15"
             android:src="@drawable/run"
             android:text="A" />
     </LinearLayout>


     <LinearLayout
         android:id="@+id/baba"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical" >


         <ScrollView
             android:id="@+id/scroll"
             android:layout_width="fill_parent"
             android:layout_height="150dp"
             android:layout_weight="0.7" >

             <LinearLayout
                 android:layout_width="fill_parent"
                 android:layout_height="186dp"
                 android:orientation="vertical" >

                 <ImageView
                     android:id="@+id/pic"
                     android:layout_width="fill_parent"
                     android:layout_height="fill_parent"
                     android:layout_weight="1" />

                 <TextView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Facial recognition"
                     android:textAppearance="?android:attr/textAppearanceMedium" />

                 <TextView
                     android:id="@+id/text3"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Small Text"
                     android:textAppearance="?android:attr/textAppearanceSmall" />

                 <TextView
                     android:id="@+id/avmarwe"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Gender and age"
                     android:textAppearance="?android:attr/textAppearanceMedium" />

                 <TextView
                     android:id="@+id/text1"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Small Text"
                     android:textAppearance="?android:attr/textAppearanceSmall" />

                 <TextView
                     android:id="@+id/skahasd"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Expression and mood"
                     android:textAppearance="?android:attr/textAppearanceMedium" />

                 <TextView
                     android:id="@+id/text2"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Small Text"
                     android:textAppearance="?android:attr/textAppearanceSmall" />

                 <TextView
                     android:id="@+id/dsfsfs"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Celebrity Facial Match"
                     android:textAppearance="?android:attr/textAppearanceMedium" />

                 <TextView
                     android:id="@+id/text4"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_weight="1"
                     android:text="Small Text"
                     android:textAppearance="?android:attr/textAppearanceSmall" />
             </LinearLayout>
         </ScrollView>

     </LinearLayout>


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom" >

        <Button
            android:id="@+id/c"
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:layout_weight="0.7"
            android:text="" />

        <Button
            android:id="@+id/share"
            android:layout_width="70dp"
            android:layout_height="50dp"
            android:layout_weight="0.3"
            android:text="" />

    </LinearLayout>

</LinearLayout>

【问题讨论】:

标签: android screenshot


【解决方案1】:

多亏了你们,我终于查明了问题所在。

View v = view.getRootView(); 不应使用,因为它会调用我不想要的根视图。我错误地认为这没有影响,因为我输入了错误的资源 ID。

MeasureSpec 不知何故没有很好地说明宽度和高度。所以我最终使用了另一种方法:

...
ScrollView z = (ScrollView) findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
u.layout(0, 0, totalWidth, totalHeight);
...

因为 ScrollView 的总高度可以由它所拥有的单个子元素来确定。

进行这些更改后,我现在可以截取嵌套的 ScrollView 及其所有内容(可见与否)的屏幕截图。对于任何感兴趣的人,这里是包含位图保存的代码块:

            View u = findViewById(R.id.scroll);
            u.setDrawingCacheEnabled(true);                                                
            ScrollView z = (ScrollView) findViewById(R.id.scroll);
            int totalHeight = z.getChildAt(0).getHeight();
            int totalWidth = z.getChildAt(0).getWidth();
            u.layout(0, 0, totalWidth, totalHeight);    
            u.buildDrawingCache(true);
            Bitmap b = Bitmap.createBitmap(u.getDrawingCache());             
            u.setDrawingCacheEnabled(false);

            //Save bitmap
            String extr = Environment.getExternalStorageDirectory().toString() +   File.separator + "Folder";
            String fileName = new SimpleDateFormat("yyyyMMddhhmm'_report.jpg'").format(new Date());
            File myPath = new File(extr, fileName);
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(myPath);
                b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.flush();
                fos.close();
                MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen");
            }catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

【讨论】:

  • 对不起,请问这些代码真的对您有帮助吗?我面临与您的问题相同的问题,但是当我尝试您的代码时,它没有显示我想要的视图,只有黑屏。
  • 是的,代码运行良好,应用程序于 2 年前发布。您是否相应地调整了变量?
  • ooppss 没看到这段代码`View u = findViewById(R.id.scroll);` 非常感谢....
  • 可以获得gridview的屏幕截图,我试过你的代码它需要整个gridview的高度和宽度,但不是内容(iamge)它显示黑框
  • 这行得通,但是我需要在截屏后重置 ScrollView 的宽度和高度。 u.layout(0, 0, totalWidth, totalHeight);代码更改尺寸。
【解决方案2】:

试试这个对我来说很好用

TableLayout tabLayout = (TableLayout) findViewById(R.id.allview);
if (tabLayout != null) {
    Bitmap image = Bitmap.createBitmap(tabLayout.getWidth(),
            tabLayout.getHeight(), Config.ARGB_8888);
    Canvas b = new Canvas(image);
    tabLayout.draw(b);
}

【讨论】:

    【解决方案3】:

    编辑:看到 OP 的评论后

    你根本不需要考虑新的活动..假设你现在在活动..布局A是活动的主要布局,布局B和C是布局A内的两个子布局。像这样,

     Layout A -> Parent
     |
      -------Layout B
     |
      -------Layout C
    

    现在如果你只想截取 C 语言的截图

    1) 在活动的 onCreate() 中

     LinearLayout myCLayout = (LinearLayout)this.findViewbyId(R.id.my_c_layout);
     ViewTreeObserver vto   =  myCLayout.getViewTreeObserver();
     vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
       @Override
       public void onGlobalLayout() {
          //fully drawn, no need of listener anymore
          myCLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
          getDrawingBitmap();
       }
     });
    

    其中 getDrawingBitmap() 是一个函数..截取您的屏幕截图..

    public void getDrawingBitmap(){
        LinearLayout myCLayout = (LinearLayout)this.findViewbyId(R.id.my_c_layout);
        Bitmap b = myCLayout.getDrawingCache();
    
        File file = saveBitmapAsFile(b);
    }
    

    编辑:对于 ScrollView

    我从未尝试过..但我认为你可以做到这一点..

    1) 先覆盖scrollView,再覆盖onMeasure函数..

    public class MyScrollView extends ScrollView{
        public MyScrollView(Context context, AttributeSet attrs) {
             super(context, attrs);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            super.onMeasure(widthMeasureSpec, yourFullScrollViewHeight));
        }
    }
    

    并在您的布局中使用 MyScrollView.. 这里 yourFullScrollViewHeight 是您需要截取屏幕截图的所有滚动视图内容的高度.. 我从未尝试过这个.. 但它可能会工作..

    【讨论】:

    • 我仍然无法使用这种方法拍摄整个滚动视图的完整图像。我想这与正常的屏幕外问题略有不同,因为不可见的滚动视图内容被视为屏幕外。
    • 请看我的编辑..我不能保证它是否会工作..但我是你我会尝试..
    • 抱歉,您在我给出答案后发布了您的 xml。您可能需要覆盖 scrollView 内的 LinearLayout,就像我在答案中覆盖 scrollView 一样。覆盖 onMeasure 并返回完整内容高度..然后当你截图时,截取线性布局(在scrollView里面的那个)而不是scrollView..我认为这会起作用..
    • 虽然我最终以另一种方式解决了这个问题,但我认为你可能是对的。感谢您的帮助!
    • @ReubenL。我想用 2 个子视图 ImageView 和 TextView 捕获 RelativeLayout 的屏幕,TextView 是可移动的,我已经尝试过代码,但没有得到位图,因为它在调用另一个 imageview 后没有显示。
    【解决方案4】:

    这是您想要的确切解决方案,它将显示整个屏幕,包括隐藏在您的 ScrollView 中的内容

    LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
    FrameLayout root = (FrameLayout) inflater.inflate(R.layout.activity_main, null); // activity_main is UI(xml) file we used in our Activity class. FrameLayout is root view of my UI(xml) file.
    root.setDrawingCacheEnabled(true);
    Bitmap bitmap = getBitmapFromView(this.getWindow().findViewById(R.id.frameLayout)); // here give id of our root layout (here its my FrameLayout's id)
    

    在您的ImageView 中显示bitmap 或随意使用它。
    享受吧..

    【讨论】:

      【解决方案5】:

      我也遇到了这个问题,自己写了代码。

      我用这段代码截取了整个布局。

      我确实修改了列表大小和一些数学项目。

      见下面website

      【讨论】:

        【解决方案6】:

        试试这个代码

        公共位图屏幕截图(查看视图) {

            Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
            view.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            view.draw(canvas);
            return bitmap;
        }
        

        【讨论】:

          猜你喜欢
          • 2018-04-22
          • 1970-01-01
          • 2012-04-22
          • 2014-01-12
          • 1970-01-01
          • 1970-01-01
          • 2016-03-30
          • 1970-01-01
          • 2014-05-16
          相关资源
          最近更新 更多