关于fragment backstate的运用

来源:互联网 发布:excel 数据对比 编辑:程序博客网 时间:2024/04/29 18:46

这两天在使用Fragment做播放器里的播放列表和歌词显示两个界面的替换与更新时发现了很多问题,在此记录下问题及解决方法:


1.多个Fragment在replace后(并且都加入了后退栈ft.addToBackStack(null)),通过点击按钮事件移除顶层的fragment(使用remove方法),返回后的fragment的oncreatview方法有执行,但是页面仍然没法自行更新数据,页面空白,UI控件都消失了。


解决:不用remove方法,改用通过popBackStack()方法直接将栈顶的fragment弹出,然后直接恢复到要返回的那个fragment。

1
getSupportFragmentManager().popBackStack();


2.使用popBackStack()方法后,页面控件恢复了,但是数据并没有同步更新。


解决:这个问题困扰了很久,后来讲replace方法改成了add方法,并且在add之前将原先的fragment隐藏掉hide。这样在点击按钮收回播放列表的fragment后,返回的歌词fragment的显示进度是同步的了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 打开播放列表
private void btnClick_playinglist()
{
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    Fragment fragment = new PlayingListFragment();
    if (isOpenPlayingList)//播放类表是否已打开
    {
        getSupportFragmentManager().popBackStack();
        mPlaying_img_openlist.setImageResource(R.drawable.icon_playing_img_openlist);
        isOpenPlayingList = false;
    }
    else
    {
        ft.hide(mFragment);
        ft.add(R.id.playing_fragment_layout, fragment);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.addToBackStack(null);
        mFragment = fragment;
        mPlaying_img_openlist.setImageResource(R.drawable.icon_playing_img_openlist_press);
        isOpenPlayingList = true;
    }
    ft.commit();
}


3.通过按钮点击可以正常弹出顶层的播放列表fragment了,同时歌词界面的fragment仍然同步更新。但是用按钮点击打开播放列表fragment,然后用back键返回,第一次正常,多次后歌词fragment就开始变成空白。将fragment的背景颜色修改成红色,异常界面就是红色。由此可见,通过back键返回的fragment仍然没有恢复和更新。


解决:这个不清楚具体原因,应该是使用back返回键和通过调用popBackStack()方法来移除fragment的机制不一样所导致的。这个找不到具体的解决办法,只能先采用规避方法,通过重写back监听方法,进而调用popBackStack()解决了这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//重写监听back键按钮
@Override
public void onBackPressed()
{
    getSupportFragmentManager().popBackStack();
    if (isOpenPlayingList)//判断播放列表是否打开
    {
        mPlaying_img_openlist.setImageResource(R.drawable.icon_playing_img_openlist);
        isOpenPlayingList = false;
    }
    else
    {
        super.onBackPressed();
    }
}
0 0