【问题标题】:Refresh SQLite data on ListView with CursorAdapter使用 CursorAdapter 刷新 ListView 上的 SQLite 数据
【发布时间】:2017-02-03 22:28:32
【问题描述】:

应用程序:我有一个应用程序可以创建多台机器:

  • _id、名称和位置

每台机器我都要让用户输入收入

  • _id、note、date、money、machines_id

问题:OnLongClickListener之后不能同时刷新ListView AND 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;
}

光标适配器

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;
        }
    });

}

}

机器信息

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);
}

}

收入提供者

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;
}

}

【问题讨论】:

  • 你的意思是 - 在 OnLongClickListener 之后不能同时刷新 ListView 和 TextView ?我的意思是你在说哪个 TextView

标签: android listview android-sqlite android-adapter


【解决方案1】:

也许您可以尝试使用Loaders

他们让您将数据源(内容提供者或其他)与活动或片段绑定。当加载器处于活动状态时,它们应该监控数据源并在内容发生变化时提供新结果。

我会给你一个通用的方法来实现它们(特别是 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 是一个好的开始。

希望对你有帮助

【讨论】:

  • 抱歉,耽搁了这么久,我确实创建了一个 ContentProvider,但它还没有刷新列表。将发布我的其他课程。感谢您尝试提供帮助
  • 当你调用 mDbHelper.deleteIncome(id) 时,你的方法 delete (inside content provider) 被调用了吗?而且,我在 DBHelper 中看不到方法 deleteIncome
  • 包括方法。我没有在内容提供程序中调用 delete 方法,因为我想模拟 SQLite 原始查询 ""SELECT _id, note, date, money FROM income WHERE machines_id = "+ machineId+" ORDER BY date ASC"
  • 在执行原始删除后尝试这样做:if ( returnNum != 0 ) getContext().getContentResolver().notifyChange(uri,null); where int returnNum = db.delete(...)
  • 我认为它没有更新,因为你没有通知加载器,所以当你删除一些行时你必须这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多