jfeinstein10 / SlidingMenu

An Android library that allows you to easily create applications with slide-in menus. You may use it in your Android apps provided that you cite this project and include the license in your app. Thanks!
Apache License 2.0
11.07k stars 5.03k forks source link

Laggy Drag #262

Open Pirdad opened 11 years ago

Pirdad commented 11 years ago

When dragging, just at the start, there's a lag/delay so it doesn't seem smooth. But after it starts, it gets better. Same thing happens when it's in the open position and your trying to close it by dragging. Tested the latest commit on the Galaxy Note. Just for the curiosity's sake, I reset the branch to commit 2bd360d1853096174d4e32258b127e0e65832be0 and it's much smoother. So I'm not sure whether it's a new change that cause this, but is anyone else also having this issue?

jwoolston commented 11 years ago

On a cursory guess, I would say this is caused by the same as #252. I did experience the same and my somewhat hackish fix is to force constant use of hardware layers (not just when dragging). In this way, after the view is drawn once (happens when the view becomes visible), the display lists do not need to be executed to start scrolling.

jwoolston commented 11 years ago

Also, the commit you referenced changed the README file only.

Pirdad commented 11 years ago

Oh yeah the commit was just random that was suppose to be about a month back. I remember trying out this library earlier back on the same device and it was working very smoothly so I just tried it on that commit. I'm not exactly sure what has been changed since then.

jwoolston commented 11 years ago

A fair bit but as far as things which might cause it to become more laggy in that sense, nothing that has caught my eye. What level of complexity do you have in your views for both the menu and the content? The menu itself is fairly low overhead so I would guess you are in a situation like I am where you have display lists which take a while to draw. One other thing you can try is that the library in the last major commit (which would be after your previous evaluation) enforced hardware layers but applies them to the mContent of mCustomViewAbove and mCustomViewBehind. My testing has shown that doing this on mCustomViewAbove/Behind results in faster drawing and thus smoother scrolling. In my fork of this library, I comment out the manageLayers() method body in SlidingMenu and instead implement my own in a CanvasTransformer. I should also mention that doing this required me to change the visibility of the views in SlidingMenu. You could instead just replace the method body in SlidingMenu.

Pirdad commented 11 years ago

Well, I am starting a new app so really, I don't have any complex layouts. Right now I am just setting up slidingmenu so I don't have anything like listviews etc. Only thing is one TextView for the back view layout. But in any case, I'll look at it a little deeper and try what you mentioned above. Thanks for the help.

jwoolston commented 11 years ago

If your views really are that light weight it may point to a problem after all. My suggestions should still help alleviate the problem.

jwoolston commented 11 years ago

@Pirdod, I just looked back over my code and realized that I eventually switched back to putting the hardware layers on the views returned by the getContent() methods. My apologies for the misinformation. I do still use them 100% of the time, in spite of Romain Guy's advice to the contrary.

Pirdad commented 11 years ago

Alright, I will take a look over my code and see if I can find anything. Thanks for letting me know.

RobGThai commented 11 years ago

I also has this issue. As a test, I just put one TextView as a menu and leaving content blank and it still lag when the ViewBehind about to open/close. Afterward, the dragging is silky smooth. The example app runs perfectly on the same device tho. I kept the implementation as simple as possible. All I did was changing FragmentActivity to SherlockFragmentActivity as guided. I added SlidingMenu by attaching it manually, not sure if that could possibly be the cause of this.

awiden commented 11 years ago

Hi!

Saw this problem when I updated to fix another bug. The problem is the constant switching between hardware and software drawing, and is caused by the posting of messages on the UI-thread by:

SlidingMenu.java:972 Workaround: Just comment out the code in this method.

I'll let the devs fix this since I have no idea the idea around switching and the git log doens't give me a better understanding.

Bug introduced in: https://github.com/jfeinstein10/SlidingMenu/commit/fa64e7aa52f1be9d2e9e051396f90197f4da7639

Thanks for the library guys!

jwoolston commented 11 years ago

The reason for the switching back in forth is that the hardware layers consume a fair bit of memory in the graphics hardware, causing (potentially) other problems. In our app we get around this by commenting that section of the library and enforcing constant hardware layer usage but we dont place any other demands on the gpu.

morganwu commented 11 years ago

hi guys,

I have the same issue, and after comparing my own app with the sample, I found the only real difference was my app kept running GC when sliding, but not happen in the sample. As the main thread will stop and wait when GC, so sure it will lag. Maybe you guys can check if you also have the GC issue.

jwoolston commented 11 years ago

This is interesting. I have not noticed anything like this but I wasn't paying much attention to it. I will do some looking into it and let you know.

morganwu commented 11 years ago

I just tried two cases: 1, including my own ui and activity in sliding menu sample 2, importing those of the sample into my project

then I got the same result, for case 1, it still lags and there is still GC issue, for case 2, no lag, no GC issue.

83 is a relevant issue.

morganwu commented 11 years ago

