SlidingMenu 在 Android 5.0 上不能刷新界面的bug解决方法

1 简介

SlidingMenu在Android 5.0上存在兼容性问题,在有多个Fragment切换的Activity中,如果同时存在SlidingMenu,则打开一次侧滑菜单,界面就卡住了,不能刷新,不能切换Fragment。
最近,测试给提了个bug,说在华为P8手机上侧滑菜单打开后,不能切换卡项,经过一番研究,发现这个是Slidingmenu在5.0上存在的兼容问题,下面记录以下研究过程。

2 bug重现

先上图,MainActivity有侧滑菜单和多个Fragment,点击下面的按钮依次切换三个Fragment,如图是正常情况:

SlidingMenu 在 Android 5.0 上不能刷新界面的bug解决方法_第1张图片

接着来看bug, 只要打开一次侧滑菜单,界面就卡住了,点击下面的按钮不能切换卡片,但是实际上是切换了的,只是界面没有刷新而已,如图:

SlidingMenu 在 Android 5.0 上不能刷新界面的bug解决方法_第2张图片

看到了吗,虽然点击了卡项2,但是界面并没有刷新

3 bug示例

(1) 主界面布局就下面一排按钮,加一个FrameLayout作为Fragment的容器
layout\activity_main.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:id="@+id/ly_bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal"
        >

        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="卡片1"
            />

        <Button
            android:id="@+id/btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="卡片2"
            />

        <Button
            android:id="@+id/btn3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="卡片3"
            />
    LinearLayout>

    <FrameLayout
        android:id="@+id/ly_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/ly_bottom">
    FrameLayout>
RelativeLayout>

(2) MainActivity中加入Slidigmenu,每次点击按钮就会切换Fragment
MainActivity:

public class MainActivity extends Activity implements View.OnClickListener {

    private SlidingMenu menu;
    private Fragment1 f1 = new Fragment1();
    private Fragment2 f2 = new Fragment2();
    private Fragment3 f3 = new Fragment3();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn1).setOnClickListener(this);
        findViewById(R.id.btn2).setOnClickListener(this);
        findViewById(R.id.btn3).setOnClickListener(this);
        this.initMenu();
    }

    private void initMenu() {
        menu = new SlidingMenu(this);
        menu.setMode(SlidingMenu.LEFT);
        menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        menu.setShadowWidth(300);
        menu.setBehindOffset(200);
        menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        menu.setMenu(R.layout.left_menu);
    }

    @Override
    public void onClick(View v) {
        FragmentTransaction tr = getFragmentManager().beginTransaction();
        switch (v.getId()) {
            case R.id.btn1:
                Toast.makeText(this, "点击了卡项1", Toast.LENGTH_SHORT).show();
                tr.replace(R.id.ly_content, f1);
                break;
            case R.id.btn2:
                Toast.makeText(this, "卡项2被点击了", Toast.LENGTH_SHORT).show();
                tr.replace(R.id.ly_content, f2);
                break;
            case R.id.btn3:
                Toast.makeText(this, "点击了卡项3", Toast.LENGTH_SHORT).show();
                tr.replace(R.id.ly_content, f3);
                break;
        }
        tr.commit();
    }

}

(3) 三个Fragment是相同的,就一个TextView,然后设一下背景,这里只列举第一个,其余两个改下字体颜色和背景
layout\layout_fragment_1.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="卡片1"
        android:textColor="@android:color/holo_green_dark"
        android:textSize="24sp"
        />

RelativeLayout>

Fragment1.java:

public class Fragment1 extends Fragment {

    public static Fragment1 newInstance(Context context) {
        Fragment1 fragment = new Fragment1();
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.layout_fragment_1, null);
    }
}

详细代码请看附件

4 bug原因

这个具体原因也不清楚,只是在Android 5.0上出现,例如:华为P8。在Android 6.0则不存在,所以,归结为SlidingMenu的兼容问题

5 解决方法一:

第一种解决方法是开启硬件加速

在AndroidManifest.xml文件中在application标签中添加属性 android:hardwareAccelerated=”false”,如图:

SlidingMenu 在 Android 5.0 上不能刷新界面的bug解决方法_第3张图片

但是,这种方法有个缺点,就是开启了硬件加速之后,如果碰到非常复杂的界面布局,嵌套太多的话,就会报StackOverflow的错误,可以自己百度一下,如果你恰好遇到一个喜欢留个FrameLayout,然后在代码里面不停的removeAllView()、addView(),动态添加布局的猪一样的队友,那么恭喜你,很有可能遇到我说的情况。顺便说一下,优雅的解决复杂布局的方法是用多个Fragment来拆开复杂界面、分离页面逻辑
万一你遇到开启硬件加速后,复杂界面报错的情况怎么办呢?别着急,临时关闭硬件加速就可以了,告诉机器,这个界面不要硬件加速。

首先找到报错的那个界面,例如MainActivity,然后设置这个Activity的属性,针对这个Activity不要使用硬件加速就可以了,如图:

SlidingMenu 在 Android 5.0 上不能刷新界面的bug解决方法_第4张图片

如果这个猪一样的队友写的报错界面太多了,你总不能一个一个去找吧,所以,就有第二种方法,直接修改SlidingMenu的源码

6 解决方法二:

修改SlidingMenu.java,定位到第1005行,将下面的代码:

boolean layer = percentOpen > 0.0f && percentOpen < 1.0f;

改为:

boolean layer = percentOpen >= 0.0f && percentOpen <= 1.0f;

推荐使用这种方法,好了,问题解决。

7 后记

博主是参考了StackOverflower上面这篇文章解决的:

http://stackoverflow.com/questions/28563240/ui-not-refreshed-after-first-toggle-the-sliding-menu-on-android-5-0-lollipop

这个bug我已经提到Github上SlidingMenu的issue了,详见下面地址:

https://github.com/jfeinstein10/SlidingMenu/issues/754

SlidingMenu的坑真是不少啊,已经发现两个了,之前博主发现一个bug,写了一篇博客,参见:

SlidingMenu addIgnoreView() 无效的bug解决方法

8 demo下载地址:

本文演示用的demo已上传,下载地址:http://download.csdn.net/detail/fuchaosz/9548810

9 转载请注明来自”梧桐那时雨”的博客:http://blog.csdn.net/fuchaosz/article/details/51657984

Tips
如果觉得这篇博客对你有帮助或者喜欢博主的写作风格,就给博主留个言或者顶一下呗,鼓励博主创作出更多优质博客,Thank you.

你可能感兴趣的:(android,bug记录)