在 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
Taking a "screenshot" of a specific layout in Android
提问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 ScrollView
nested in a LinearLayout
.
(1) - 我希望截取特定布局的内容的屏幕截图,即ScrollView
嵌套在LinearLayout
.
(2) - As the ScrollView
has 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.boss
is the ID of the ScrollView
and 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.boss
which 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。
MeasureSpec
somehow 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 bitmap
in your ImageView
or use it as you want.
Enjoy..
显示bitmap
在你ImageView
或你想使用它。
享受..
回答by muruganvel
回答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;
}