Recyclerview is Laggy? - java

I am following the tutorial in this link to learn about RecyclerView. The tutorial loads images from drawable folder. When I do the same the app just runs out of memory. So I made a little change to resize images.
#Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
viewHolder.title.setText(galleryList.get(i).getImage_title());
viewHolder.img.setScaleType(ImageView.ScaleType.CENTER_CROP);
viewHolder.img.setImageResource((galleryList.get(i).getImage_ID()));
}
Changed the 3rd line to this
viewHolder.img.setImageDrawable(scaleImage(galleryList.get(i).getImage_ID(), ScaleFactor));
And defined scaleImage as
private Drawable scaleImage(int imageId, float scaleFactor)
{
Drawable image = context.getResources().getDrawable(imageId);
if ((image == null) || !(image instanceof BitmapDrawable)) {
return image;
}
Bitmap b = ((BitmapDrawable)image).getBitmap();
int sizeX = Math.round(image.getIntrinsicWidth() * scaleFactor);
int sizeY = Math.round(image.getIntrinsicHeight() * scaleFactor);
Bitmap bitmapResized = Bitmap.createScaledBitmap(b, sizeX, sizeY, false);
image = new BitmapDrawable(context.getResources(), bitmapResized);
return image;
}
But as I scroll RecyclerView lags until It loads the coming rows which I think is because I load each image individually and then resize it. Is there a way to do this asychronously?

It's become cause you are resizing the image, it's a heavy process.
try to resize images async or use image loader libs.
There are some useful libraries you can use for loading images like Glide
Also, you can see this Picasso v/s Imageloader v/s Fresco vs Glide

Related

Screenshot not captured while agora.io video call Android Java

I have implemented a video calling feature in our app. There is a button which captures the screenshot of specific view. On video call there a two views Local View and Remote View. These are actually Relative and Frame layouts. In this case i want take screenshot of remote view but it's just giving me a blank image. I think somehow agora video calling not allowing it but there should be any settings or something to disable this but that i have not found yet. here is the code:
Setting up remote video:
mRemoteContainer is a RelativeLayout and mRemoteVideo is VideoCanvas by agora.io
Similarly mLocalContainer is FrameLayout.
private void setupRemoteVideo(int uid) {
ViewGroup parent = mRemoteContainer;
if (parent.indexOfChild(mLocalVideo.view) > -1) {
parent = mLocalContainer;
}
if (mRemoteVideo != null) {
return;
}
SurfaceView view = RtcEngine.CreateRendererView(getBaseContext());
view.setZOrderMediaOverlay(parent == mLocalContainer);
parent.addView(view);
mRemoteVideo = new VideoCanvas(view, VideoCanvas.RENDER_MODE_HIDDEN, uid);
mRemoteVideo.view.setWillNotDraw(false);
mRtcEngine.setupRemoteVideo(mRemoteVideo);
}
This function used to get bitmap from the view
private Bitmap getScreenShotFromView(View v) {
Bitmap screeShoot = null;
try {
screeShoot = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(screeShoot);
v.draw(canvas);
} catch (Exception e) {
Log.e("GFG", "Failed to capture screenshot because:" + e.getMessage());
}
return screeShoot;
}
I tried function call with both view but getting black or blank image
Bitmap bitmap = getScreenShotFromView(mRemoteVideo.view);
Bitmap bitmap = getScreenShotFromView(mRemoteContainer);
Your help will be really appreciated for me as i stuck on this issue.
By the way I used the same view capturing technique on iOS with swift
and Its working fine.

How to take full scrolled screenshot in flutter_native_screenshot

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

Bitmap not updating/ showing old values

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.

how to read images from "Drawable" instead of "SD Card" Android

i am beginner in android programing, and i created a Full Screen Image Slider app using this tutorial:
Link:
http://www.androidhive.info/2013/09/android-fullscreen-image-slider-with-swipe-and-pinch-zoom-gestures/
in this tutorial it reads images from Sd Card but i want to read images from drawable folder, i don't want to access images from SD Card instead access images from drawable.
This is the way I've seen, I hope it is correct:
private Bitmap bitmap = null;
private void createBitmap(Context context)
{
Resources resources = context.getResources();
Drawable d = resources.getDrawable(R.drawable.imagename);
Bitmap bitmap = ((BitmapDrawable) d).getBitmap();
this.bitmap = bitmap;
}
It can be done like this:
Drawable drawable = this.getResources().getDrawable(R.drawable.image);
where this refers to the context of the actual activity.
OR
you can just give the name of the image and then you can get the image using getIdentifier,
getResources().getIdentifier(name,"drawable", getPackageName());
Where name will be the name of your image i.e - "image1"

Add an image as background and put other images on top of it

I am creating an image by using Canvas- and Bitmap class. I want to set it as a background for the user. Then I want to add some more images on top of it.
this is the code for image that is supposed to be as background.
ImageView imgMap1 = (ImageView) findViewById(R.id.imgMap1);
imgMap1.setImageDrawable(new BitmapDrawable(Bitmap.createBitmap(bmp, 0, 0, 500, 500)));
and this is the code to make it as background:
LinearLayout ll = new LinearLayout(this);
ll.setBackgroundResource(R.drawable.nn);
this.setContentView(ll);
The Problem here is: When I set it as background, I can't see the other photo anymore.
How can I do this?
Thanks in advance.
The other Images are added in the Layout. they are movable by finger touch. user can reposition them by finger.
ImageView i1 = (ImageView) findViewById(R.id.Image1);
ImageView i2 = (ImageView) findViewById(R.id.Image2);
The layout is built from the top down in your XML file, or in the order you add elements in code. It sounds like your other images is being added to the layout first, either as a higher-up element in the XML file, or earlier in your code. You'll need to add the other code as context for a complete answer.
Just noticed that you can directly set Bitmap as your ImageView's content using setImageBitmap(Bitmap bm)See the Android Reference
Then let talk about your question.
First, create your own class extends the View;
Second, load background image and overlay image using Bitmap
Third, invoke onTouch event, so that the onDraw method will automatically redraw the overlay image using the coordinates returned by onTouch
Something like:
public class dragndrop extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// using this to load your background image
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565; // this is not a must
bmBackground = BitmapFactory.decodeFile(filePath, opt);
super.onCreate(savedInstanceState);
DrawView dv = new DrawView(dragndrop.this);
setContentView(dv);
}
public class DrawView extends View {
Point coordinate;
public DrawView(Context context) {
super(context);
setFocusable(true); //necessary for getting the touch events
}
#Override
protected void onDraw(Canvas canvas) {
// assume you have already load your background image as bitmap
canvas.drawBitmap(bmBackground, 0, 0, null);
// assume bm is the overlay image you need to put on top,
// the method here will draw the object with the coordinate you give
canvas.drawBitmap(bm, coordinate.x, coordinate.y, null);
}
// events when touching the screen
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int x = (int)event.getX();
int y = (int)event.getY();
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
// add code here to determine the point user touched is within the object or not
break;
}
}
break;
case MotionEvent.ACTION_MOVE: // touch 'n' drag
// pass the touch point to your object
coordinate.x = x;
coordinate.y = y;
break;
case MotionEvent.ACTION_UP:
// touch drop - just do things here after dropping
break;
}
// redraw the canvas
invalidate();
return true;
}
}
}
This is my own snippet, please edit before use, and please let me know when your question is resolved.

Categories