I found some even more strange things by running the exactly same code in my own project and the example and tracking memory allocation, the allocation for the example is low and stable. Here is the top allocations:

456 248 int[]   1   java.lang.Throwable nativeFillInStackTrace  
463 240 int[]   1   java.lang.Throwable nativeFillInStackTrace  
340 178 char[]  1   android.support.v4.view.VelocityTrackerCompat   <clinit>    
337 178 char[]  1   java.lang.VMClassLoader loadClass   
333 160 char[]  1   dalvik.system.DexFile   defineClass 
330 160 char[]  1   java.lang.VMClassLoader loadClass   
461 156 char[]  1   android.support.v4.view.MotionEventCompat   <clinit>    

While it's quite different for my app, there are some unknown bitmaps:

60  1005856 byte[]  1   android.graphics.Bitmap nativeCreate    
28  1005856 byte[]  1   android.graphics.Bitmap nativeCreate    
12  1005856 byte[]  1   android.graphics.Bitmap nativeCreate    
165 58782   byte[]  4   org.apache.harmony.dalvik.ddmc.DdmVmInternal    getRecentAllocations    
272 45411   byte[]  4   org.apache.harmony.dalvik.ddmc.DdmVmInternal    getRecentAllocations    
353 35230   byte[]  4   org.apache.harmony.dalvik.ddmc.DdmVmInternal    getRecentAllocations    
436 312 int[]   1   java.lang.Throwable nativeFillInStackTrace  

and I dumped the stack trace, found it happened in the 'dispatchDraw' method of 'CustomViewAbove' and 'CustomViewBehind', here it is:

  at android.graphics.Bitmap.nativeCreate(Native Method)    
  at android.graphics.Bitmap.createBitmap(Bitmap.java:922)  
  at android.graphics.Bitmap.createBitmap(Bitmap.java:897)  
  at android.view.View.buildDrawingCache(View.java:10653)   
  at android.view.ViewGroup.drawChild(ViewGroup.java:3040)  
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)   
  at com.slidingmenu.lib.CustomViewAbove.dispatchDraw(CustomViewAbove.java:831) 
  at android.view.View.draw(View.java:11017)    
  at android.view.ViewGroup.drawChild(ViewGroup.java:3186)  
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)   
  at android.view.ViewGroup.drawChild(ViewGroup.java:3184)  
  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)   
  at android.view.View.draw(View.java:11017)    
  at android.widget.FrameLayout.draw(FrameLayout.java:450)  
  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2175) 
  at android.view.ViewRootImpl.draw(ViewRootImpl.java:2234) 

I'm sure I was using the same layout to do these testing, so I have no idea what is wrong.

jwoolston commented 11 years ago

@MorganWu, What version of android is this running on? Based on what you stated a few days ago and what you are stating with regards to the bitmap, I'm guessing this is a pre-honeycomb device and you are leaking your bitmap memory to some degree. If the sample app also lagged with your UI there must be something in your UI (this is the same issue I have, my UI needs to be made more efficient). Are you using fragments?

morganwu commented 11 years ago

@jwoolston, my device is of 4.0.3, and yes I'm using fragment by extending my activity from SlidingFragmentActivity as same as the sample app. One point I might not state clearly, actually it didn't lag with running the sample app with my UI, so I suppose it is not the matter of UI. And from another point of view, the sample UI should be ok as the sample runs smoothy, but it also laged when I ran my own app with it.

jwoolston commented 11 years ago

@MorganWu, are you performing any fragment transactions? Especially some that might be handled differently between the two implementations?

morganwu commented 11 years ago

hi Jared, Thanks for your constant response, I do need fragment transactions for production environment, but for these testing, my case is very simple. I just open a single view, and then drag. I was also trying to find out what the difference, but got no clue so far. I'll try to extract a quite simple sample from my app, and try again.

jwoolston commented 11 years ago

Morgan, if you can pare it down to an example which demonstrates it which you are free to send my way I would be happy to dig through it in an effort to shed some light on it. I have a suspicion of the cause in my case and am working towards that end but I am not ruling out other alternatives especially given the similarities in behavior between our two apps

kalisky commented 11 years ago

Hi, I'm also interested in a fix for this, here's the simplest code that reproduces it:

I know the xmls can be simpler, but using these, you see the lag easily

package com.slidingmenu.example;

import android.app.Activity;
import android.os.Bundle;

import com.slidingmenu.lib.R;
import com.slidingmenu.lib.SlidingMenu;

public class SlidingMenuTest extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        SlidingMenu menu = new SlidingMenu(this);
        menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        menu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
        menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        menu.setMenu(R.layout.mymenu);
    }
}

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button1" />

            <Button
                android:id="@+id/button2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button2" />

            <Button
                android:id="@+id/button3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Button3" />
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

mymenu.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical">
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!"/>
</LinearLayout>
tracyboehrer commented 11 years ago

