0

私は (そしてしばらくの間) 非常に基本的なクラス スケジュール アプリとして機能する Android プロジェクトに取り組んでいます。これまでのところ、私は次の作業を行っています:データベースにコースを追加し、データベースからコースを削除し、リストに場所と主題を含むコースを表示し、「課題」メニューを開いてコースの課題を作成します。

問題は、課題作成メニューの保存ボタンをクリックしようとしても、課題がリストに追加されないことです。

課題リストは、「コース」データベース内の 2 番目のテーブルです ( lunchlist.db というラベルが付いています)。以下に添付されているのは、割り当ての処理を担当する 3 つのクラスです。

課題リスト:

public class AssList extends ListActivity {
    public final static String ID_EXTRA = "apt.tutorial._ID";
    Cursor model = null;
    AssAdapter adapter = null;
    AssHelper helper = null;
    SharedPreferences prefs = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ass);

        helper = new AssHelper(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        helper.close();
    }

    @Override
    public void onListItemClick(ListView list, View view, int position, long id) {
        Intent i = new Intent(AssList.this, AssForm.class);

        i.putExtra(ID_EXTRA, String.valueOf(id));
        startActivity(i);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.ass_option, menu);

        return (super.onCreateOptionsMenu(menu));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.add_ass) {
            startActivity(new Intent(AssList.this, AssForm.class));

            return (true);
        }

        return (super.onOptionsItemSelected(item));
    }

    public void initList() {
        if (model != null) {
            stopManagingCursor(model);
            model.close();
        }

        model = helper.getAll(prefs.getString("sort_order", "name"));
        startManagingCursor(model);
        adapter = new AssAdapter(model);
        setListAdapter(adapter);
    }

    private SharedPreferences.OnSharedPreferenceChangeListener prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        public void onSharedPreferenceChanged(SharedPreferences sharedPrefs,
                String key) {
            if (key.equals("sort_order")) {
                initList();
            }
        }
    };

    class AssAdapter extends CursorAdapter {
        AssAdapter(Cursor c) {
            super(AssList.this, c);
        }

        @Override
        public void bindView(View row, Context ctxt, Cursor c) {
            AssHolder holder = (AssHolder) row.getTag();

            holder.populateFrom(c, helper);
        }

        @Override
        public View newView(Context ctxt, Cursor c, ViewGroup parent) {
            LayoutInflater inflater = getLayoutInflater();
            View row = inflater.inflate(R.layout.row, parent, false);
            AssHolder holder = new AssHolder(row);

            row.setTag(holder);

            return (row);
        }
    }

    static class AssHolder {
        private TextView name = null;
        private TextView address = null;
        private ImageView icon = null;

        AssHolder(View row) {
            name = (TextView) row.findViewById(R.id.title);
            address = (TextView) row.findViewById(R.id.address);
            icon = (ImageView) row.findViewById(R.id.icon);
        }

        void populateFrom(Cursor c, AssHelper helper) {
            name.setText(helper.getName(c));
            address.setText(helper.getUrgency(c));

            if (helper.getUrgency(c).equals("normal")) {
                icon.setImageResource(R.drawable.eg);
            } else if (helper.getUrgency(c).equals("pending")) {
                icon.setImageResource(R.drawable.ey);
            } else {
                icon.setImageResource(R.drawable.er);
            }
        }
    }
}

課題フォーム:

public class AssForm extends Activity {
    EditText name = null;
    RadioGroup types = null;
    AssHelper helper = null;
    String AssId = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ass_edit);

        helper = new AssHelper(this);

        name = (EditText) findViewById(R.id.assname);
        types = (RadioGroup) findViewById(R.id.urge);

        Button save = (Button) findViewById(R.id.save_ass);
        Button del = (Button) findViewById(R.id.del_ass);
        save.setOnClickListener(onSave);
        del.setOnClickListener(onDel);

        AssId = getIntent().getStringExtra(AssList.ID_EXTRA);

        if (AssId != null) {
            load();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        helper.close();
    }

    private void load() {
        Cursor c = helper.getById(AssId);

        c.moveToFirst();
        name.setText(helper.getName(c));

        if (helper.getUrgency(c).equals("normal")) {
            types.check(R.id.normal);
        } else if (helper.getUrgency(c).equals("pending")) {
            types.check(R.id.pending);
        } else {
            types.check(R.id.due);
        }

        c.close();
    }

    private View.OnClickListener onSave = new View.OnClickListener() {
        public void onClick(View v) {
            String type = null;

            switch (types.getCheckedRadioButtonId()) {
            case R.id.normal:
                type = "normal";
                break;
            case R.id.pending:
                type = "pending";
                break;
            case R.id.due:
                type = "due";
                break;
            }

            if (AssId == null) {
                helper.insert(name.getText().toString(), type);
            } else {
                helper.update(AssId, name.getText().toString(), type);
            }

            finish();
        }
    };

    private View.OnClickListener onDel = new View.OnClickListener() {
        public void onClick(View v) {
            helper.deleteValue(name.getText().toString());

            finish();
        }
    };
}

割り当てヘルパー:

class AssHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "lunchlist.db";
    private static final int SCHEMA_VERSION = 1;

    public AssHelper(Context context) {
        super(context, DATABASE_NAME, null, SCHEMA_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE assignments (_id INTEGER PRIMARY KEY AUTOINCREMENT, assname TEXT, urge TEXT);");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // no-op, since will not be called until 2nd schema
        // version exists
    }

    public Cursor getAll(String orderBy) {
        return (getReadableDatabase().rawQuery(
                "SELECT _id, assname, urge FROM assignments ORDER BY "
                        + orderBy, null));
    }

    public Cursor getById(String id) {
        String[] args = { id };

        return (getReadableDatabase().rawQuery(
                "SELECT _id, assname, urge FROM assignments WHERE _ID=?",
                args));
    }

    public void insert(String name, String type) {
        ContentValues cv = new ContentValues();

        cv.put("assname", name);
        cv.put("urge", type);

        getWritableDatabase().insert("assignments", "assname", cv);
    }

    public void deleteValue(String value) {
        SQLiteDatabase db = getWritableDatabase();

        String whereClause = "assname" + "=?";
        String[] whereArgs = new String[] { String.valueOf(value) };
        db.delete("assignments", whereClause, whereArgs);
        db.close();
    }

    public void update(String id, String name, String type) {
        ContentValues cv = new ContentValues();
        String[] args = { id };

        cv.put("assname", name);
        cv.put("urge", type);

        getWritableDatabase().update("assignments", cv, "_ID=?", args);
    }

    public String getName(Cursor c) {
        return (c.getString(1));
    }

    public String getUrgency(Cursor c) {
        return (c.getString(2));
    }
}

読み通すのが大変なことはわかっていますが、プロジェクトのこの最後の部分に本当に行き詰まっています。これら 3 つのクラスは、(すべての意図と目的において) コースを追加するための 3 つのクラスとほぼ同じです。唯一の違いは、変数名が変更されたことと、割り当てクラスに一致するようにクラス参照が切り替えられたことです。どんな助けや批判も大歓迎です。私の質問を読んでくれてありがとう。

4

2 に答える 2

1

別の方法として、データベースをContentProviderでラップしてから、CursorLoaderを使用してカーソルを管理することもできます。CursorLoaderはバックグラウンドスレッドで実行され(イェーイ!)、基になるデータが変更されると自動的にカーソルをリロードします。

ContentProviderは少しオーバーヘッドを提供しますが、それ以外の場合は自分で処理しなければならない多くの厄介なデータベースのものを隠します。ドキュメントには、データベースを使用するためにコンテンツプロバイダーを使用する必要はないと記載されていますが、コンテンツプロバイダーの方が優れている場合もあります。それはあなたの時間を節約するので、それは主に良いです。ほとんどのアプリのパフォーマンスは、コンテンツプロバイダーを使用しても全体的に影響を受けないと思います。

于 2012-11-05T22:13:07.353 に答える
1

編集またはエントリをデータベースに保存した後、カーソルをリロードし、リストビューを呼び出しnotifydatasetchanged()て更新するように指示する必要があります。OnResume()送信フォームとリストビューは異なるアクティビティにあり、一方が他方の上にある必要があるため、おそらく条件付きの意図で扇動されたリストアクティビティのメソッドでこれらを行うのが最も簡単な方法だと思います無駄なリフレッシュを避けるために。さらに率直なのは、リストアクティビティがビューの外にあるときに常に「終了」していることを確認して、新しいインスタンスが表示されるたびにカーソルをリセットすることです。

上記が正しいことを確認する良い方法は、アプリを完全に閉じて、アプリの再起動時に編集またはエントリが表示されるかどうかを確認することです。


編集:まあ、あなたの質問は私の好奇心を少し刺激していました。最終的には座屈して、自分で完全なコードを実行し、このソリューションを自分でテストしました。私たち全員がそれを見逃したとは信じられませんが、問題はリストビューに追加されていないことではなく、リストビューがまったく表示されていなかったことです。問題は、リストビューがカーソル アダプターに接続されていなかったことです。必要なものは次のとおりです。

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ass);
        helper = new AssHelper(this);        
        loadListview();      
    }   

    private void loadListview() {
        Cursor c = helper.getAll("urge");
        mAdapter = new AssAdapter(c);
        setListAdapter(mAdapter);
    }

わずか 3 行のコードで別のメソッドを作成しました。実際には、アクティビティに戻ったときにリストビューを更新する必要があるためです。このようにしたくないかもしれませんが、私は怠け者なので、次の方法で行うことにしました。

@Override
protected void onResume() {
    super.onResume();
    loadListview();
}

これに関する私の個人的な問題は、カーソルの最初のインスタンスが閉じられる機会が決して得られないことです。これは少しエレガントではありません。ところで、これは問題とは何の関係もありませんが、コードは非推奨のメソッド (非推奨のカーソル コンストラクターなどstartManagingCursor) をかなり使用しています。完了したら、カーソルとデータベースを閉じることも忘れないでください。

于 2012-11-05T19:37:17.477 に答える