i cannot load an image in picasso from my drawable due to resons known only to picasso, so whever picasso fails to load i want to load a default image please help
#Override
public Object instantiateItem(ViewGroup container, final int position) {
final Context context =getApplicationContext();
final ImageView imageView = new ImageView(getApplicationContext());
int padding = context.getResources().getDimensionPixelSize(
R.dimen.padding_medium);
imageView.setPadding(padding, padding, padding, padding);
PicassoTools.clearCache(Picasso.with(context));
((ViewPager) container).addView(imageView, 0);
imageView.setTag("myview" + position);
Picasso.with(context).load(mImages[position]).resize(320,280).centerInside().placeholder(placeholderDrawable)
.into(imageView,new Callback() {
#Override
public void onError() {
// TODO Auto-generated method stub
imageView.setImageResource(R.drawable.c3);
}
#Override
public void onSuccess() {
// TODO Auto-generated method stub
}
});
iv included callback in the hope to do something but my brain is not working, any1 help
Picasso.with(context).load(www.google.com/image/1).placeholder(context.getResources().getDrawable(R.drawable.default_person_image)).error(context.getResources().getDrawable(R.drawable.default_person_image)).into(pictureView);
This is what i'm currently using (placeholder URL of course). It will try and load the image you provide in the "load()" part, will show the "placeholder()" part before it has downloaded the image, and if it fails it will show the "error()" part.
Personally i have both the placeholder() and error() part to show the same image, but you can load two different images.
Related
I have implemented a shared element activity transition animation between MainActivity (GridView) and DetailActivity. When item is clicked, the image in Grid item will zoom-in to become the background image in DetailActivity. I have made the transition very smooth by saving the image on the MainActivity into a file, then use it as placeholder image in DetailActivity before the higher quality image is downloaded via picasso. When picasso finished its task the higher quality image will replace the placeholder one very neatly.
Code from onCreateView() in DetailActivityFragment.java
ImageView iv = (ImageView) mRootview.findViewById(R.id.movie_poster);
try {
// Prepare "InterimPoster" jpeg file to be placeholder image
Bitmap bitmap = BitmapFactory.decodeStream(c.openFileInput("InterimPoster"));
Picasso.with(c).load("http://image.tmdb.org/t/p/w780" + mMovieInfo[2])
.placeholder(new BitmapDrawable(getResources(), bitmap))
.fit()
.centerCrop()
.noFade()
.into(iv);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
As for animation, I implement it like in the link here step 1-3 https://guides.codepath.com/android/Shared-Element-Activity-Transition
However, sometimes there's flicker when the higher quality image finished download before the transition animation is completed. The zooming-in image will be replaced with new image while moving which is an unpleasant animation.
So I wonder how can I fix this flicker? One thing I can think of is to delay the image download because I already have lower quality image as a placeholder. How can I do that?
Here the video.
Usually, on my test device it's smooth 80% of the time, but luckily in this video it flicker most of the time.
what's animation ? load image while animation end
TranslateAnimation translateAnimation = new TranslateAnimation(0,1.5f,0,1.5f);
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
//load image when animation end
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
and
LayoutTransition.TransitionListener transitionListener = new LayoutTransition.TransitionListener() {
#Override
public void startTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
}
#Override
public void endTransition(LayoutTransition transition, ViewGroup container, View view, int transitionType) {
//load image when animation end
}
};
Now I have found a way to delay Picasso image loading (or any other task). It's very simple really with the use of Handler and Runnable.
Now my code looks like this. The image replacement is pretty smooth in any case now.
// Set Background Poster in Try-catch in case file cannot be open
try {
// Get/Prepare "InterimPoster" jpeg file to be placeholder image
final ImageView iv = (ImageView) mRootview.findViewById(R.id.movie_poster);
final Bitmap bitmap = BitmapFactory.decodeStream(c.openFileInput("InterimPoster"));
final Drawable lowResPoster = new BitmapDrawable(getResources(), bitmap);
iv.setImageDrawable(lowResPoster);
// Download higher resolution image with 0.8 sec delay to avoid load complete before
// animation finishes (causing some flicker/overflow image problem).
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
Picasso.with(c).load("http://image.tmdb.org/t/p/w780" + mMovieInfo[2])
// still need placeholder here otherwise will flash of white image
.placeholder(lowResPoster)
.error(lowResPoster)
.fit()
.centerCrop()
.noFade() // without this image replacement will not be smooth
.into(iv);
}
};
handler.postDelayed(runnable, 800);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Try the below code:
First use picasso normally to load placeholder into the imageview
iv.setImageBitmap(bitmap);
Then use SharedElement Listener like this
Transition sharedElementEnterTransition = getWindow().getSharedElementEnterTransition();sharedElementEnterTransition.addListener(new TransitionListenerAdapter() {
#Override
public void onTransitionEnd(android.support.transition.Transition transition) {
super.onTransitionEnd(transition);
Picasso.with(c).load("http://image.tmdb.org/t/p/w780" + mMovieInfo[2])
.placeholder(new BitmapDrawable(getResources(), bitmap))
.fit()
.centerCrop()
.noFade()
.into(iv);
}
});
To delay some process, you can use Handler().
Example.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// write your codes here.. this will delay 2 seconds...
startActivity(new Intent(this,MySecondActivity.class);
}
},2000);
I'm using Glide to load images on Scale ImageView - it is a custom view with pan and zoom gestures. I should pass Bitmap object to this custom view in order to set picture.
So I can use Glide's .asBitmap() with SimpleTarget:
private SimpleTarget target = new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
scaleImageView.setImage(ImageSource.bitmap(bitmap));
}
};
private void loadImageSimpleTarget() {
Glide
.with(context)
.load(url)
.asBitmap()
.into(target);
}
This code snippet works well, but I will get fullsize Bitmap, which can lead to OutOfMemoryErrors. Also I could specify desired Bitmap size on constructor like this: ...new SimpleTarget<Bitmap>(250, 250)..., but I would have to manually calculate dimensions.
Is there a possibility to pass view (instance of CustomView) to Glide's request, so dimensions will calculated automatically and receive Bitmap object as a result?
Continuing the discussion from the comments, you get 0 for width and height when calling it from onCreateView. However, you can set a listener to be notified when the bounds of the view are actually calculated and then you can get the real width and height by calling getWidth or getHeight:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// ...
// your other stuff
// ...
// set listener
customView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("debug", "width after = " + customView.getHeight());
// pass the width and height now that it is available
target = new SimpleTarget<Bitmap>(customView.getWidth(), customView.getHeight()) {
#Override
public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) {
scaleImageView.setImage(ImageSource.bitmap(bitmap));
}
};
// remove listener, we don't need to be notified again.
customView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
I have made a ViewPager using davemorrissey's SubsamplingScaleImageView
When sliding the ViewPager, the next slide appears to be blank for some seconds before the image loads.
Has anyone faced same type of issue ? Any pointers for possible fixes ?
viewPager = (ViewPager) findViewById(R.id.pager);
magePagerAdapter adapter = new ImagePagerAdapter();
viewPager.setAdapter(adapter);
ArrayList<String> imageFull = new ArrayList<String>();
for(int i=0;i<10;i++){
String image = "mnt/sdcard/imageDemo"+i+".jpg";
imageFull.add(image);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Context context = ImageGallery.this;
SubsamplingScaleImageView fullImage = new SubsamplingScaleImageView(ImageGallery.this);
fullImage.setImage(ImageSource.uri(imageFull.get(position)));
return fullImage;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((SubsamplingScaleImageView) object);
}
Your Screen is black cause the image is not decoded yet.
You can use:
public final void setImage(ImageSource imageSource, ImageSource previewSource)
and use a thumbnail as preview. The preview is shown until the decoding of the image is finished.
Note that:
the Preview image cannot be used unless dimensions are provided for the main image.
No tested but something like:
Uri uri = imageFull.get(position);
Bitmap preview = MediaStore.Images.Thumbnails.getThumbnail(
getContentResolver(), uri,
MediaStore.Images.Thumbnails.MINI_KIND,
null);
ImageSource src = ImageSource.uri(uri);
src .dimensions(w, h); // if you don't know the size, you can just decode the bounds of your image which is quite fast
fullImage.setImage(src , ImageSource.bitmap(preview));
If generation of the Thumbnail is to slow for you, feel free to do that in an AsyncTask.
I was able to workaround it with this patch. I also wrote a similar answer in the visibility problem issue
initialiseBaseLayer is called the first onDraw of the view, that's why it doesn't load until the page is partially visible.
The issue is that initializing outside onDraw you lose access to the canvas, which is used to calculate the max bitmap dimensions:
private Point getMaxBitmapDimensions(Canvas canvas) {
if (VERSION.SDK_INT >= 14) {
try {
int maxWidth = (Integer)Canvas.class.getMethod("getMaximumBitmapWidth").invoke(canvas);
int maxHeight = (Integer)Canvas.class.getMethod("getMaximumBitmapHeight").invoke(canvas);
return new Point(maxWidth, maxHeight);
} catch (Exception e) {
// Return default
}
}
return new Point(2048, 2048);
}
So, you will have to provide the max dimensions on your own. I'm using this function. I store the value during the onCreate of the activity and later the ViewPager get that value.
Before setting the image call fullImage.setMaxDimensions(x, y) and that's it.
It works fine (in my case) for a ViewPager, but it doesn't on a RecyclerView, so use it with care.
I am using Picasso for background loading of images (list view and ImagePager). I can set loading image and errorimage with Picasso, but I am unable to show a "loading in progress" Image during background loading.
Has anybody an idea how to get this done? In my PagerAdapter Class I have the following method:
#Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(context);
int padding = context.getResources().getDimensionPixelSize(R.dimen.padding_medium);
imageView.setPadding(padding, padding, padding, padding);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
// Set default Image before loading real image
imageView.setImageResource(R.drawable.img_def);
imageView.setId(imgViewId);
imageView.setClickable(true);
imageView.setOnClickListener(this);
((ViewPager) container).addView(imageView, 0);
// Set default Image before loading real image
Picasso.with(context).load(R.drawable.img_def).into(imageView);
// Load real image with Picasso and show error image if failed
Picasso.with(context).load(GalImgUrls[position]).error(R.drawable.no_img).into(imageView);
return imageView;
}
However, it does not show the "loading..." image. Any solutions/ideas?
Thanks!
Looks like I found a solution myself. Use "placeholder" image:
Picasso.with(context).load(tnu).error(R.drawable.no_img).placeholder(R.drawable.img_def).into(holder.immoPic);
Works like charm....
I have done enough searching and finally I am asking this question.
I am converting gallery of imageviews into Viewpager backed up by PagerAdapter. I was able to achieve this:-
In onpageselected I am getting the position which I am using to get the red border.
Problem:-
Only the left most imageview is returned in onpageselected(). The rightmost imageview can never come to left and thus cannot be selected. Further on touching an imageview onpageselected() does not get called. It only gets called when you swipe it.
Questions:-
How to centre the selected imageview?
How to get the imageview position on touching it?
Thanks to NathanZ he gave me some direction. Finally I had to set a OnClickListener() on the ImageView not the ViewPager.
public Object instantiateItem(ViewGroup container, int position) {
// TODO Auto-generated method stub
MyImageView grpView = new MyImageView(ctxt);
final int temp=position;
grpView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
pos=temp;//This is the value what I am interested in
}
});
grpView.setLayoutParams(new LayoutParams((int)(109*density), (int)(109*density)));
myViewPager.addView(grpView);
return grpView;
}