在 Android 中拍摄特定布局的“屏幕截图”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10650049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:30:36  来源:igfitidea点击:

Taking a "screenshot" of a specific layout in Android

androidscreenshot

提问by Reuben L.

I have two main issues which are closely linked. I am looking at these problems from a programmatic point of view.

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

(1) - I wish to take a screenshot of the contents of a SPECIFIC layout, i.e. a ScrollViewnested in a LinearLayout.

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

(2) - As the ScrollViewhas content that spills out of the screen (hence scrolling made possible), how can I ensure that the screenshot includes the elements that are not visible on the screen?

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

This is the current block of code I use. It does the job of taking a screenshot but only for the entire screen. This is even though R.id.bossis the ID of the ScrollViewand not the main LinearLayout.

这是我当前使用的代码块。它可以截取屏幕截图,但仅限于整个屏幕。即使这R.id.boss是 的 IDScrollView而不是 main的 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);

Thanks in advance.

提前致谢。

EDIT:

编辑:

I've made a few mistakes. I used R.id.bosswhich is the wrong resource. I am now able to take a screenshot of the scrollview alone, less the out-of-screen parts.

我犯了一些错误。我使用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>

回答by Reuben L.

Thanks to you guys, I've finally found out what was wrong.

多亏了你们,我终于知道出了什么问题。

View v = view.getRootView();should not be used because it will call the root view which I do not want. I mistakenly thought this did not make a difference because I had entered the wrong resource ID.

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

MeasureSpecsomehow did not give a good account of the width and height. So I ended up using another method:

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

As ScrollView's total height can be determined by the single child element that it has.

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

After making these changes, I am now able to take a screenshot of a nested ScrollView and all its contents, visible or not. For anyone interested, here is the block of code including the saving of the bitmap:

进行这些更改后,我现在可以截取嵌套的 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();
            }

回答by Mahtab

try this it works fine for me

试试这个对我来说很好用

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

回答by Krishnabhadra

EDIT : after seeing OP's comment

编辑:在看到 OP 的评论后

You dont need to think about new activities at all.. Say you are in Activity right now.. Layout A is the main layout for the activity, Layout B and C are two child layouts inside Layout A. Like this,

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

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

Now if you want to take screenshot of C only

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

1) in onCreate() of activity

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

where getDrawingBitmap() is a function..to take your screenshot..

其中 getDrawingBitmap() 是一个函数..截取你的截图..

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

    File file = saveBitmapAsFile(b);
}

EDIT: For ScrollView

编辑:对于滚动视图

I never tried it.. But I think you can do this..

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

1) first override scrollView, and override onMeasure function..

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

and use MyScrollView in your layout.. here yourFullScrollViewHeight is the height of all scrollView content you need to take screenshot of.. I never tried this.. But it might work..

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

回答by Nirav Dangi

Here is the exact solution you want, It will display entire screen including content hidden in your ScrollView

这是您想要的确切解决方案,它将显示整个屏幕,包括隐藏在您的 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)

Display bitmapin your ImageViewor use it as you want.
Enjoy..

显示bitmap在你ImageView或你想使用它。
享受..

回答by muruganvel

I also had this problem and coded it myself.

我也有这个问题并自己编码。

I used this code to take screenshot of whole layout.

我使用此代码截取整个布局的屏幕截图。

I did modified the list size and some mathematical items.

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

See the following website,

请参阅以下网站

回答by Thilina Anuradh

Try this code

试试这个代码

public Bitmap screenShot(View view) {

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

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