该应用:我有一个可以创建多台计算机的应用:
每台机器我都要让用户输入收入
问题: OnLongClickListener 后无法同时刷新 ListView和TextView 。
我尝试过:光标适配器,swapCursor。
我的问题:在同一活动中同时更新这两件事的最佳方法是什么?
如果您需要任何其他课程或有任何反馈,请随意放纵我!
DBHelper
public class DBHelpter extends SQLiteOpenHelper {
private static final String DB_NAME = "machines.db";
private static final int DB_VERSION = 1;
public static final String TABLE_MACHINES = "machines";
public static final String MACHINES_COLUMN_NAME = "name";
public static final String MACHINES_COLUMN_LOCATION = "location";
public static final String MACHINES_ID = "id";
public static final String TABLE_INCOME = "income";
public static final String INCOME_COLUMN_MONEY = "money";
public static final String INCOME_COLUMN_DATE = "date";
public static final String INCOME_COLUMN_NOTE = "note";
public static final String INCOME_ID = "id";
public static final String INCOME_COLUMN_MACHINES_ID = "machines_id";
private Context mContext;
public DBHelpter(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query1 = String.format("CREATE TABLE " + TABLE_MACHINES + "("
+ MACHINES_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ MACHINES_COLUMN_NAME + " TEXT NOT NULL, "
+ MACHINES_COLUMN_LOCATION + " TEXT NOT NULL)",
TABLE_MACHINES, MACHINES_COLUMN_NAME, MACHINES_COLUMN_LOCATION, MACHINES_ID);
String query2 = String.format("CREATE TABLE " + TABLE_INCOME + "("
+ INCOME_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ INCOME_COLUMN_MONEY + " REAL NOT NULL, "
+ INCOME_COLUMN_DATE + " DATE NOT NULL, "
+ INCOME_COLUMN_NOTE + " TEXT NOT NULL, "
+ INCOME_COLUMN_MACHINES_ID + " INTEGER NOT NULL)",
TABLE_INCOME, INCOME_ID, INCOME_COLUMN_MONEY, INCOME_COLUMN_DATE, INCOME_COLUMN_NOTE, INCOME_COLUMN_MACHINES_ID);
db.execSQL(query1);
db.execSQL(query2);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String query1 = String.format("DROP TABLE IF EXISTS " + TABLE_MACHINES);
String query2 = String.format("DROP TABLE IF EXISTS " + TABLE_INCOME);
db.execSQL(query1);
db.execSQL(query2);
onCreate(db);
}
public void insertNewMachine(String name, String location){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(MACHINES_COLUMN_NAME, name);
values.put(MACHINES_COLUMN_LOCATION, location);
db.insertWithOnConflict(TABLE_MACHINES, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void insertNewIncome(Double money, String date, String note, long machines_id){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(INCOME_COLUMN_MONEY, money);
values.put(INCOME_COLUMN_DATE, date);
values.put(INCOME_COLUMN_NOTE, note);
values.put(INCOME_COLUMN_MACHINES_ID, machines_id);
db.insertWithOnConflict(TABLE_INCOME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void getIncomeOfMachine(long machinesId){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT machines_id, SUM(money) AS total FROM income WHERE machines_id = "+machinesId+"", null);
cursor.moveToFirst();
double total_amount = cursor.getDouble(cursor.getColumnIndex("total"));
return total_amount;
}
public ArrayList<MachinesClass> getAllMachines(){
ArrayList<MachinesClass> machinesList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM "+ TABLE_MACHINES, null);
while (cursor.moveToNext()){
final long id = cursor.getLong(cursor.getColumnIndex(MACHINES_ID));
final String name = cursor.getString(cursor.getColumnIndex(MACHINES_COLUMN_NAME));
final String location = cursor.getString(cursor.getColumnIndex(MACHINES_COLUMN_LOCATION));
machinesList.add(new MachinesClass(id, name, location));
}
cursor.close();
db.close();
return machinesList;
}
public void deleteIncome(long id){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_INCOME, INCOME_ID+ "=?", new String[]{id + ""});
db.close();
}
public Cursor getInfoOfMachine(long machinesId){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT _id, note, date, money FROM income WHERE machines_id = "+machinesId+" ORDER BY date ASC",null);
return cursor;
}
的CursorAdapter
public class ListAdapter extends CursorAdapter {
public ListAdapter(Context context, Cursor c) {
super(context, c);
}
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.notes_list, parent, false);
}
@Override
public void bindView(View view, final Context context, final Cursor cursor) {
final DBHelpter mDBHelper = new DBHelpter(context);
TextView mNote = (TextView) view.findViewById(R.id.tvNote);
TextView mNotesDate = (TextView) view.findViewById(R.id.tvFecha);
TextView mMoney = (TextView) view.findViewById(R.id.tvMoney);
RelativeLayout mRelativeLayout = (RelativeLayout) view.findViewById(R.id.rlNotesList);
final Long id = cursor.getLong(cursor.getColumnIndex("_id"));
String note = cursor.getString(cursor.getColumnIndex("note"));
String date = cursor.getString(cursor.getColumnIndex("date"));
double money = cursor.getDouble(cursor.getColumnIndex("money"));
mNote.setText(note);
mNotesDate.setText(date);
DecimalFormat formatter = new DecimalFormat("$#,##0.000");
String formatted = formatter.format(money);
mMoney.setText(formatted);
mNote.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
AlertDialog alertDialog = new AlertDialog.Builder(v.getContext())
.setTitle("Confirmación")
.setMessage(Html.fromHtml("Segura de "+"<b>"+"BORRAR"+"</b>"+" la información?"))
.setNegativeButton("No", null)
.setPositiveButton("Si", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mDBHelper.deleteIncome(id);
notifyDataSetChanged();
}
})
.create();
alertDialog.show();
return true;
}
});
}
}
MachineInfo
public class MachineInfo extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
private TextView mLocation, mMoney;
private DBHelpter mDBHelpter;
private ListView mNotesList;
private FloatingActionButton mFAB;
private SQLiteDatabase db;
private Cursor mCursor;
private ListAdapter mAdapter;
private Context mContext;
private static final int LOADER_INTEGER = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_machine_info);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDBHelpter = new DBHelpter(getApplicationContext());
db = mDBHelpter.getWritableDatabase();
mLocation = (TextView) findViewById(R.id.tvLocation);
mMoney = (TextView) findViewById(R.id.tvMoney);
mFAB = (FloatingActionButton) findViewById(R.id.fabAddIncome);
mNotesList = (ListView) findViewById(R.id.lvNotes);
SharedPreferences mSharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
final Long machines_id = mSharedPreferences.getLong("machines_id", 0);
double total_amount = mDBHelpter.getIncomeOfMachine(machines_id);
DecimalFormat formatter = new DecimalFormat("$#,##0.000");
String formatted = formatter.format(total_amount);
mMoney.setText(formatted);
String location = mSharedPreferences.getString("location", null);
mLocation.setText(location);
mAdapter = new ListAdapter(this, mDBHelpter.getInfoOfMachine(machines_id));
mAdapter.notifyDataSetChanged();
mNotesList.setAdapter(mAdapter);
getLoaderManager().initLoader(LOADER_INTEGER, null, this);
mFAB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(getApplicationContext(), IncomeCreation.class);
startActivity(i);
}
});
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
SharedPreferences mSharedPreferences = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
final Long machines_id = mSharedPreferences.getLong("machines_id", 0);
String[] projection = new String[]{"_id", "note", "date", "money"};
String selection = "machines_id = "+machines_id;
String sortOrder = "date ASC";
return new CursorLoader(this, IncomeProvider.CONTENT_URI, projection, selection, null, sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
IncomeProvider
public class IncomeProvider extends ContentProvider {
private static final int INCOME = 1;
private static final int INCOME_ID = 2;
private static final String PROVIDER = "tech.destinum.machines.incomeprovider";
static final Uri CONTENT_URI = Uri.parse("content://"+ PROVIDER + "/income");
public static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static{
mUriMatcher.addURI(PROVIDER, "income", INCOME);
mUriMatcher.addURI(PROVIDER, "income/#", INCOME_ID);
}
private DBHelpter mDBHelper;
private SQLiteDatabase db;
@Override
public boolean onCreate() {
Context context = getContext();
mDBHelper = new DBHelpter(context);
SQLiteDatabase db = mDBHelper.getWritableDatabase();
return (db == null)? false:true;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(DBHelpter.TABLE_INCOME);
switch (mUriMatcher.match(uri)) {
case INCOME:
break;
case INCOME_ID:
queryBuilder.appendWhere(DBHelpter.INCOME_ID + "="
+ uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SharedPreferences mSharedPreferences = getContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
final Long machines_id = mSharedPreferences.getLong("machines_id", 0);
db = mDBHelper.getWritableDatabase();
projection = new String[]{"_id", "note", "date", "money"};
selection = "machines_id = "+machines_id;
sortOrder = "date ASC";
Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Nullable
@Override
public String getType(Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = mUriMatcher.match(uri);
SQLiteDatabase sqlDB = mDBHelper.getWritableDatabase();
long id = 0;
switch (uriType) {
case INCOME:
id = sqlDB.insert(DBHelpter.TABLE_INCOME, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse("income" + "/" + id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = mUriMatcher.match(uri);
SQLiteDatabase sqlDB = mDBHelper.getWritableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case INCOME:
rowsDeleted = sqlDB.delete(DBHelpter.TABLE_INCOME, selection,
selectionArgs);
break;
case INCOME_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(
DBHelpter.TABLE_INCOME,
DBHelpter.INCOME_ID + "=" + id,
null);
} else {
rowsDeleted = sqlDB.delete(
DBHelpter.TABLE_INCOME,
DBHelpter.INCOME_ID + "=" + id
+ " and " + selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int uriType = mUriMatcher.match(uri);
SQLiteDatabase sqlDB = mDBHelper.getWritableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case INCOME:
rowsUpdated = sqlDB.update(DBHelpter.TABLE_INCOME,
values,
selection,
selectionArgs);
break;
case INCOME_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqlDB.update(DBHelpter.TABLE_INCOME,
values,
DBHelpter.INCOME_ID + "=" + id,
null);
} else {
rowsUpdated = sqlDB.update(DBHelpter.TABLE_INCOME,
values,
DBHelpter.INCOME_ID + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
}
答案 0 :(得分:1)
也许您可以尝试使用Loaders。
他们让您将数据源(Content Provider或其他)与Activity或Fragment绑定在一起。当加载程序处于活动状态时,它们应监视其数据源并在内容更改时提供新结果。
我将为您提供实现它们的一般方法(特别是CursorLoader):
public class MachineInfo extends AppCompatActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final int LOADER_INTEGER = 1;
// ... existing code
@Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(LOADER_INTEGER, null, this);
super.onActivityCreated(savedInstanceState);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(
this,
ContentProvider.CONTENT_URI,
projection,
null,
null,
sortOrder
);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mCursorAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mCursorAdapter.swapCursor(null);
}
}
你可以在互联网上阅读很多相关信息,例如here就是一个好的开始。
希望这有帮助