【问题标题】:Android - Viewpager and fragments, methods not workingAndroid - Viewpager 和片段,方法不起作用
【发布时间】:2012-09-08 07:51:20
【问题描述】:

我有一个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 中存在错误,或者考虑到我们都遇到了这种情况。
  • 你的 xml 布局怎么样?这对于在活动布局中声明的静态片段来说不是问题,但对于动态片段来说不是这样
  • @zipc @DLock 和我都在使用ViewPager。在这种情况下,您不会在 XML 中写入 Fragments
  • 我遇到了同样的问题。这个问题是3年前提出的,对此有更新吗?我正在考虑将我的 Activity 修复为肖像,因为我厌倦了 Android 并且它是未记录的片段使用。我还没有在这方面找到任何东西,即使我保留了我的片段,Android 仍然会重新创建视图,然后再次附加 Activity,但在翻转页面后片段会将 isAlive() 设为 false。对我来说没有任何意义。

标签: android android-fragments android-viewpager android-fragmentactivity


【解决方案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,但我认为这些不是可靠的解决方案。我想这种方式适用于您有一个或两个Fragments 的情况,但实际上我有五个受此影响。不过,我很高兴它对你有用。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    要测试系统是否正在重新创建活动,请检查 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 的片段视图的状态。
    • 您可以重写此方法来存储额外的片段状态信息。
    • 如果系统正在从以前保存的状态重新创建片段,它会提供对包含该状态的Bundle 的引用到onCreate()onCreateView()onActivityCreated() 方法;否则, 参数设置为null

    如果您想了解详细信息,here's Marakana 的 Ken Jones 的精彩演讲

    【讨论】:

    • 这个答案与问题无关。 @DLock 和我没有在我们的 XML 中使用 FragmentTransaction 或静态 Fragments。我们使用ViewPager,它需要FragmentPagerAdapter
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多