I have a card view which has a custom adapter and it loads image into its target using Picasso(inside onBindViewHolder(lazy load) ).
The custom row has a button on which when clicked opens fragment which displays image in wide view , Using the bitmap from original imageview
( before in fragment i check if bitmap is loaded fully in main imageview using a boolean in callback of Picasso to 'true' in onSucess() . till then my button is disabled ) like :
BindViewHolder:
Picasso.with(context)
.load(cl.getUrlPhoto())
.resize(500, 500)
.error(R.drawable.images)
.into(cardViewHolder.urlPhoto, new Callback() {
#Override
public void onSuccess() {
cardViewHolder.imgL=true;
cardViewHolder.fab.setEnabled(true);
cardViewHolder.pb_b.setVisibility(View.INVISIBLE);
}
#Override
public void onError() {
cardViewHolder.imgL=false;
cardViewHolder.fab.setEnabled(false);
cardViewHolder.pb_b.setVisibility(View.GONE);
}
});
(i check here for the boolean to be true then do this part of code )Fragment part where it loads :
imageView.buildDrawingCache(true);
Bitmap bitmap = imageView.getDrawingCache(true);
BitmapDrawable bitmapDrawable = (BitmapDrawable)
imageView.getDrawable();
bitmap1 = bitmapDrawable.getBitmap();
scaleImageView.setImageBitmap(bitmap1);
. But Sometimes on scrolling when the images are still loading or loaded or just clicking to view full image 2-3 times it crashes and gives error
" RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap . "
This exception is raised in situations where you try to recycle or set to null an image which is loaded by Picasso which means the Picasso library does not expect the image loaded by it to be recycled and when it tries to load that an exception is thrown. hope this solution works for you
Try replacing Picasso with Glide
Related
I am using WebView for loading websites in my project. It is loading websites but very slow. It takes around 10 to 15 seconds to load this site.
I try a solution from this thread. I have added android:hardwareAccelerated="true" on the manifest under application level, but no luck.
For iOS and Windows the solution is below: But I don't know how to create the custom render.
In iOS, try to use WKWebView instead of UIWebView.
For the UWP, use Windows.UI.Xaml.Controls.WebViewcontrol instead of using the built-in Xamarin WebView control.
Can I get the sample custom renderer for iOS and Windows-like above?
It is loading websites but very slow
The speed of loading website will up to lots of causes . For example, it will consume a lot of time if the web contains many remote css/js file . And it will also up to network performance .
The link that you provided loads slow even if on browser on my side . It contains lots of remote css if we check the source code.
For Android , We can create an custom renderer webview to accelerate it.
Set Render Priority to hight.
Enable the dom storeage.
When Loading the html, we can disable the image showing, when
loading finished, load the image by
Control.Settings.BlockNetworkImage.
Enable the Cache, if you load it at the nexttime, you can load it
quickly.
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyWebviewRender))]
namespace MyWebviewDemo.Droid
{
public class MyWebviewRender : WebViewRenderer
{
public MyWebviewRender(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
Control.Settings.JavaScriptEnabled = true;
Control.Settings.SetAppCacheEnabled(true);
Control.Settings.CacheMode = Android.Webkit.CacheModes.Normal;
Control.Settings.SetRenderPriority(RenderPriority.High);
Control.Settings.DomStorageEnabled = true;
Control.Settings.BlockNetworkImage = true;
Control.SetWebChromeClient(new MyWebChromeClient());
}
}
internal class MyWebChromeClient : WebChromeClient
{
public override void OnProgressChanged(Android.Webkit.WebView view, int newProgress)
{
base.OnProgressChanged(view, newProgress);
if (newProgress == 100)
{
// webview load success
// // loadDialog.dismiss();
view.Settings.BlockNetworkImage=false;
}
else
{
// webview loading
// loadDialog.show();
}
}
}
}
In iOS, try to use WKWebView instead of UIWebView. For the UWP, use Windows.UI.Xaml.Controls.WebViewcontrol instead of using the built-in Xamarin WebView control.
In your case it will only have less improve even if using above solution . You could add an ActivityIndicator during the loading . If you can access the website , it would be better to download the css file to local and loading them in ContentPage .
I'm using ImageView ( javafx ), I tried to load an image (jpg), it works, and when i try to load another it is not (I tried gif, png, also another jpg). I also tried to change the name of the image loaded before, and same, it doesn't load.
It just work with the first image, with same name.
I declared this :
#FXML
private ImageView imageView;
AND this is the code that worked:
InputStream is = this.mainApp.getClass().getResourceAsStream("..\\resources\\images\\facture\\recuBank\\2015\\22-12-2015\\12080351_10206938666998884_3823913475123618229_o.jpg");
if(is != null)
{
Image img = new Image(is);
this.imageView.setImage(img);
}
AND this doens't worked :
// I renamed the first image
InputStream is = this.mainApp.getClass().getResourceAsStream("..\\resources\\images\\facture\\recuBank\\2015\\22-12-2015\\a.jpg");
if(is != null)
{
Image img = new Image(is);
this.imageView.setImage(img);
}
Hope someone can help
WOW I solved it just by doing a REFRESH in folder "resources", in my project (in Eclise).
I was adding the images directly in the folder, so in my project, Eclise is not aware that any change happened.
I have a page that displays data about an object. At the top of the page is room for an icon, showing a picture of that object. Tapping this icon brings up a new page that allows the user to take a new picture, and save it as a temporary new picture for the object (not put in database, but should persist for the session)
Initial page:
private var source:Object = new Object();
protected function onInitialize():void {
source = navigator.poppedViewReturnedObject;
}
When setting source for the image later...
if (source != null) {
pic.source = source.object;
}
else {
pic.source = "no_picture_available_image.png";
}
2nd Page (User can take picture, and view new picture):
[Bindable]
private var imageSource:Object = null;
<s:Image id="pic" width="90%" height="75%" horizontalCenter="0" source="{imageSource}" />
After taking picture...
protected function mediaPromiseLoaded(evt:Event):void {
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
imageSource = loaderInfo.loader;
}
This does show the picture just taken correctly on this page.
To get back to old page, i use navigator.popView, and use:
override public function createReturnObject():Object {
return imageSource;
}
Unfortunately, it doesn't work. The imageSource isn't null when it is read from navigator.poppedViewReturnedObject, but no image is shown.
Does the LoaderInfo not persist after popping the view? Are the camera pics not automatically saved? I can't find answers to any of these questions, and I can't debug using the phone in my current environment.
After thinking about this a bit, don't return LoaderInfo.loader as the poppedViewReturnedObject. If I remember correctly, a DisplayObject can only be set as the source of one Image. Instead, return LoaderInfo.loader.content.bitmapData. That BitmapData should be the raw data used to display the image. This data can be used repeatedly to create images and can be set as the source of an Image.
Problem turned out to be in my first page's image declaration - I didn't set a width. Seemingly, the object being displayed couldn't handle not having a specified width.
Note that passing back the loader did work fine.
I'm developing an application with a menu which contains a list of buttons, when you click one of these buttons, another activity (the same activity with different image for each button) is opened showing an imageview. The problem is that when i click several times in different buttons (opening new images) the app crashes and i'm not able to solve it. Any help? Thanks.
That problem is because your are using a lot of images in your views and never clean the memory, then in one momento your don't have more memory for the new ones.
One form to resolve that problem is cleaning the memory always your destroy and activity.
You can override the next method in your activity for clean the memory.
#Override
public void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
that method review a view, in your case those views will be your ImageView and ImageButton.
Finally you need call this method in the method onDestroy() (need override that method too).
How can I copy or duplicate the bitmapdata from a mx:image component?
I need to display the same image in multiple screens of my application and don't want to have to download the image multiple times.
I could just use a urlrequest to download the image as a bitmap and copy that but I like the way you can can just set the source of the image component.
Image extends SWFLoader which has a content property that will contain the Bitmap object that was loaded. Wait for the image to load, cast the content to Bitmap and read its bitmapData
public function imageLoadCompleteHandler(e:Event):void
{
var bitmap:Bitmap = img.content as Bitmap;
if(bitmap == null) {
trace("loaded content is not an image");
return;
}
bmpData = bitmap.bitmapData;
//hurray..!
}
Actually after reading the message above (and trying stuff out) I think this is wrong. The Complete listener fires on my second image so I guess it is loading it twice. Oh well.
I couldn't place the whole Flex doc, but this seemed to work. I added this to the Application tag: applicationComplete="Run();"
The following is wrapped in a mx:Script tag:
import mx.controls.Image;
private function Run():void
{
var i:Image = new Image();
i.source = first.source;
addChild(i);
}
And this is just a Image outside of the script tag:
<mx:Image x="12" y="125" source="e53c04a51d5992fb77ab1e20c45ddc9f.jpeg" id="first" />
I also tried this after setting the i source:
first.source = null;
Just to see what happens, the i image keeps it's source