访问从另一个片段创建的一个片段中的Loader

时间:2012-11-09 08:22:54

标签: android android-fragments android-loadermanager commonsware-cwac android-loader

我的应用程序具有相当标准的片段布局。左侧是可扩展的listview片段,右侧是面板,根据用户选择对左侧列表执行的操作(显示数据,添加新数据等),用于不同的事物。

我正在使用LoaderManager(第一次使用加载器)和CommonWare的loaderex库,因为我不需要或者不想为我的数据库创建内容提供程序,所以我可以使用标准的CursorLoader。此设置非常适合显示我的列表。

我遇到的问题是当我使用第二个片段将数据添加到数据库时。我无法弄清楚如何在第一个片段中触发重新加载列表。对于我的生活,我无法弄清楚如何从第二个片段中抓取加载器,以便它知道需要再次拉动数据,我也无法想象如何手动触发重新加载。

由于这是我第一次尝试使用装载机,如果我正在做一些不正确的事情,我会很乐意(轻轻地)重新指向更好的路径。

片段1

public class StudentListFragment extends ListFragment implements
        LoaderManager.LoaderCallbacks<Cursor> {

    private TAOpenHelper mDbHelper = null;
    private MyExpandableListAdapter mAdapter = null;
    private ExpandableListView lv = null;
    private Button addStudentButton;
    public static long mRowId = 0;
    public SQLiteCursorLoader studentLoader=null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.leftlistfragment_entry, container,
                false);
        return v;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        addStudentButton = (Button) getActivity().findViewById(R.id.AddButton);
        addStudentButton.setText(getResources().getString(
                R.string.button_add_student));
        addStudentButton.setOnClickListener(addStudentButtonHandler);

        lv = (ExpandableListView) getListView();

        mDbHelper = TAOpenHelper.getInstance(getActivity());

        fillData();
        getLoaderManager().getLoader(-1);
        if (studentLoader != null && !studentLoader.isReset()) {
            getLoaderManager().restartLoader(-1, null, this);
        } else {
            getLoaderManager().initLoader(-1, null, this);
        }
    }

    private void fillData() {
        mAdapter = new MyExpandableListAdapter(getActivity(), this,
                R.layout.listlayout_exp_double_group,
                R.layout.listlayout_exp_double_child,
                new String[] { TeacherAidDB.STUDENT_FIRST,
                        TeacherAidDB.STUDENT_LAST }, new int[] {
                        R.id.ListItem1, R.id.ListItem2 }, new String[] {
                        TeacherAidDB.CLASS_NAME, TeacherAidDB.CLASS_LEVEL },
                new int[] { R.id.ListItem1, R.id.ListItem2 });
        lv.setAdapter(mAdapter);
    }

    public class MyExpandableListAdapter extends SimpleCursorTreeAdapter {
        protected final SparseIntArray mGroupMap;
        private StudentListFragment mFragment;

        public MyExpandableListAdapter(Context context,
                StudentListFragment clf, int groupLayout, int childLayout,
                String[] groupFrom, int[] groupTo, String[] childrenFrom,
                int[] childrenTo) {
            super(context, null, groupLayout, groupFrom, groupTo, childLayout,
                    childrenFrom, childrenTo);
            mFragment = clf;
            mGroupMap = new SparseIntArray();
        }

        @Override
        protected Cursor getChildrenCursor(Cursor groupCursor) {
            int groupPos = groupCursor.getPosition();
            int groupId = groupCursor.getInt(groupCursor
                    .getColumnIndex(TeacherAidDB.CLASS_ROWID));
            mGroupMap.put(groupId, groupPos);
            Loader<Cursor> loader = getActivity().getLoaderManager().getLoader(
                    groupId);
            if (loader != null && !loader.isReset()) {
                getActivity().getLoaderManager().restartLoader(groupId, null,
                        mFragment);
            } else {
                getActivity().getLoaderManager().initLoader(groupId, null,
                        mFragment);
            }
            return null;
        }

        public SparseIntArray getGroupMap() {
            return mGroupMap;
        }
    }

    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (id != -1) { // Child Cursor
            studentLoader = new SQLiteCursorLoader(getActivity(), mDbHelper,
                    TeacherAidDB.STUDENT_LIST_CLASS_QUERY + id, null);
        } else { // Group Cursor
            studentLoader = new SQLiteCursorLoader(getActivity(), mDbHelper,
                    TeacherAidDB.STUDENT_LIST_QUERY, null);
        }
        return studentLoader;
    }

    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        int id = loader.getId();
        if (id != -1) { // Child cursor
            if (!data.isClosed()) {
                SparseIntArray groupMap = mAdapter.getGroupMap();
                int groupPos = groupMap.get(id);
                mAdapter.setChildrenCursor(groupPos, data);
            }
        } else { // Groups cursor
            mAdapter.setGroupCursor(data);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        mAdapter.changeCursor(null);
    }

    View.OnClickListener addStudentButtonHandler = new View.OnClickListener() {
        public void onClick(View v) {
            AddPerson personadd = AddPerson.newInstance(AddPerson.STUDENT, AddPerson.CREATE, mRowId);
            getFragmentManager().beginTransaction()
                    .replace(R.id.rightpane, personadd).commit();
        }
    };
}

