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.08k stars 5.04k forks source link

Problem on rotate #77

Open acquariusoft opened 12 years ago

acquariusoft commented 12 years ago

HI

i use xml for enable slidemenu

with xml like

<?xml version="1.0" encoding="utf-8"?> <com.slidingmenu.lib.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:sliding="http://schemas.android.com/apk/res-auto" android:id="@+id/slidingmenulayout" android:layout_width="fill_parent" android:layout_height="fill_parent" sliding:viewAbove="@layout/xxxx" sliding:viewBehind="@layout/xxxx" sliding:behindWidth="@dimen/menu_slide_width" />

and se android:configChanges in androidManifest.xml

if i rotate the app the slidemenu not have the right with and sometimes it not work

Tnx for your great work!!

slidese commented 11 years ago

I'm not sure if I am having the same problem as you are describing above but I noticed that my sample app would not handle the width of the menu correctly when I'd flip the phone to landscape and the immediately click the home icon to reveal the menu.

It seem to be related to Android not loading the resources correctly.

Removing the android:configChanges="orientation|screenSize|screenLayout" form the manifest seem to have solved it.

cnordvik commented 11 years ago

I have the same problem where I actually need to have the android:configChanges="orientation|screenSize|screenLayout" of the activity. Then the menu is not displayed correctly, it seems to use the size of the previous orientation.

Is there a way to notify the menu that it needs to recalculate it's size because the device rotated?

tobrun commented 11 years ago

I'm also having problems with this. I have got a activity setup with androd:configChanges, this activity is responsible for managing my fragments.

The swipe implemenation works great but I have also setup the hardware options button to show the slidingmenu (by invoking the toggle() function) and replaced the ActionBar icon to do the same. The problem occurs when the function toggle() is called after an orientation change.

Is someone looking into this?

dani- commented 11 years ago

Joining the #77 club. And I think, I have a fix.

I'm using sliding menu on right side of screen and I have this in the manifest for my activity: android:configChanges="orientation | keyboardHidden | screenSize"

Reproducing the problem.

The problem is that, scroller is not getting the correct value for scrollX on orientation change.

I cannot remove android:configChanges="orientation | keyboardHidden | screenSize" as I need this for various other reasons.

Fixing

Added the below code to public void onConfigurationChanged(Configuration newConfig) in my activity.

int offset = (int) getResources().getDimension(R.dimen.menu_offset); // Menu offset dp
float density = getResources().getDisplayMetrics().density;
int w = (int)(newConfig.screenWidthDp * density); // New width
int h = (int)(newConfig.screenHeightDp * density); // New height
sm.getMenu().layout(0, 0, w - offset, h); // Update content for CustomViewBehind

sm is the SlidingMenu reference.

Actual fix should go to SlidingMenu: 1. SlidingMenu.java Add this

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (w != oldw){
            mViewBehind.resetSize(w, h);
        }
    }

2. CustomViewBehind.java Add this

    public void resetSize(int width, int height) {
        mContent.layout(0, 0, width-mWidthOffset, height);
        if (mSecondaryContent != null)
            mSecondaryContent.layout(0, 0, width-mWidthOffset, height);
    }

Replace line# 131-133 with an invoke to the new method (resetSize)

jfeinstein - Can you check if this is correct and if yes, add it to SlidingMenu.

Note: I love SlidingMenu.

menny commented 11 years ago

@danimonk, screenWidthDp field is available in API level 13 and higher. I'm wonderring if this will be enough (for the public void onConfigurationChanged(Configuration newConfig) code):

int offset = (int) getResources().getDimension(R.dimen.menu_content_offset);
DisplayMetrics dm = getResources().getDisplayMetrics();
int w = dm.widthPixels;
int h = dm.heightPixels;
menu.getMenu().layout(0, 0, w - offset, h); // Update content for CustomViewBehind
dani- commented 11 years ago

@menny you are correct. Need to find an option to support lower versions as well.

rogerheim commented 11 years ago

@danimonk lines 131-133 are in onMeasure(). Can't remove setMeasuredDimension(); what is the change you're making there?

dani- commented 11 years ago

@rogerheim Looks like the code has changed after I posting the comment. My suggestion was to extract the following lines of code from onLayout method

mContent.layout(0, 0, width-mWidthOffset, height);
if (mSecondaryContent != null)
     mSecondaryContent.layout(0, 0, width-mWidthOffset, height);

to the method resetSize (to be added new), so that this piece of code can be invoked from onSizeChanged (newly suggested method) in SlidingMenu.

:+1: Lesson learned: Do not use line numbers while explaining code :)

rogerheim commented 11 years ago

@dani- Got it. Thanks for the reply.

vinothbabu commented 11 years ago

@dani- tried what you indicated but no luck.

public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
    int offset = (int) getResources().getDimension(R.dimen.slidingmenu_offset); // Menu offset dp
    float density = getResources().getDisplayMetrics().density;
    int w = (int)(newConfig.screenWidthDp * density); // New width
    int h = (int)(newConfig.screenHeightDp * density); // New height
    getSlidingMenu().getMenu().layout(0, 0, w - offset, h);
}

Added the above code to my Activity class.

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (w != oldw){
            mViewBehind.resetSize(w, h);
        }
    }

Added the above to slidingmenu.java

public void resetSize(int width, int height) {
        mContent.layout(0, 0, width-mWidthOffset, height);
        if (mSecondaryContent != null)
            mSecondaryContent.layout(0, 0, width-mWidthOffset, height);
}

Added the above to CustomViewBehind.java

Ultimater commented 11 years ago

@dani- when we invoke your resetSize() method, what parameters should we be sending it? 0, 0, width,height or width-mWidthOfset,height? I'm guessing you want us to edit CustomViewBehind.java and find and replace

mContent.layout(0, 0, width-mWidthOffset, height);
if (mSecondaryContent != null)
     mSecondaryContent.layout(0, 0, width-mWidthOffset, height);

and edit it with:

@Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  final int width = r - l;
  final int height = b - t;
   mContent.resetSize(width, height);
 }

Is that correct?

Nandan078 commented 11 years ago

Dani, Jeremy - can any of you please help on this one if you have a solution?

dani- commented 11 years ago

@vinothbabu The changes to onConfigurationChanged method is a work around. You may choose one of the option below - not both at same time.

Option A Add/Modify onConfigurationChanged method as described above.

Option B

  1. Add onSizeChanged method to SlidingMenu.java
  2. Add resetSize method to CustomViewBehind.java
dani- commented 11 years ago

@Ultimater You are correct, except that in onLayout method, it is not

mContent.resetSize(width, height);

but just

resetSize(width, height);
dani- commented 11 years ago

@Nandan078 were you referring to questions by @vinothbabu and @Ultimater ?

Nandan078 commented 11 years ago

Yes Dani - was referring to the same things as Vinoth and Ultimater, thank you for the response. Will try your suggestion and keep you posted...