I experience this lag on a Galaxy Nexus, just on the first open. Oddly though, on a Razr HD or Nexus 7 I don't notice it at all. My menu layout is not too different than the previous poster. I have a vertical LinearLayout with around 12 or so TextViews.

jwoolston commented 11 years ago

The difference is due to the relative power of the GPU compared to the screen. The Nexus 7 makes apps appear to perform very well.

jwoolston commented 11 years ago

I would note too that after speaking with MorganWu for a few days, I was unable to replicate the lag he is experiencing however I do believe it exists, but I have to wonder if it is something outside his app.

kalisky commented 11 years ago

The code I posted earlier displays the lag on every swipe, both open and close, and it happens to me on Galaxy S3. The SlidingMenu Demos work well on the same device...

jwoolston commented 11 years ago

Are you using attachToActivity on your own or using one of his classes that manages that already?

kalisky commented 11 years ago

On my own, see the code I attached above https://github.com/jfeinstein10/SlidingMenu/issues/262#issuecomment-14166132

jwoolston commented 11 years ago

Hmmm, that confuses things some. Morgan's code makes use of SlidingFragmentActivity. Mine is like yours and when I tried SlidingActivity I experienced no difference. I will keep trying to find a clue as this is still immediately relevant to my app as well. Let me know if you discover any other info, I will do the same.

marcelhoffs commented 11 years ago

I'm integrating this library in my app right now and I experience the same. Initial drag is laggy, afterwards it is butter smooth.

JesseFarebro commented 11 years ago

As well experiencing the inital drag and from time to time some tear in the drag, as well as noted in the OP before commit 2bd360d it was smoother.

JesseFarebro commented 11 years ago

Rdio pushed an update today with presumably the updated SlidingMenu library they noted in the change log there were ui performances. Anyways you can see this initial drag lag is super bad with there implementation and just to note as well I'm getting this choppiness on an S3 as well.

ghost commented 11 years ago

As awiden has pointed out, I simply changed line 975 of SlidingMenu.java from: boolean layer = percentOpen > 0.0f && percentOpen = 1.0f; to: boolean layer = percentOpen >= 0.0f && percentOpen <= 1.0f;

And the issue dispeared.

Hi!

Saw this problem when I updated to fix another bug. The problem is the constant switching between hardware and >software drawing, and is caused by the posting of messages on the UI-thread by:

SlidingMenu.java:972 Workaround: Just comment out the code in this method.

I'll let the devs fix this since I have no idea the idea around switching and the git log doens't give me a better >understanding.

Bug introduced in: fa64e7a

Thanks for the library guys!

kalisky commented 11 years ago

Seems like that fixes it for me! Thanks yishun!

morganwu commented 11 years ago

It works for me too! Thanks a lot.

RobGThai commented 11 years ago

I'm still experiencing minimal lag but after applying yishun fix it was much greatly smoother. So the lag was probably my phone.

vstyle commented 11 years ago

I am experiencing minimal lag bug as well and also the scrolling became laggy in other list views in my app after applying yishun's fix, rolled back the changes...

nachtien commented 11 years ago

What is the impact of this fix that yishun proposed? What are the odds that this will break on some devices but not others?

ghost commented 11 years ago

Hi! First of all, i'd like saying, thanks to jfeinstein to write this android library! Anyway, I used the fragment sample code, with some modify in the layout file, like adding some EditText, TextView, and SeekBar, but when I commit the transactions, with a click on a ListView, it shows a perceptible lag. The question i'd like to ask is: Can I do an action (in this case, switching the fragment), when the fragment is correctly finished loading? In my opinion, the lag, is caused by an "live" loading of the fragment, when it's not already loaded. I don't know if you got me.

Sorry for my English.

sidiqpermana commented 11 years ago

Hi .. this is great library, but when i try to implement this library with fragment which download some data from webservice , i always got lag problem when the first open of slide,, i had implement the newest and the same problem always apprea.. please help me to fix this problem,

Thank You

stackoverflows commented 11 years ago

I don't know if this is related, but I noticed significant improved when I set android:hardwareAccelerated="true" in the Manifest for each Activity.

sidiqpermana commented 11 years ago

Thank you for the answer but unfortunately it doesnt work for me, im using this lib with fragment and viewpager in single FragmentActivity,, and he problem is in when the first open by clicking the side menu icon. Does anyone face the same problem like me?

Thx

kosiara commented 9 years ago

I had the "laggy drag" problem described here. I had a listview inside SlidingMenu which consisted of elements - image + textview. The lag turned out to be a listview optimization problem. SlidingMenu refreshes listview many time a second and so listview elements need to be as much optimized as possible. The funny thing for me was that the lag appeared on some devices more than on others. On an old Samsung I9100 everything was smooth and on HTC One M7 it was laggy as hell.

I optimized the method: public View getView(int position, View convertView, ViewGroup parent)

using view.setTag() and view.getTag() method for recycling created views.

I'd also scaled down the images to 30x30 pixels. I helped a lot. I did NOT even had to touch the method public void manageLayers(float percentOpen) in SlidingMenu.java.