Comments (12)
Hi Gang,
I believe I have identified the cause and a solution to the issue of Picasso triggerring continuous calls to the getView method of the adapter.
First, the issue (for me) only arises when I use the .fit() method with Picasso. This method causes Picasso to wait until the ImageView is loaded, and dimensions are obtained, before making the network/in-memory call(s) necessary prior to calling setImageDrawable.
One of the idiosyncrasies of setImageDrawable on an ImageView is that it triggers an onMeasure and onLayout, according to this SO post.
If you were to avoid using the .fit() method, the call to Picasso.load.into would also call setImageDrawable and call requestLayout, but calls to requestLayout in the middle of a layout pass have no effect. However, if you defer the call to setImageBitmap, then you end up in a cycle where a layout pass is calling getView, which is calling Picasso, which does a deferred setImageBitmap, which (a few ms later) requests a layout pass, ad infinitum.
Why does this work normally with ListViewAdapters? I am not entirely sure, but something in this Swipecards implementation of onLayout is causing it to constantly create new views. I suspect that ListViewAdapters know how to "recycle" views, so that if you have a ListView of 5 items laid out, and you call onLayout, it won't re-create 5 views but will instead re-use the 5 views on screen and thus avoid triggering Picasso again.
Regardless - I have a proposed fix. In the nominal case, onLayout is repeatedly called until there is both an active and top card, meaning we end up in this code here:
if(mActiveCard!=null && topCard!=null && topCard==mActiveCard) {
removeViewsInLayout(0, LAST_OBJECT_IN_STACK);
layoutChildren(1, adapterCount);
}else{
This code has the effect of re-laying out the cards behind the top card, and is necessary for cards in the back to be aligned properly as the card in the front is moving, in the event that they interact. If you aren't actively dragging or manipulating the top card, you don't need to do anything with the layout, because the code just below will have already taken care of it. Thus, we need a new method to detect when the user is actively manipulating the top card. I added this code to FlingCardListener.java:
public boolean isTouching() {
return this.mActivePointerId != INVALID_POINTER_ID;
}
public PointF getLastPoint() {
return new PointF(this.aPosX, this.aPosY);
}
And then changed SwipeFlingAdapterView.java, lines 104-105, to this:
if(mActiveCard!=null && topCard!=null && topCard==mActiveCard) {
if (this.flingCardListener.isTouching()) {
PointF lastPoint = this.flingCardListener.getLastPoint();
if (this.mLastTouchPoint == null || !this.mLastTouchPoint.equals(lastPoint)) {
this.mLastTouchPoint = lastPoint;
removeViewsInLayout(0, LAST_OBJECT_IN_STACK);
layoutChildren(1, adapterCount);
}
}
}else{
I also added PointF mLastTouchPoint
as a member variable. Per this change for me, this will now only call getView when the user is actively moving the top card or at Activity onCreate.
Cheers!
from swipecards.
Can you describe this issue in more detail? Did not encounter this issue or maybe just didn't notice yet?!
from swipecards.
I am using Universal Image Loader, and it is working fine with SwipeCards.
from swipecards.
I'm receiving OutOfMemory crashes on Google Play during beta testing of an app with your (awesome) library.
I'm also using Picasso to set card backgrounds in getView from adapter.
You have any suggestions how to prevent this? Txn.
(Report from Samsung Galaxy S4 with Android (4.4)
android.view.InflateException: Binary XML file line #17: Error inflating class
at android.view.LayoutInflater.createView(LayoutInflater.java:626)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:675)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:700)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
at be.accentjobs.swop.ui.MainActivity$JobAdapter.getView(MainActivity.java:408)
at flingswipe.SwipeFlingAdapterView.layoutChildren(SwipeFlingAdapterView.java:122)
at flingswipe.SwipeFlingAdapterView.onLayout(SwipeFlingAdapterView.java:109)
at android.view.View.layout(View.java:15655)
at android.view.ViewGroup.layout(ViewGroup.java:4856)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1055)
at android.view.View.layout(View.java:15655)
at android.view.ViewGroup.layout(ViewGroup.java:4856)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:15655)
at android.view.ViewGroup.layout(ViewGroup.java:4856)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1677)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1531)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1440)
at android.view.View.layout(View.java:15655)
at android.view.ViewGroup.layout(ViewGroup.java:4856)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
at android.view.View.layout(View.java:15655)
at android.view.ViewGroup.layout(ViewGroup.java:4856)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2284)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2004)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1236)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6471)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:573)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:600)
... 44 more
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
at android.content.res.Resources.loadDrawable(Resources.java:3056)
at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
at android.widget.ImageView.(ImageView.java:133)
at android.widget.ImageView.(ImageView.java:123)
... 47 more
from swipecards.
Hi niob,
I have solved this problem in my pull request, pleasee see below link.
#15
from swipecards.
I'll remove my previous comment because that's not related to the Picasso issue. But thanks @qichuan for the tip!
from swipecards.
OutOfMemory is usually a sign of memory leak. The problem is that picasso looks like it creates an infinite loop when interfering with async tasks (infinite calls of requestLayout).
Sorry guys but I cant help these days much. Will help after a week or so that i will be back on track.
from swipecards.
Any update on this issue?
from swipecards.
Not really. I would be glad to review a pull request however if someone digs into that.
from swipecards.
Same problem (getView continuously) when using android query or universal imageloader
comment out 2 lines below in SwipeFlingAdapterView seems do some help
...
if (mActiveCard != null && topCard != null && topCard == mActiveCard) {
// removeViewsInLayout(0, LAST_OBJECT_IN_STACK);
// layoutChildren(1, adapterCount);
} ...
from swipecards.
The last comment fixes the issues for me too! Can someone fix this in the main rep? Would be awesome :)
regards
Simon
from swipecards.
thank u @esilverberg bro. U save my day (Y) 🥇
from swipecards.
Related Issues (20)
- supports text only HOT 2
- Why do we need stop animation when componentWillReceiveProps(nextProps)?
- ViewPager is not working inside SwipeFlingAdapterView Adapter HOT 2
- Fragment in card
- Creating a SwipeFlingAdapterView with a CardView fragment that uses YouTube Thumbnail API
- How to alter min adapter stack? HOT 1
- How to clear when nothing to load?
- Next Card doesn't swipe on first touch. HOT 2
- How to fire current card onclick event programmatically
- ViewPager
- How to update the button state in top card?
- How to display text while dragging image?
- Is there an eta for 2.0.0?
- NullPointerException because ArrayAdapter is null when flingswipe tries to set it
- Not set again adaptorin SwipeFlingAdapterView
- How to Implement this Library on a Fragmen?
- Get index of selected Item HOT 1
- Gradle please is obsolete
- Issue
- remove fling gesture and program the gestures to button
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swipecards.