So in my Flutter project I'm using this plugin flutter_native_screenshot
It works quite well for single screenshot of the page, but it's not taking full scrollable screenshot. I've checked behind this plugin use a code like takeScreenshotOld()
View view = this.activity.getWindow().getDecorView().getRootView();
view.setDrawingCacheEnabled(true);
Bitmap bitmap = null;
if (this.renderer.getClass() == FlutterView.class) {
bitmap = ((FlutterView) this.renderer).getBitmap();
} else if (this.renderer.getClass() == FlutterRenderer.class) {
bitmap = ((FlutterRenderer) this.renderer).getBitmap();
}
The question is:- How can I make this code to take full scrolled screenshot.
I've tried flutter screenshot plugin as well but unfortunately it fails to capture flutter_tex (webview)
and shows blank. The native plugin worked but unable to get full page.
This answer is using Java but you can follow the same logic in flutter,
You will need to do the following steps:
Implement a listener to the scrollView scrolling, then every time the height is dividable by screen height, take a screenshot
Display display = getWindowManager().getDefaultDisplay();
int height = display.getHeight();
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged() {
int scrollY = targetScrollView.getScrollY();
if (scrollY % height == 0){
takeScreenShotAndSaveIt();
}
}
});
Manullay scroll through the scroll view
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
}
});
Finally you will remove scroll listener and merge the saved images of the screen shots.
Another option is to take the full view as bitmap and save it: https://stackoverflow.com/a/43817149/19074651
I have a linear layout that has multiple fields that are to be filled by the user. The fields are to be filled with text or decimal numbers and they are all TextInputLayouts with one date picker. After the user has filled those fields I have a review button which once clicked shows a preview of all the values entered in an image view. I am showing the image by using bitmap and canvas and sending the bitmap as an argument to my material bottom sheet with the following code.
private Bitmap getDailySheetBitmap() {
Bitmap bitmap = Bitmap.createBitmap(completeSheetLinearLayout.getWidth(), completeSheetLinearLayout.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Log.d("Bitmap", "bitmap size: "+bitmap.getByteCount());
completeSheetLinearLayout.draw(canvas);
return bitmap;
}
And the code for sending arg is
private void buildBottomSheet(Bitmap bitmap) {
Bundle args = new Bundle();
args.putParcelable("Bitmap", bitmap);
ViewDailySheet viewDailySheet = new ViewDailySheet();
viewDailySheet.setArguments(args);
viewDailySheet.show(getChildFragmentManager(), "DailySheet");
}
The problem is that after the user reviews the fields and changes are made to those fields and when the user again clicks on the review button, the bitmap with the same old values is shown. I have tried recycling bitmap, invalidating the view, requestLayout() and forceLayout() method. But none of it is helping.
This is the code that puts bitmap into image view.This is in bottom sheet dialog fragment.
if (getArguments() != null) {
bitmap = getArguments().getParcelable("Bitmap");
binding.dailySheetImage.invalidate();
binding.dailySheetImage.setImageBitmap(bitmap);
getArguments().clear();
}
What am I doing wrong or missing?
The bitmap only captures what it thinks has changed. If the text field(not the data, just UI) is not changed it will show the same text field value as before. So I refreshed the whole layout as it would re-draw the entire layout by the following code.
private void refreshView() {
completeSheetLinearLayout.setVisibility(View.GONE);
completeSheetLinearLayout.setVisibility(View.VISIBLE);
}
I put this code just before creating the bitmap.
I am relatively new to android development and so far I haven't picked up on the purpose of fragments. Anyways, I am trying to create a unique QR code for every user that sign's into my app. This QR code is filled with the user's info which I have retrieved from the database. Now the only trouble I am experiencing is the generation of said qr Code. I have looked through dozens of tutorials but oftentimes they are rendered invalid for my use case or I can't simply get them to work. I have also looked through the ZXING api but that was of not help. I ask of the StackoverFlow community to help with this endeavour and all help is appreciated
There is a slight difference usage between Activity and Fragment. Both of them can be used to show the UI. To use a fragment, you need the Activity as its host, because Fragment must always be embedded in the Activity.
From the documentation:
A Fragment represents a behavior or a portion of user interface in an
Activity. You can combine multiple fragments in a single activity to
build a multi-pane UI and reuse a fragment in multiple activities. You
can think of a fragment as a modular section of an activity, which has
its own lifecycle, receives its own input events, and which you can
add or remove while the activity is running (sort of like a "sub
activity" that you can reuse in different activities).
A fragment must always be embedded in an activity and the fragment's
lifecycle is directly affected by the host activity's lifecycle.
You need to read Building a Dynamic UI with Fragments to mastering the Fragment. The steps to create a Fragment (Note, this not a strict rule):
Create the Activity as the host
Create the layout for Activity. Within, you need to create a FrameLayout view as the fragment holder.
Create the Fragment by extending Fragment class
Create the UI layout for the Fragment
Attach the Fragment to Activity by using FragmentTransaction
Now the create QR code part. You need to determine what information need to be shown in your QR code. Don't give all information in the QR code, because you mustn't expose all your user data to the world. If you have more than 1 string of information, you can use ";" or anything else to join the text info.
To build the QR code image, first, you need to include the ZXing library by using the following line in your app build.gradle (use the latest version):
compile 'com.google.zxing:core:3.3.0'
Then create the QR code bitmap using the following code:
private Bitmap textToImage(String text, int width, int height) throws WriterException, NullPointerException {
BitMatrix bitMatrix;
try {
bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.DATA_MATRIX.QR_CODE,
width, height, null);
} catch (IllegalArgumentException Illegalargumentexception) {
return null;
}
int bitMatrixWidth = bitMatrix.getWidth();
int bitMatrixHeight = bitMatrix.getHeight();
int[] pixels = new int[bitMatrixWidth * bitMatrixHeight];
int colorWhite = 0xFFFFFFFF;
int colorBlack = 0xFF000000;
for (int y = 0; y < bitMatrixHeight; y++) {
int offset = y * bitMatrixWidth;
for (int x = 0; x < bitMatrixWidth; x++) {
pixels[offset + x] = bitMatrix.get(x, y) ? colorBlack : colorWhite;
}
}
Bitmap bitmap = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, Bitmap.Config.ARGB_4444);
bitmap.setPixels(pixels, 0, width, 0, 0, bitMatrixWidth, bitMatrixHeight);
return bitmap;
}
Then you can use it to set the generated image to your ImageView in your Fragment with something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.your_fragment_layout, container, false);
ImageView imvQrCode = (ImageView) view.findViewById(R.id.your_image_view);
Bitmap bitmap = textToImage("your_text_info", 500, 500);
imageView.setImageBitmap(bitmap);
return view;
}
You can find here how to create and use Fragments. But for generating QR Code I found one which is very tiny and smart library QRGen
Sample Code:
Bitmap myBitmap = QRCode.from("www.example.org").bitmap();
ImageView myImage = (ImageView) findViewById(R.id.imageView);
myImage.setImageBitmap(myBitmap);
try {
Bitmap bitmap= encodeAsBitmap("Muhammad Qasim Android Developer", BarcodeFormat.QR_CODE, Width, Height);
if (bitmap!= null) {
img.setImageBitmap(bitmap);
}
} catch (WriterException e) {
Log.e(""+e,"Exception");
}
I'm trying to display a captured image from a camera intent, but when I call a showPhoto method the image isn't shown in the ImageView. There is no error output to the stack trace so I'm not sure how the issue can be debugged.
Does anyone know what is wrong with the method that its not showing the captured image?
The showPhoto method is as follows:
private void showPhoto(Uri photoUri) {
String filePath = photoUri.getEncodedPath();
File imageFile = new File(filePath);
//File imageFile = new File(photoUri.getPath());
if (imageFile.exists()){
Drawable oldDrawable = photoImage.getDrawable();
if (oldDrawable != null) {
((BitmapDrawable)oldDrawable).getBitmap().recycle();
}
Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath());
BitmapDrawable drawable = new BitmapDrawable(this.getResources(), bitmap);
photoImage.setScaleType(ImageView.ScaleType.FIT_CENTER);
photoImage.setImageDrawable(drawable);
}
}
This is the tutorial that I've followed: http://www.linux.com/learn/tutorials/722038-android-calling-the-camera
The device I'm testing on is JellyBean 4.1 and this is the link to the complete class:
http://hastebin.com/oqokupulol.java
Use BitmapOptions.inJustDecodeBounds to find out the dimension of the image first
Typically, Android won't load images larger than 4000px wide/tall
If you find out the image is too large, you can use BitmapOptions.inSampleSize to downscale the image so that Android would load it
And in fact, you can directly use ImageView.setImageBitmap(Bitmap) instead of setImageDrawable
Here is my code
// create bitmap screen capture
Bitmap bitmap;
View v1 = (View)findViewById(R.id.text);
View rootV = v1.getRootView();
rootV.setDrawingCacheEnabled(true);
bitmap = rootV.getDrawingCache();
rootV.setDrawingCacheEnabled(false);
the nullpointer occurs on bitmap = rootV.getDrawingCache(); and R.id.text is a textView in the layout
I was able to find the answer here. Its because I was calling the method in the onCreate()
Screen capture inside the method onCreate not working in android