まず、必要ありませんgetView
。bindView
と組み合わせるとnewView
、その代わりとして完全に十分ですが、おそらくもっと良いと言う人もいます。さらに、新しいビューでbindviewを呼び出す必要はありません。ここにあるべきものの再構築があります。
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = inflater.inflate(R.layout.lvct, parent, false);
return v;
}
createEntry
これは完全にあなたの呼び出しですが、少なくともそのメソッドでは、あなたのメソッドをアダプタに入れるべきではないと思います。アダプターのメソッドはリストビューの各行に対して呼び出されるため、冗長に多くのことが発生する可能性があります。さらに、データベースに段階的に挿入するのは無駄だと私は個人的に感じています。むしろ、誰かがチェックボックスの選択を解除した場合はどうなるので、一度にすべてを実行する以外に選択肢はないと思います。エントリを削除しますか?無駄であるだけでなく、カーソル位置を追跡するのは面倒であるか_id
、何かが追加されるたびに再クエリを実行する必要があります。あなたがすべきことは、データベースに追加する必要があるもののリストを維持し、それが完了したらそれを一括挿入することです。
まず、挿入したいデータを保持するオブジェクトを作成する必要があります。オブジェクトは、複数の情報を保持する必要がある最もクリーンな方法です。ここでは非常に簡単です。コンストラクターに必要な値を挿入してから、getterメソッドを使用して取得します。
public class ContactObject {
private String name;
private String phone;
public ContactObject(String name, String phone) {
super();
this.name = name;
this.phone = phone;
}
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
}
ここで、これらのオブジェクトがチェックされたときにそれらを保持するためのオブジェクトが必要です。奇妙なことですが、それらが識別され、繰り返し実行でき、一般に参照用にバッチ処理されていると、はるかに便利です。この種のタスクにはが必要だと思いますHashMap
。コンストラクターで作成します。
contactMap = new HashMap<Integer, ContactObject>(c.getCount());
さあ、ブギをする時が来ました。チェックボックスのメソッドを作成して、からのものを追加および削除しますHashMap
。
cbInsert.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (cbInsert.isChecked()) {
contactMap.put(cursor.getPosition(), new ContactObject(str_name, str_phone));
} else {
contactMap.remove(cursor.getPosition());
}
}
});
内のオブジェクトのIDのようにカーソル位置を使用しましたHashMap
。また、チェックボックスがオフになっていて、配置されたオブジェクトを削除したい場合は、使用した識別子を参照するだけです。より賢明な人は、削除する前にその位置に何かがあるかどうかを確認したいと思うかもしれません。それはあなたの裁量です。これでほぼ完了です。HashMapをデータベースのエントリに変換するにはどうすればよいですか?データベースオブジェクトにアクセスし、ループしてから、オブジェクトを1つずつ取得する必要があります。問題は今どこにあるかです。アダプターで直接行うこともできますが、私の場合、他のタスクのアクティビティ用にデータベースがすでに作成されており、自分よりも多くのオブジェクトを作成したくないため、通常はアクティビティでこのようなことを行います。にプッシュしました。したがって、私たちにできることは、HashMapのアダプターでgetterメソッドを使用して終了することです。
public HashMap<Integer, ContactObject> getContactMap() {
return contactMap;
}
これで、アプリが終了するときにこのようなことを行うと思いますので、ここで説明します。
@Override
protected void onDestroy() {
super.onDestroy();
HashMap<Integer, ContactObject> contactMap = adapter.getContactMap();
DatabaseHelper db = new DatabaseHelper(this);
// iterate through hashmap
for (Map.Entry<Integer, ContactObject> entry : contactMap.entrySet()) {
Integer key = entry.getKey();
ContactObject value = entry.getValue();
db.creatEntry(key, value.getPhone(), value.getName());
}
db.close();
}
今、物事は少し奇妙に見えます、私はあなたのエントリー方法で何をしましたか?
public long creatEntry(Integer id, String inputnumber, String name) { // for add data
long lng;
String strId = id.toString();
String[] selectionArgs = {strId};
Cursor cursor = ourdatabase.query(DATABASE_TABLE, null, "other_id = ?", selectionArgs, null, null, null);
if (cursor.moveToFirst()) {
// it exists, i'd assume that you might not want anything else done here
lng = -1;
} else {
// it doesn't exist
ContentValues cv= new ContentValues();
cv.put(KEY_NUMBER, inputnumber);
cv.put(N_NAME, name);
cv.put(KEY_OTHERID, strId);
Log.v(inputnumber, "adding to Database");
lng = ourdatabase.insert(DATABASE_TABLE, null, cv);
}
// cursor.close();
return lng;
}
ご覧のとおり、IDも取り込むように変更しました。あなたが遭遇する問題は、データベースに繰り返しがあることだと思いました。変更可能なIDの別のフィールドを用意することで、管理できると思いました。このIDは、から渡されたIDを参照しHashMap
ます。挿入するたびに、最初にその前のIDが存在するかどうかを確認してから、何をしたいかを決定すると思いました。これは完璧な解決策ではありませんが、その問題が発生する可能性があることを警告し、それを管理するためのヒントを提供したいと思います。一般に、挿入メソッドは、数行だけを挿入する場合は問題ありませんが、挿入するものがたくさんある場合は、パフォーマンスのために一括トランザクションを調べたい場合があります。
もう1つ、リストビューのチェックボックスは、通常予想されるように状態が持続することを期待できません。チェックボックスが各位置でどのような状態になるかを明示的に指定する必要があります。HashMap
対応するキーで何かがいっぱいになっている場合に対応させました。より明確になることを期待して、完全なアダプタメソッドを次に示します。
public class ContactCursorAdapterCT extends CursorAdapter {
private LayoutInflater inflater;
private HashMap<Integer, ContactObject> contactMap;
public ContactCursorAdapterCT(Context context, Cursor c) {
super(context, c);
inflater = LayoutInflater.from(context);
contactMap = new HashMap<Integer, ContactObject>(c.getCount());
// i used c.getCount() as a capacity limit for this.
// if you opened made this multiple times, it might get over inflated and
// slow things down.
}
@Override
public void bindView(View view, Context context, final Cursor cursor) {
TextView name = (TextView)view.findViewById(R.id.contactlistTV1);
TextView phone = (TextView)view.findViewById(R.id.contactlistTV2);
final CheckBox cbInsert = (CheckBox) view.findViewById(R.id.contactlistCB1);
String str_name = cursor.getString
(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String str_phone = cursor.getString
(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
name.setText(str_name);
phone.setText(str_phone);
boolean isFilled = contactMap.containsKey(cursor.getPosition());
cbInsert.setChecked(isFilled);
// insert, remove objects to hashmap
cbInsert.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (cbInsert.isChecked()) {
contactMap.put(cursor.getPosition(), new ContactObject(str_name, str_phone));
} else {
contactMap.remove(cursor.getPosition());
}
}
});
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View v = inflater.inflate(R.layout.lvct, parent, false);
return v;
}
public HashMap<Integer, ContactObject> getContactMap() {
return contactMap;
}
}