【问题标题】:How do I call a Fragment's method once the Fragment View is loaded?加载 Fragment View 后如何调用 Fragment 的方法?
【发布时间】:2014-10-03 16:22:15
【问题描述】:

正如问题所示,我正在尝试从其父 Activity 的 onCreate 调用 Fragment 的方法。但是,被调用的方法会在 Fragment 处产生空指针异常。违规行是:

getListView().setAdapter(aAdapter);

我怀疑 getListView() 还不存在。也许这是我对 Fragment/Activity 生命周期的知识的一个空白,但是我可以使用 Activity 中的“AfterCreate”吗?

//Views
private RelativeLayout vClassSettings;
private LinearLayout vPeople;
private LinearLayout vLinks;
private RelativeLayout vAttendanceSettings;

private static final String sTag = "ActivityClassEdit";



private Boolean insertMode;
//==============On Create================
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_classedit);
        vClassSettings=(RelativeLayout) findViewById(R.id.ace_container_settings);
        vPeople = (LinearLayout) findViewById(R.id.ace_container_people);
        vLinks = (LinearLayout) findViewById(R.id.ace_container_links);
        vAttendanceSettings = (RelativeLayout)     findViewById(R.id.ace_container_attendanceDetails);
        insertMode=true;
        startupFragments();
    }

    /*
      Sets modes for children fragments so that we do not get null adapters, be it Object or SQL related
     */
    private void startupFragments(){
        instantiateFragments();
        if(insertMode){
            if(fLinkList==null){Log.d(sTag,"null fragment for LinkList");}
            fLinkList.setArrayMode();
            fCrList.setArrayMode();
            fPersonList.setArrayMode();
        } else {
            //TODO set CursorMode with parent class argument
        }

    }

以及片段的冒犯方法:

public void setArrayMode(){
    aAdapter = new LinkArrayListAdapter(getActivity(), links);
    getListView().setAdapter(aAdapter);
    getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            final LinkTable.Link selectedLink =  (Link) parent.getItemAtPosition(position);
            selectedLink.setIndex(aAdapter.getPosition(selectedLink));
            App.getInstance().getEventBus().post(new FragmentEvent.LinkObjectLoad(selectedLink));
            //App.getInstance().getEventBus().post(arg0);
        }});}

【问题讨论】:

  • 发布您的活动代码。
  • “我可以使用 Activity 中的“AfterCreate”吗?”。是的,Activity.onPostCreate()
  • @Gil +1。还有onResumeFragments().
  • @kcoppock 很酷,不知道那个。看起来它只是在支持库中。

标签: android android-fragments android-fragmentactivity android-lifecycle


【解决方案1】:

我建议您永远不要从 Fragment 本身的外部触摸 Fragment 的视图。 Fragment 应该在onCreateView() 中创建它的视图,获取视图引用并在onViewCreated() 中初始化视图,然后在onDestroyView() 中释放它。如果您需要在创建后向其提供数据,您可以:

  1. 在您的 Fragment 中提供一个方法来设置适配器的数据。如果 View 还没有被创建,数据应该在 Fragment 设置适配器时被拾取。否则,片段可以使用新数据更新其适配器。

  2. 将数据作为 Fragment 参数 (Fragment.setArguments(Bundle)) 提供,并让 Fragment 在onViewCreated() 中使用getArguments().get{someDataType}() 设置列表适配器。

编辑:所以为片段提供参数:

public static MyListFragment newInstance(int type, ArrayList<? extends Parcelable> items) {
    MyListFragment fragment = new MyListFragment();
    Bundle args = new Bundle();
    args.putInt(TYPE_ARG, type);
    args.putParcelableArrayList(ITEMS_ARG, items);
    fragment.setArguments(args);
    return fragment;
}

public void onViewCreated(View view, Bundle savedInstanceState) {
    final int type = getArguments().getInt(TYPE_ARG);

    if (type == FIRST_TYPE) {
        // Set first type adapter
    } else /* Some other type of argument */ {
        // Set another adapter type
    }
}

虽然我建议这两种类型是否非常不同,但可能有一个具有共享行为的基本片段,并为每种适配器类型都有子类,并根据您使用的任何参数从 Activity 实例化不同的片段决定。

【讨论】:

  • 感谢您的及时回答。并不是从 Activity 中实例化视图,而是根据 Activity 的参数,ListFragment 需要设置正确的适配器。
  • 您指出不要从活动中弄乱片段的视图是正确的。不幸的是,我的片段被嵌入到 Activity 的 XML 布局中,所以我必须使用事件总线。但是,您的逻辑仍将被使用,只是没有捆绑包。感谢您在 Android 中扩展陌生人的知识
  • 没问题,很高兴它帮助您上路。 :) 旁注:如果可能的话,我会从 XML 中删除片段定义并以编程方式实例化它们。将来您会以这种方式获得更多的灵活性(因为来自 XML 的片段不能轻易地替换为在运行时创建的片段)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多