加载片段视图后如何调用Fragment的方法?

时间:2014-10-03 16:22:16

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

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

getListView().setAdapter(aAdapter);

我怀疑是getListView()还不存在。也许这是我对片段/活动生命周期的了解,但是有一个" 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);
        }});}

1 个答案:

答案 0 :(得分:3)

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

  1. 在Fragment中提供一个方法来设置适配器的数据。如果尚未创建视图,则应在Fragment设置适配器时拾取数据。否则,片段可以使用新数据更新其适配器。

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

  3. 编辑:所以提供片段的参数:

    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
        }
    }
    

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