我创建了一个演示应用程序,它将一些数据插入sqlite数据库并在listview [Fragment]上更新。但我想通过点击按钮添加另一个数据,该数据来自EditText,并使用新数据更新listview。
我在下面写下我的演示代码。请告诉我如何在listview中显示同时添加到数据库中的所有数据。
####################################### 步骤1package com.example.locationsample.database;
import java.util.List;
import android.database.sqlite.SQLiteDatabase;
public abstract class DataSource<T> {
public final SQLiteDatabase mDatabase;
public DataSource(final SQLiteDatabase database) {
mDatabase = database;
}
public abstract boolean insert(T entity);
public abstract boolean delete(T entity);
public abstract boolean update(T entity);
public abstract List read();
public abstract List read(String selection, String[] selectionArgs,
String groupBy, String having, String orderBy);
}
####################################### 第2步
package com.example.locationsample.model;
public class Test {
public Test() {
}
public Test(String name) {
this.name = name;
}
private int id;
private String name;
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(final int id) {
this.id = id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(final String name) {
this.name = name;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return name;
// return "Test [name=" + name + "]";
}
}
####################################################
package com.example.locationsample.database;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.locationsample.model.Test;
public class TestDataSource extends DataSource<Test> {
public static final String TABLE_NAME = "test";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_NAME = "name";
public static final String CREATE_COMMAND = "create table " + TABLE_NAME
+ " (" + COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_NAME + " text not null);";
public TestDataSource(final SQLiteDatabase database) {
super(database);
}
@Override
public boolean insert(final Test entity) {
if (entity == null) {
return false;
}
final long result = mDatabase.insert(TABLE_NAME, null,
generateContentValueFromObject(entity));
return result != -1;
}
@Override
public boolean delete(final Test entity) {
if (entity == null) {
return false;
}
final int result = mDatabase.delete(TABLE_NAME, COLUMN_ID + "=?",
new String[] { String.valueOf(entity.getId()) });
return result != 0;
}
@Override
public boolean update(final Test entity) {
if (entity == null) {
return false;
}
final int result = mDatabase.update(TABLE_NAME,
generateContentValueFromObject(entity), COLUMN_ID + "=?",
new String[] { String.valueOf(entity.getId()) });
return result != 0;
}
@Override
public List<Test> read() {
final Cursor cursor = mDatabase.query(TABLE_NAME, getAllColumns(),
null, null, null, null, null);
final List<Test> tests = new ArrayList<Test>();
if (cursor != null && cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
tests.add(generateObjectFromCursor(cursor));
cursor.moveToNext();
}
cursor.close();
}
return tests;
}
@Override
public List<Test> read(final String selection,
final String[] selectionArgs, final String groupBy,
final String having, final String orderBy) {
final Cursor cursor = mDatabase.query(TABLE_NAME, getAllColumns(),
selection, selectionArgs, groupBy, having, orderBy);
final List<Test> tests = new ArrayList<Test>();
if (cursor != null && cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
tests.add(generateObjectFromCursor(cursor));
cursor.moveToNext();
}
cursor.close();
}
return tests;
}
private String[] getAllColumns() {
return new String[] { COLUMN_ID, COLUMN_NAME };
}
private Test generateObjectFromCursor(final Cursor cursor) {
if (cursor == null) {
return null;
}
final Test test = new Test();
test.setId(cursor.getInt(cursor.getColumnIndex(COLUMN_ID)));
test.setName(cursor.getString(cursor.getColumnIndex(COLUMN_NAME)));
return test;
}
private ContentValues generateContentValueFromObject(final Test entity) {
if (entity == null) {
return null;
}
final ContentValues values = new ContentValues();
values.put(COLUMN_NAME, entity.getName());
return values;
}
}
####################################### 第4步
package com.example.locationsample.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TestDataSource.CREATE_COMMAND);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TestDataSource.TABLE_NAME);
onCreate(db);
}
}
##############################################
package com.example.locationsample.loader;
import android.content.Loader;
import android.os.AsyncTask;
import android.util.Log;
public abstract class ContentChangingTask<T1, T2, T3> extends
AsyncTask<T1, T2, T3> {
private static final String TAG = "ContentChangingTask";
private Loader<?> mLoader = null;
public ContentChangingTask(final Loader<?> loader) {
mLoader = loader;
}
@Override
protected void onPostExecute(final T3 result) {
// super.onPostExecute(result);
Log.i(TAG, "+++ onPostExecute() called! +++");
mLoader.onContentChanged();
}
}
##############################################
package com.example.locationsample.loader;
import java.util.List;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.util.Log;
public abstract class AbstractDataLoader<E extends List<?>> extends
AsyncTaskLoader<E> {
private static final String TAG = "AbstractDataLoader";
protected E mLastDataList = null;
protected abstract E buildList();
public AbstractDataLoader(final Context context) {
super(context);
}
/**
* Runs on a worker thread, loading in our data. Delegates the real work to
* concrete subclass' buildList() method.
*/
@Override
public E loadInBackground() {
Log.d(TAG, "+++ loadInBackground() called! +++");
return buildList();
}
/**
* Runs on the UI thread, routing the results from the background thread to
* whatever is using the dataList.
*/
@Override
public void deliverResult(final E dataList) {
Log.d(TAG, "+++ deliverResult() called! +++");
if (isReset()) {
// An async query came in while the loader is stopped
emptyDataList(dataList);
return;
}
final E oldDataList = mLastDataList;
mLastDataList = dataList;
if (isStarted()) {
super.deliverResult(dataList);
}
if (oldDataList != null && oldDataList != dataList
&& oldDataList.size() > 0) {
emptyDataList(oldDataList);
}
}
/**
* Starts an asynchronous load of the list data. When the result is ready
* the callbacks will be called on the UI thread. If a previous load has
* been completed and is still valid the result may be passed to the
* callbacks immediately.
*
* Must be called from the UI thread.
*/
@Override
protected void onStartLoading() {
//super.onStartLoading();
Log.d(TAG, "+++ onStartLoading() called! +++");
if (mLastDataList != null) {
deliverResult(mLastDataList);
}
if (takeContentChanged() || mLastDataList == null
|| mLastDataList.size() == 0) {
forceLoad();
}
}
/**
* Must be called from the UI thread, triggered by a call to stopLoading().
*/
@Override
protected void onStopLoading() {
Log.d(TAG, "+++ onStopLoading() called! +++");
// Attempt to cancel the current load task if possible.
cancelLoad();
}
/**
* Must be called from the UI thread, triggered by a call to cancel(). Here,
* we make sure our Cursor is closed, if it still exists and is not already
* closed.
*/
@Override
public void onCanceled(final E dataList) {
Log.d(TAG, "+++ onCanceled() called! +++");
if (dataList != null && dataList.size() > 0) {
emptyDataList(dataList);
}
}
/**
* Must be called from the UI thread, triggered by a call to reset(). Here,
* we make sure our Cursor is closed, if it still exists and is not already
* closed.
*/
@Override
protected void onReset() {
super.onReset();
Log.d(TAG, "+++ onReset() called! +++");
// Ensure the loader is stopped
onStopLoading();
if (mLastDataList != null && mLastDataList.size() > 0) {
emptyDataList(mLastDataList);
}
mLastDataList = null;
}
protected void emptyDataList(final E dataList) {
if (dataList != null && dataList.size() > 0) {
for (int i = 0; i < dataList.size(); i++) {
dataList.remove(i);
}
}
}
}
##############################################
package com.example.locationsample.loader;
import java.util.List;
import android.content.Context;
import android.util.Log;
import com.example.locationsample.database.DataSource;
import com.example.locationsample.model.Test;
public class SQLiteTestDataLoader extends AbstractDataLoader<List<Test>> {
private static final String TAG = "SQLiteTestDataLoader";
private final DataSource<Test> mDataSource;
private String mSelection;
private String[] mSelectionArgs;
private String mGroupBy;
private String mHaving;
private String mOrderBy;
public SQLiteTestDataLoader(final Context context,
final DataSource<Test> dataSource, final String selection,
final String[] selectionArgs, final String groupBy,
final String having, final String orderBy) {
super(context);
mDataSource = dataSource;
}
@SuppressWarnings("unchecked")
@Override
protected List<Test> buildList() {
final List<Test> testList = mDataSource.read(mSelection,
mSelectionArgs, mGroupBy, mHaving, mOrderBy);
return testList;
}
public void insert(final Test entity) {
new InsertTask(this).execute(entity);
}
public void update(final Test entity) {
new UpdateTask(this).execute(entity);
}
public void delete(final Test entity) {
new DeleteTask(this).execute(entity);
}
private class InsertTask extends ContentChangingTask<Test, Void, Void> {
InsertTask(final SQLiteTestDataLoader loader) {
super(loader);
}
@Override
protected Void doInBackground(final Test... params) {
Log.i(TAG, "+++ Inserting... +++");
mDataSource.insert(params[0]);
return (null);
}
}
private class UpdateTask extends ContentChangingTask<Test, Void, Void> {
UpdateTask(final SQLiteTestDataLoader loader) {
super(loader);
}
@Override
protected Void doInBackground(final Test... params) {
Log.i(TAG, "+++ Updating... +++");
mDataSource.update(params[0]);
return (null);
}
}
private class DeleteTask extends ContentChangingTask<Test, Void, Void> {
DeleteTask(final SQLiteTestDataLoader loader) {
super(loader);
}
@Override
protected Void doInBackground(final Test... params) {
Log.i(TAG, "+++ Deleting... +++");
mDataSource.delete(params[0]);
return (null);
}
}
}
###############################################
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/txt_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<EditText
android:id="@+id/edtxt_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toLeftOf="@+id/btn_add"
android:inputType="text"
android:labelFor="@+id/edtxt_add" />
<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="ADD" />
<fragment
android:id="@+id/titles"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/btn_add"
android:layout_below="@id/txt_data"
class="com.example.locationsample.MainFragment" />
</RelativeLayout>
#############################################
package com.example.locationsample;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import com.example.locationsample.database.DbHelper;
import com.example.locationsample.database.TestDataSource;
import com.example.locationsample.loader.SQLiteTestDataLoader;
import com.example.locationsample.model.Test;
import com.example.locationsample.utilities.Utils;
public class MainActivity extends Activity implements
OnClickListener {
private static final String TAG = "MainActivity";
private TextView mTxtData;
private EditText mEdTxtAdd;
private LocationManager mLocationManager;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTxtData = (TextView) findViewById(R.id.txt_data);
mEdTxtAdd = (EditText) findViewById(R.id.edtxt_add);
findViewById(R.id.btn_add).setOnClickListener(this);
DbHelper helper = new DbHelper(MainActivity.this);
SQLiteDatabase database = helper.getWritableDatabase();
TestDataSource dataSource = new TestDataSource(database);
List<Test> testList = dataSource.read();
if (testList == null || testList.size() == 0) {
dataSource.insert(new Test("11111"));
dataSource.insert(new Test("22222"));
dataSource.insert(new Test("33333"));
}
database.close();
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_add:
if (mEdTxtAdd == null
|| TextUtils.isEmpty(mEdTxtAdd.getText().toString())) {
return;
}
DbHelper helper = new DbHelper(MainActivity.this);
SQLiteDatabase database = helper.getWritableDatabase();
TestDataSource dataSource = new TestDataSource(database);
SQLiteTestDataLoader loader = new SQLiteTestDataLoader(
MainActivity.this, dataSource, null, null, null, null, null);
loader.insert(new Test(mEdTxtAdd.getText().toString()));
break;
default:
break;
}
}
}
###############################################
package com.example.locationsample;
import java.util.List;
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Loader;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import com.example.locationsample.database.DbHelper;
import com.example.locationsample.database.TestDataSource;
import com.example.locationsample.loader.SQLiteTestDataLoader;
import com.example.locationsample.model.Test;
public class MainFragment extends ListFragment implements
LoaderCallbacks<List<Test>> {
private ArrayAdapter<Test> mAdapter;
// The Loader's id (this id is specific to the ListFragment's LoaderManager)
private static final int LOADER_ID = 1;
private static final boolean DEBUG = true;
private static final String TAG = "MainFragment";
private SQLiteDatabase mDatabase;
private TestDataSource mDataSource;
private DbHelper mDbHelper;
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mDbHelper = new DbHelper(getActivity());
mDatabase = mDbHelper.getWritableDatabase();
mDataSource = new TestDataSource(mDatabase);
mAdapter = new ArrayAdapter<Test>(getActivity(),
android.R.layout.simple_list_item_1);
setEmptyText("No data, please add from menu.");
setListAdapter(mAdapter);
setListShown(false);
if (DEBUG) {
Log.i(TAG, "+++ Calling initLoader()! +++");
if (getLoaderManager().getLoader(LOADER_ID) == null) {
Log.i(TAG, "+++ Initializing the new Loader... +++");
} else {
Log.i(TAG,
"+++ Reconnecting with existing Loader (id '1')... +++");
}
}
// Initialize a Loader with id '1'. If the Loader with this id already
// exists, then the LoaderManager will reuse the existing Loader.
getLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override
public Loader<List<Test>> onCreateLoader(final int id, final Bundle arg1) {
final SQLiteTestDataLoader loader = new SQLiteTestDataLoader(
getActivity(), mDataSource, null, null, null, null, null);
return loader;
}
@Override
public void onLoadFinished(final Loader<List<Test>> loader,
final List<Test> data) {
Log.d(TAG, "+++### onLoadFinished() called! ###+++");
if (DEBUG)
Log.i(TAG, "+++ onLoadFinished() called! +++");
mAdapter.clear();
for (final Test test : data) {
mAdapter.add(test);
}
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
}
@Override
public void onLoaderReset(final Loader<List<Test>> arg0) {
Log.i(TAG, "+++ onLoadReset() called! +++");
mAdapter.clear();
}
@Override
public void onDestroy() {
super.onDestroy();
mDbHelper.close();
mDatabase.close();
mDataSource = null;
mDbHelper = null;
mDatabase = null;
}
}
#
每当我在edittext中写一些内容并单击Add按钮时,它只将数据存储到数据库中,但它不会更新到我们在那里显示的listview。 请检查我在哪里弄错???
答案 0 :(得分:0)
在onClick
getLoaderManager().restartLoader(0,null,this);