片段2

public class AddPerson extends Fragment {

    public static int STUDENT = 0;
    public static int TEACHER = 1;
    public static int CREATE = 0;
    public static int EDIT = 1;
    private int mRowId;
    private TAOpenHelper mDbHelper;
    private Cursor personedit;
    private Button commit;
    private Button cancel;

    int who;
    int what;
    long rowId;

    static AddPerson newInstance(int type, int action, long rowid) {
        AddPerson f = new AddPerson();
        Bundle args = new Bundle();
        args.putInt("type", type);
        args.putInt("action", action);
        args.putLong("rowid", rowid);
        f.setArguments(args);
        return f;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        who = getArguments().getInt("type");
        what = getArguments().getInt("action");
        rowId = getArguments().getInt("rowid");
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.dialog_person_add, container, false);

        mDbHelper = TAOpenHelper.getInstance(getActivity());

        if (what == EDIT) {
            if (who == STUDENT) {
                // Student Edit stuff here
            } else {
                // Teacher Edit stuff here 
            }
        } else { 
            if (who == STUDENT) { 
                // Student Create stuff here
            } else {
                // Teacher Create stuff here 
            }
        }

        // Code to gather data from user goes here

        commit = (Button) v.findViewById(R.id.commitbutton);
        commit.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {

                first = firstTxt.getText().toString();
                last = lastTxt.getText().toString();
                street = streetTxt.getText().toString();
                city = cityTxt.getText().toString();
                zip = zipTxt.getText().toString();
                phone = phoneTxt.getText().toString();
                email = emailTxt.getText().toString();
                if (what == CREATE) {
                    processAdd(who);
                } else {
                    processUpdate(who);
                }
            }
        });

        cancel = (Button) v.findViewById(R.id.cancelbutton);
        cancel.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Fragment check = getFragmentManager().findFragmentById(
                        R.id.rightpane);
                getFragmentManager().beginTransaction().remove(check).commit();
            }
        });
        return v;
    }

    private void processAdd(int who) {
        ContentValues initialValues = new ContentValues();
        if (who == STUDENT) {
            initialValues.put(TeacherAidDB.STUDENT_FIRST, first);
            initialValues.put(TeacherAidDB.STUDENT_LAST, last);
            initialValues.put(TeacherAidDB.STUDENT_STREET, street);
            initialValues.put(TeacherAidDB.STUDENT_CITY, city);
            initialValues.put(TeacherAidDB.STUDENT_STATE, state);
            initialValues.put(TeacherAidDB.STUDENT_ZIP, zip);
            initialValues.put(TeacherAidDB.STUDENT_PHONE, phone);
            initialValues.put(TeacherAidDB.STUDENT_EMAIL, email);
            initialValues.put(TeacherAidDB.STUDENT_BDAY, birthday);

            // How to get studentLoader from fragment 1?
            //studentLoader.insert(TeacherAidDB.STUDENT_TABLE, null, initialValues);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

使用常规CursorLoader,这将通过ContentObserver框架自动发生,最终归结为一堆静态数据成员。

使用SQLiteCursorLoaderContentObserver不可用,最接近的模拟是通过Loader路由您的CRUD操作,因此它知道重新加载Cursor。并且 实际上只是设计用于单个活动。

因此,正如Luksprog建议的那样,您最好的选择是将CRUD工作委托给包含活动。

如果这些片段可能由不同的活动托管(例如,对于小/普通与大/ xlarge屏幕大小),请定义一个用于处理此工作的公共接口,并将片段委托给接口。