安卓-Viewpager和片段,方法不起作用

6

我有一个ViewPager,其中包含两个Fragments,我在FragmentActivityonCreate中实例化了它们。

private List<Fragment> fragments = new Vector<Fragment>();

fragments.add(Fragment.instantiate(this,Frag_1.class.getName()));
fragments.add(Fragment.instantiate(this,Frag_2.class.getName()));
    this.vPagerAdapter = new Adapt(super.getSupportFragmentManager(),fragments);
    vPager = (ViewPager) super.findViewById(R.id.pager);
    vPager.setAdapter(vPagerAdapter);

我的第二个 Fragment 里面有一个方法,我会调用这个方法来更新我的 ListView - refreshList()

public class Frag_2 extends Fragment {

    private ListView list;
    private ArrayList<data> data;
    private boolean firstCreation=true;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.setRetainInstance(false);
    }   

    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.layout, container, false);
        list = (ListView) view.findViewById(R.id.lst);
        //this.setRetainInstance(true);
        return view;
    }


    public void refreshList(ArrayList <data> data){
        if(data!=null){
            ArrayAdapter<data> adapter = new Item_data_adapter(getActivity(),data);
            list.setAdapter(adapter);}
    }
}

从我的FragmentActivity中调用

//Something
Frag_2 fr = (Frag_2) vPagerAdapter.getItem(1);
if (fr.getView() != null) {
    fr.refreshList(data);
}

直到我改变屏幕方向之前,它都很好用。如果我说错了,请纠正我,但我搜索了几个小时,没有找到解决方案或好的解释。 FragmentActivity 只创建一次,而 Fragments 附加到它上面,但是 Fragments 会在配置更改时重新创建。现在,当方向改变时,我无法从 onCreate 中获取 View,因此当我尝试从 Fragment 中获取 View 时,它返回 null,并且我的 refreshList() 方法不被调用。我该怎么办?

我遇到了同样的问题,但没有找到解决方案。 我开始认为在FragmentManager或其它地方存在漏洞,因为我们都遇到了这个问题。 - adneal
你的XML布局怎么样呢?对于在activity布局中声明的静态碎片来说,这不是一个问题,但对于动态碎片来说则不同。 - chip
@zipc,@DLock和我都在使用ViewPager。在这种情况下,您不需要在XML中编写Fragments。 - adneal
我遇到了同样的问题。这个问题是3年前提出的,有任何更新吗?我正在考虑将我的Activity固定为竖屏,因为我厌倦了Android和它未记录的片段使用。我没有找到任何关于此的信息,即使我保留了我的片段,Android仍然会重新创建视图,然后再次附加Activity,但在翻页后,片段将具有false的isAlive()。对我来说毫无意义。 - breakline
3个回答

1
我是这样解决问题的: 在FragmentActivity的onCreate方法中。
if(savedInstanceState!=null){
            frag1 = (frag_1) getSupportFragmentManager().getFragment(savedInstanceState, frag_1.class.getName());
            frag2 = (frag_2) getSupportFragmentManager().getFragment(savedInstanceState, frag_2.class.getName());
        }
        else{
            frag1 = (frag_1) Fragment.instantiate(this,frag_1.class.getName());
            frag2 = (frag_2) Fragment.instantiate(this,frag_2.class.getName());
        }
        fragments.add(frag1);
        fragments.add(frag2);


protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        getSupportFragmentManager().putFragment(outState, frag_1.class.getName(), frag1);
        getSupportFragmentManager().putFragment(outState, frag_2.class.getName(), frag2);
    }

也许这不是宇宙中最好的解决方案,但看起来它似乎有效...

这确实可以解决问题,同时在清单文件中调整“configChanges”也可以解决,但我认为这些不是稳定的解决方案。我想这种方式可能适用于你只有一个或两个“Fragment”的情况,但我实际上有五个受到影响的“Fragment”。不过,我很高兴它对你有效。 - adneal

0

当您想要刷新列表时,请执行以下操作:

public void setView() {
    Frag_2 fr = (Frag_2) vPagerAdapter.getItem(1);
    fragmentManager.beginTransaction().detach(fr).commit();
    fragmentManager.beginTransaction().attach(fr).commit();
}

-1

如果您正在使用动态片段,则需要先进行测试,以防止创建片段的第二个实例。

要测试系统是否正在重新创建活动,请检查传递给活动的Bundle参数的onCreate()是否为null

如果它是非null的,则系统正在重新创建活动。在这种情况下,活动会自动重新实例化现有的片段。

如果它是null,则可以安全地实例化您的动态片段。例如:

public void onCreate(Bundle savedInstanceState) {
  // ...
  if (savedInstanceState != null) {
  FragmentManager fragmentManager = getFragmentManager()
  // Or: FragmentManager fragmentManager = getSupportFragmentManager()
  FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
  ExampleFragment fragment = new ExampleFragment();
  fragmentTransaction.add(R.id.fragment_container, fragment);
  fragmentTransaction.commit();
  }
}

Fragment 类支持 onSaveInstanceState(Bundle) 方法(但不支持 onRestoreInstanceState() 方法),方法的使用和 Activity 类非常相似。

  • 默认实现将所有具有 ID 的片段视图的状态保存下来。
  • 您可以覆盖此方法以存储其他片段状态信息。
  • 如果系统正在从先前保存的状态重新创建片段,则会向 onCreate()onCreateView()onActivityCreated() 方法提供包含该状态的 Bundle 引用;否则,参数将设置为 null

如果您想要详细的信息,这里 有一篇由 Marakana 的 Ken Jones 提供的好文章。


这个回答与问题不相关。@DLock和我没有使用FragmentTransaction或静态的Fragments在我们的XML中。我们正在使用ViewPager,它需要一个FragmentPagerAdapter - adneal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接