android - 如何使用 LoaderManager 和 SimpleCursorAdapter 填充 ListFragment?

标签 android android-contentprovider android-listfragment android-loadermanager

我有一个包含 ListFragment 和 Button 的布局。当我单击该按钮时,将创建一个新的 Buchungstag 对象并将其存储在数据库中。现在我假设 LoaderManager 注意到这个变化并创建一个新游标。然后 ListFragment 应该显示新对象,但什么也没有发生。谁能告诉我哪里错了?

这是我 Activity 的 onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.zeiterfassung);
    buchungstagDAO = new BuchungstagDAO(getApplicationContext());

    Button kommen = (Button) findViewById(R.id.zeit_bntKommen);
    kommen.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View arg0) {
            LogWL.e(TAG, "button clicked");
            TBuchungstag tag = new TBuchungstag();
            tag.setDatum(new Date());
            tag.setFrueh(true);
            tag.setMittag(false);
            tag.setAbend(true);
            tag.setNebenkosten(0.37d);
            tag.setParkgebuehren(4.50d);
            tag.setNebenkostenKommentar("billig");
            tag.setParkgebuehrenKommentar("parkhaus");
            tag.setAnwender(((WLAuToApplication) getApplication()).anwender);
            tag.setReiseweg("Bochum - Muenster - Bochum");
            tag.setAendDatum(new Date());
            tag = buchungstagDAO.saveOrUpdate(tag);
            LogWL.e(TAG, tag.getInterneId()+" saved");
        }
    });
}

这是我的名为 BuchungstagFragment 的 fragment :

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

    private BuchungstagSimpleCursorAdapter buchungstagCursorAdapter;
    private Anwender anwender;
    private Date syncDatum = Date.getInstance(1970, 1, 1);
    private OnItemSelectedListener listener;

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


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

        buchungstagCursorAdapter = new BuchungstagSimpleCursorAdapter(getActivity());
        setListAdapter(buchungstagCursorAdapter);

        getLoaderManager().initLoader(0, null, this);
    }


    @Override
    public void setArguments(Bundle args) {
        super.setArguments(args);
        this.anwender = (Anwender) args.get("anwender");
        this.syncDatum = (Date) args.get("syncDatum");
    }

    private static final String[] COLUMNS = new String[] { BuchungstagTable._ID, BuchungstagTable.BUCHUNGSTAG_ID,
            BuchungstagTable.FRUEH, BuchungstagTable.MITTAG, BuchungstagTable.ABEND, BuchungstagTable.NEBENKOSTEN,
            BuchungstagTable.NEBENKOSTEN_KOMMENTAR, BuchungstagTable.PARKGEBUEHREN,
            BuchungstagTable.PARKGEBUEHREN_KOMMENTAR, BuchungstagTable.SYNC_DATUM, BuchungstagTable.AEND_DATUM,
            BuchungstagTable.UEB_DATUM, BuchungstagTable.DATUM, BuchungstagTable.ANWENDER_ID };

    /*
     * (non-Javadoc)
     * 
     * @see android.app.LoaderManager.LoaderCallbacks#onCreateLoader(int,
     * android.os.Bundle)
     */
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Uri baseUri = BuchungstagTable.CONTENT_URI;
        return new CursorLoader(getActivity(), baseUri, COLUMNS, BuchungstagTable.SYNC_DATUM + " = ?",
                new String[] { syncDatum.toString() }, null);
    }


    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        buchungstagCursorAdapter.swapCursor(cursor);
    }


    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        buchungstagCursorAdapter.swapCursor(null);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof OnItemSelectedListener) {
            listener = (OnItemSelectedListener) activity;
        } else {
            throw new ClassCastException(activity.toString()
                    + " muss BuchungstagFragment.OnItemSelectedListener implementieren!");
        }
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        TBuchungstag tag = (TBuchungstag) buchungstagCursorAdapter.getItem(position);
        Bundle tagBundle = new Bundle();
        tagBundle.putSerializable("buchungstag", tag);
        listener.onBuchungstagItemSelected(tagBundle);
        getLoaderManager().restartLoader(0, null, this);
    }

    public interface OnItemSelectedListener {
        public void onBuchungstagItemSelected(Bundle tagBundle);
    }

}

这是我的BuchungstagSimpleCursorAdapter:

public class BuchungstagSimpleCursorAdapter extends SimpleCursorAdapter {

    private static String[] COLUMNS = { BuchungstagTable.DATUM };

    private static int[] guifelder = { R.id.zeit_buchungstagTagLabel, R.id.zeit_buchungstagDatumLabel };

    private final LayoutInflater inflater;
    private Context context;

    public BuchungstagSimpleCursorAdapter(Context context) {
        super(context, R.layout.zeiterf_buchungstag, null, COLUMNS, guifelder, 0);
        inflater = LayoutInflater.from(context);
        this.context = context;
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.widget.SimpleCursorAdapter#bindView(android.view.View,
     * android.content.Context, android.database.Cursor)
     */
    @Override
    public void bindView(View view, Context context, Cursor cur) {
        Date d = new Date(cur.getLong(cur.getColumnIndex(BuchungstagTable.DATUM)));
        String day = d.format("EEEE");
        String date = d.format("dd.MM.yyyy");

        TextView tag = (TextView) view.findViewById(R.id.zeit_buchungstagTagLabel);
        tag.setHintTextColor(view.getResources().getColor(R.color.buchungstagTagColor));
        tag.setText(day);

        TextView datum = (TextView) view.findViewById(R.id.zeit_buchungstagDatumLabel);
        datum.setText(date);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View v = inflater.inflate(R.layout.zeiterf_buchungstag, parent);
        return v;
    }
}

我的 ContentProvider 在其 insert() 方法的末尾有一个 getContext().getContentResolver().notifyChange()。有人可以向我解释为什么这没有按预期工作吗?

最佳答案

我发现了我的错误。在我的 onCreateLoader() 方法中,我传递了一个选择参数,它阻止游标在数据库中找到任何合适的项目。删除参数后,加载程序按预期工作。

关于android - 如何使用 LoaderManager 和 SimpleCursorAdapter 填充 ListFragment?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18381150/

相关文章:

java - 从一个应用程序中的数据库在另一个应用程序中运行 SQLite 命令

android - 使用 firebase 向所有用户发送推送通知

java - Cursor,CursorAdapter,LoaderManager,Loader之间的关系

Android跨应用数据传递

android - addToBackStack() 在按下后退按钮时复制原始 fragment

android - 每行带有按钮的 ListFragment

android - 无法在 Cordova 中删除 Android 平台

java - 在 WebView android 中单击链接时显示 pdf

android - 为什么用Bitmap.CompressFormat.JPEG压缩后图片颜色变了

Android ListFragment onclick问题