他のいくつかの記事と同様に、各行のCheckBoxを含むListViewを作成しようとしています.SQLiteデータベースを使用して、選択。Android:ListBox with CheckBox、SQLiteデータベースからデータを取り込みました
http://appfulcrum.com/?p=351の例では、それほどうまくいきませんでしたが、私はデータベースを作成し、20個のアイテムを取り込み、リストを表示する単純なアプリケーションを作成しました。
正常に状態を取得し、選択状態を正常に保存します。
ただし、変更してリストのもう一方の端にスクロールしてスクロールバックすると、CheckBoxの状態が正しく表示されません。例えば最初のCheckBoxを選択し、下にスクロールして先頭に戻ると、CheckBoxは設定されなくなります。これは、Android 2.1のSamsung端末で実行されています。
メイン画面に戻ると、リストに戻り、が正しく設定されているため、データベースは実際に更新されています。
この例はSimpleCursorAdapterを拡張し、getView()はテーブルの選択列の値に基づいて、必要に応じてtrueまたはfalseを指定してsetChecked()を呼び出します。
以下はすべての情報源です。
私は確かに言われていただければと思い、 "おやおやは、ここにあなたの問題は...だ"
CustomListViewDB.java
// src/CustomListViewDB.java
package com.appfulcrum.blog.examples.listviewcustomdb;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.SQLException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class CustomListViewDB extends ListActivity {
private ListView mainListView = null;
CustomSqlCursorAdapter adapter = null;
private SqlHelper dbHelper = null;
private Cursor currentCursor = null;
private ListView listView = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple);
if (this.dbHelper == null) {
this.dbHelper = new SqlHelper(this);
}
listView = getListView();
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
//listView.setClickable(true);
Button btnClear = (Button) findViewById(R.id.btnClear);
btnClear.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),
" You clicked Clear button", Toast.LENGTH_SHORT).show();
ClearDBSelections();
}
});
new SelectDataTask().execute();
this.mainListView = getListView();
mainListView.setCacheColorHint(0);
}
@Override
protected void onRestart() {
super.onRestart();
new SelectDataTask().execute();
}
@Override
protected void onPause() {
super.onPause();
this.dbHelper.close();
}
protected void ClearDBSelections() {
this.adapter.ClearSelections();
}
private class SelectDataTask extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... params) {
try {
CustomListViewDB.this.dbHelper.createDatabase(dbHelper.dbSqlite);
CustomListViewDB.this.dbHelper.openDataBase();
CustomListViewDB.this.currentCursor = CustomListViewDB.this.dbHelper
.getCursor();
} catch (SQLException sqle) {
throw sqle;
}
return null;
}
// can use UI thread here
protected void onPostExecute(final String result) {
startManagingCursor(CustomListViewDB.this.currentCursor);
int[] listFields = new int[] { R.id.txtTitle };
String[] dbColumns = new String[] { SqlHelper.COLUMN_TITLE };
CustomListViewDB.this.adapter = new CustomSqlCursorAdapter(
CustomListViewDB.this, R.layout.single_item,
CustomListViewDB.this.currentCursor, dbColumns, listFields,
CustomListViewDB.this.dbHelper);
setListAdapter(CustomListViewDB.this.adapter);
}
}
}
CustomSqlCursorAdapter.java
// src/CustomSqlCursorAdapter.java
package com.appfulcrum.blog.examples.listviewcustomdb;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class CustomSqlCursorAdapter extends SimpleCursorAdapter {
private Context mContext;
private SqlHelper mDbHelper;
private Cursor mCurrentCursor;
public CustomSqlCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, SqlHelper dbHelper) {
super(context, layout, c, from, to);
this.mCurrentCursor = c;
this.mContext = context;
this.mDbHelper = dbHelper;
}
public View getView(int pos, View inView, ViewGroup parent) {
View v = inView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.single_item, null);
}
if (!this.mCurrentCursor.moveToPosition(pos)) {
throw new SQLException("CustomSqlCursorAdapter.getView: Unable to move to position: "+pos);
}
CheckBox cBox = (CheckBox) v.findViewById(R.id.bcheck);
// save the row's _id value in the checkbox's tag for retrieval later
cBox.setTag(Integer.valueOf(this.mCurrentCursor.getInt(0)));
if (this.mCurrentCursor.getInt(SqlHelper.COLUMN_SELECTED_idx) != 0) {
cBox.setChecked(true);
Log.w("SqlHelper", "CheckBox true for pos "+pos+", id="+this.mCurrentCursor.getInt(0));
} else {
cBox.setChecked(false);
Log.w("SqlHelper", "CheckBox false for pos "+pos+", id="+this.mCurrentCursor.getInt(0));
}
//cBox.setOnClickListener(this);
cBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Log.w("SqlHelper", "Selected a CheckBox and in onCheckedChanged: "+isChecked);
Integer _id = (Integer) buttonView.getTag();
ContentValues values = new ContentValues();
values.put(SqlHelper.COLUMN_SELECTED,
isChecked ? Integer.valueOf(1) : Integer.valueOf(0));
mDbHelper.dbSqlite.beginTransaction();
try {
if (mDbHelper.dbSqlite.update(SqlHelper.TABLE_NAME, values, "_id=?",
new String[] { Integer.toString(_id) }) != 1) {
throw new SQLException("onCheckedChanged failed to update _id="+_id);
}
mDbHelper.dbSqlite.setTransactionSuccessful();
} finally {
mDbHelper.dbSqlite.endTransaction();
}
Log.w("SqlHelper", "-- _id="+_id+", isChecked="+isChecked);
}
});
TextView txtTitle = (TextView) v.findViewById(R.id.txtTitle);
txtTitle.setText(this.mCurrentCursor.getString(this.mCurrentCursor
.getColumnIndex(SqlHelper.COLUMN_TITLE)));
return (v);
}
public void ClearSelections() {
this.mDbHelper.clearSelections();
this.mCurrentCursor.requery();
}
}
ListViewWithDBActivity.java
package com.appfulcrum.blog.examples.listviewcustomdb;
import android.app.Activity;
import android.os.Bundle;
public class ListViewWithDBActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
SqlHelper
// SqlHelper.java
package com.appfulcrum.blog.examples.listviewcustomdb;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;
public class SqlHelper extends SQLiteOpenHelper {
private static final String DATABASE_PATH = "/data/data/com.appfulcrum.blog.examples.listviewcustomdb/databases/";
public static final String DATABASE_NAME = "TODOList";
public static final String TABLE_NAME = "ToDoItems";
public static final int ToDoItems_VERSION = 1;
public static final String COLUMN_ID = "_id"; // 0
public static final String COLUMN_TITLE = "title"; // 1
public static final String COLUMN_NAME_DESC = "description";// 2
public static final String COLUMN_SELECTED = "selected"; // 3
public static final int COLUMN_SELECTED_idx = 3;
public SQLiteDatabase dbSqlite;
private Context mContext;
public SqlHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
createDB(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w("SqlHelper", "Upgrading database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS ToDoItems;");
createDB(db);
}
public void createDatabase(SQLiteDatabase db) {
createDB(db);
}
private void createDB(SQLiteDatabase db) {
if (db == null) {
db = mContext.openOrCreateDatabase(DATABASE_NAME, 0, null);
}
db.execSQL("CREATE TABLE IF NOT EXISTS ToDoItems (_id INTEGER PRIMARY KEY, title TEXT, "
+" description TEXT, selected INTEGER);");
db.setVersion(ToDoItems_VERSION);
//
// Generate a few rows for an example
//
// find out how many rows already exist, and make sure there's some minimum
SQLiteStatement s = db.compileStatement("select count(*) from ToDoItems;");
long count = s.simpleQueryForLong();
for (int i = 0; i < 20-count; i++) {
db.execSQL("INSERT INTO ToDoItems VALUES(NULL,'Task #"+i+"','Description #"+i+"',0);");
}
}
public void openDataBase() throws SQLException {
String myPath = DATABASE_PATH + DATABASE_NAME;
dbSqlite = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
@Override
public synchronized void close() {
if (dbSqlite != null)
dbSqlite.close();
super.close();
}
public Cursor getCursor() {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_NAME);
String[] asColumnsToReturn = new String[] { COLUMN_ID, COLUMN_TITLE,
COLUMN_NAME_DESC, COLUMN_SELECTED };
Cursor mCursor = queryBuilder.query(dbSqlite, asColumnsToReturn, null,
null, null, null, COLUMN_ID+" ASC");
return mCursor;
}
public void clearSelections() {
ContentValues values = new ContentValues();
values.put(COLUMN_SELECTED, 0);
this.dbSqlite.update(SqlHelper.TABLE_NAME, values, null, null);
}
}
Start.java
//src/Start.java
package com.appfulcrum.blog.examples.listviewcustomdb;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class Start extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnSimple = (Button) findViewById(R.id.btnSimple);
btnSimple.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),
" You clicked ListView From DB button", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(v.getContext(), CustomListViewDB.class);
startActivityForResult(intent, 0);
}
});
}
}
レイアウト/ main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/buttonlayout" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:gravity="left|top" android:paddingTop="2dp"
android:paddingBottom="2dp">
<TextView android:id="@+id/txtTest" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:textStyle="bold"
android:text="@string/app_name" android:textSize="15sp"
android:textColor="#FF0000" android:gravity="center_vertical"
android:paddingLeft="5dp">
</TextView>
<Button android:id="@+id/btnSimple"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="Listview from DB"
android:textColor="#000000"
>
</Button>
</LinearLayout>
レイアウト/ simple.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:id="@+id/buttonlayout"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:height="32dp"
android:gravity="left|top" android:paddingTop="2dp"
android:paddingBottom="2dp">
<LinearLayout android:id="@+id/buttonlayout2"
android:orientation="horizontal" android:layout_height="wrap_content"
android:gravity="left|center_vertical" android:layout_width="wrap_content"
android:layout_gravity="left|center_vertical">
<TextView android:id="@+id/txtTest"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:textStyle="bold"
android:text="@string/list_header" android:textSize="15sp"
android:gravity="center_vertical" android:paddingLeft="5dp">
</TextView>
<Button android:id="@+id/btnClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Clear"
android:textSize="15sp" android:layout_marginLeft="10px"
android:layout_marginRight="10px"
android:layout_marginBottom="2px"
android:layout_marginTop="2px" android:height="15dp"
android:width="70dp"></Button>
</LinearLayout>
</LinearLayout>
<TableLayout android:id="@+id/TableLayout01"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:stretchColumns="*">
<TableRow>
<ListView android:id="@android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></ListView>
</TableRow>
</TableLayout>
</LinearLayout>
レイアウト/ single_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal" android:gravity="center_vertical">
<CheckBox android:id="@+id/bcheck"
android:layout_width="wrap_content"
android:layout_height="fill_parent" />
<TextView android:id="@+id/txtTitle"
android:layout_width="wrap_content" android:gravity="left|center_vertical"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_alignParentLeft="true"
android:textSize="20sp" android:text="Test"
android:textStyle="bold" android:paddingLeft="5dp"
android:paddingRight="2dp" android:focusable="false"
android:focusableInTouchMode="false"></TextView>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content" android:orientation="horizontal"
android:gravity="right|center_vertical">
</LinearLayout>
</LinearLayout>
値/ストリング。あなたが構築したい場合は、XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, ListViewWithDBActivity!</string>
<string name="app_name">ListViewWithDB</string>
<string name="list_header">List Headers</string>
</resources>
のAndroidManifest.xmlは
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" android:versionName="1.0"
package="com.appfulcrum.blog.examples.listviewcustomdb">
<application android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar">
>
<activity android:name=".Start" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CustomListViewDB"></activity>
</application>
<uses-sdk android:minSdkVersion="7" /> <!-- android 1.6 -->
</manifest>
、描画可能にいくつかの任意icon.pngのを投げます。
ありがとうございます。
TL; DR ...本当は、もっと簡潔にしようとしています。 –
このような他の質問はより簡潔でしたが、依然として人々は混乱しました。私は必要なだけ多くの情報を提供したかったのです。私の追加の回答に記載されているように、別のサイトは正確な問題の解決策を提供しました。乾杯。試してみる価値があります。 – user877139