在数据库中更新数据后,recyclerview中的项目不会更新

时间:2016-05-26 09:15:26

标签: android android-recyclerview

我正在开发一个用户在运行时添加数据的项目。我正在使用cursorloader加载数据内容提供程序以将数据添加到数据库和customadapter以将数据设置为recyclerview。问题是每当用户向数据插入新数据时正在添加到数据库,但它没有在recyclerview中更新。

当用户输入数据时执行方法addDetails(View view)

public class AddLog extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{

    TextView TotalAmount,Date;
    EditText name,mobile,city,detailname,detailamount;
    RecyclerView adddetailtolist;
    DetailsAdapter adapter;
    Intent returnback;
    double totamount;
    long logid;
    String Debt = "Debt";
    String Paid = "Paid";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_log);
        Toolbar toolbar = (Toolbar)findViewById(R.id.addlogtoolbar);
        setSupportActionBar(toolbar);
        toolbar.setTitle("Add Log");
        returnback = new Intent(this,MainActivity.class);
        Intent intent = getIntent();
        logid = intent.getExtras().getLong("ID");
        TotalAmount = (TextView)findViewById(R.id.totalAmount);
        Date = (TextView)findViewById(R.id.addlogDate);
        name = (EditText)findViewById(R.id.AddName);
        mobile = (EditText)findViewById(R.id.AddPhone);
        city = (EditText)findViewById(R.id.Addcity);
        detailname = (EditText)findViewById(R.id.Detailname);
        detailamount = (EditText)findViewById(R.id.Detailamount);
        adddetailtolist = (RecyclerView)findViewById(R.id.addloglist);
        Date.setText(getDate());
        getSupportLoaderManager().initLoader(2,null,this);
    }
    private String getDate()
    {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE,dd-MMM-yyyy");
        String date = simpleDateFormat.format(calendar.getTime());
        return date;
    }
    public void addDetails(View view)
    {
        String Name = detailname.getText().toString();
        String Amount = detailamount.getText().toString();
        String date = Date.getText().toString();
        ContentValues contentValues = new ContentValues();
        contentValues.put(DataProvider.Dname,Name);
        contentValues.put(DataProvider.DCategory,Debt);
        contentValues.put(DataProvider.Damount,Amount);
        contentValues.put(DataProvider.Ddate,date);
        contentValues.put(DataProvider.Per_In,logid);
        getContentResolver().insert(DataProvider.ContentUri_Details,contentValues);
        adapter.notifyDataSetChanged();
        Toast.makeText(AddLog.this, DataProvider.Per_In, Toast.LENGTH_SHORT).show();
        NumberFormat currency = changeamount();
        TotalAmount.setText(currency.format(getAmount()));
    }   

    private double getAmount()
    {
        ContentProviderClient client = getContentResolver().acquireContentProviderClient(DataProvider.ContentUri_Details);
        SQLiteDatabase db = ((DataProvider)client.getLocalContentProvider()).sqLiteDatabase;
        String query = "SELECT SUM(DAmount) FROM Details WHERE Per_In = "+logid;
        Cursor cursor = db.rawQuery(query, null);
        cursor.moveToFirst();
        double amount = cursor.getDouble(0);
        cursor.close();
        client.release();
        return amount;
    }


    public NumberFormat changeamount()
    {
        Locale locale = new Locale("en","IN");
        NumberFormat currencyformat = NumberFormat.getCurrencyInstance(locale);
        return currencyformat;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuinflate = getMenuInflater();
        menuinflate.inflate(R.menu.addlogmenu,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case R.id.done:
                saveData();
        }
        return super.onOptionsItemSelected(item);
    }

    private void saveData()
    {
        String name1 = name.getText().toString();
        String phone  = mobile.getText().toString();
        String address = city.getText().toString();
        if (TextUtils.isEmpty(name1)||TextUtils.isEmpty(phone)||TextUtils.isEmpty(address))
        {
            if (TextUtils.isEmpty(name1))
            {
                name.setError("Feild can not be Empty");
            }
           else if (TextUtils.isEmpty(phone))
            {
                mobile.setError("Feild can not be Empty");
            }
           else if (TextUtils.isEmpty(address))
            {
                city.setError("Feild can not be Empty");
            }
        }
        else
        {
            ContentValues values = new ContentValues();
            values.put(DataProvider.Pname,name1);
            values.put(DataProvider.Pphone,phone);
            values.put(DataProvider.Paddress,address);
            values.put(DataProvider.PCategory,"Debt");
            values.put(DataProvider.Pamount,totamount);
            String uri = DataProvider.ContentUri_Person+"/"+logid;
            Uri uri1 = Uri.parse(uri);
            getContentResolver().update(uri1,values,null,null);
            startActivity(returnback);
            finish();
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(final int id, Bundle args)
    {
        String _uri = DataProvider.ContentUri_Details+"/"+logid;
        Uri uri = Uri.parse(_uri);
        return new CursorLoader(this,uri,new String[]{DataProvider.Dname,DataProvider.Damount,DataProvider.Ddate},null,null,null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data)
    {
        adapter = new DetailsAdapter(this,data);
        adddetailtolist.setAdapter(adapter);
        adddetailtolist.setLayoutManager(new LinearLayoutManager(this));
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {

    }
}

自定义光标适配器:

    public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {

    private Context mContext;

    private Cursor mCursor;

    private boolean mDataValid;

    private int mRowIdColumn;

    private DataSetObserver mDataSetObserver;

    public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
        mContext = context;
        mCursor = cursor;
        mDataValid = cursor != null;
        mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
        mDataSetObserver = new NotifyingDataSetObserver();
        if (mCursor != null) {
            mCursor.registerDataSetObserver(mDataSetObserver);
        }
    }

    public Cursor getCursor() {
        return mCursor;
    }

    @Override
    public int getItemCount() {
        if (mDataValid && mCursor != null) {
            return mCursor.getCount();
        }
        return 0;
    }

    @Override
    public long getItemId(int position) {
        if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
            return mCursor.getLong(mRowIdColumn);
        }
        return 0;
    }

    @Override
    public void setHasStableIds(boolean hasStableIds) {
        super.setHasStableIds(true);
    }

    public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);

    @Override
    public void onBindViewHolder(VH viewHolder, int position) {
        if (!mDataValid) {
            throw new IllegalStateException("this should only be called when the cursor is valid");
        }
        if (!mCursor.moveToPosition(position)) {
            throw new IllegalStateException("couldn't move cursor to position " + position);
        }
        onBindViewHolder(viewHolder, mCursor);
    }

    /**
     * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
     * closed.
     */
    public void changeCursor(Cursor cursor) {
        Cursor old = swapCursor(cursor);
        if (old != null) {
            old.close();
        }
    }

    /**
     * Swap in a new Cursor, returning the old Cursor.  Unlike
     * {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
     * closed.
     */
    public Cursor swapCursor(Cursor newCursor) {
        if (newCursor == mCursor) {
            return null;
        }
        final Cursor oldCursor = mCursor;
        if (oldCursor != null && mDataSetObserver != null) {
            oldCursor.unregisterDataSetObserver(mDataSetObserver);
        }
        mCursor = newCursor;
        if (mCursor != null) {
            if (mDataSetObserver != null) {
                mCursor.registerDataSetObserver(mDataSetObserver);
            }
            mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
            mDataValid = true;
            notifyDataSetChanged();
        } else {
            mRowIdColumn = -1;
            mDataValid = false;
            notifyDataSetChanged();
            //There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
        }
        return oldCursor;
    }

    private class NotifyingDataSetObserver extends DataSetObserver {
        @Override
        public void onChanged() {
            super.onChanged();
            mDataValid = true;
            notifyDataSetChanged();
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            mDataValid = false;
            notifyDataSetChanged();
            //There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
        }
    }
}

适配器类

public class DetailsAdapter extends CursorRecyclerViewAdapter<DetailsAdapter.View_Holder>
{

    public DetailsAdapter(Context context, Cursor cursor) {
        super(context, cursor);
    }
    public static class View_Holder extends RecyclerView.ViewHolder
    {
        TextView mName,mAmount,mDate;
        public View_Holder(View itemView)
        {
            super(itemView);
            mName = (TextView)itemView.findViewById(R.id.DetailName);
            mAmount = (TextView)itemView.findViewById(R.id.DetailAmount);
            mDate = (TextView)itemView.findViewById(R.id.DetailDate);
        }
    }
    @Override
    public DetailsAdapter.View_Holder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.addloglistlayout,parent,false);
        View_Holder viewHolder = new View_Holder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(DetailsAdapter.View_Holder viewHolder, Cursor cursor)
    {
        Details details = Details.from(cursor);
        viewHolder.mName.setText(details.getName());
        viewHolder.mAmount.setText(String.valueOf(details.getAmount()));
        viewHolder.mDate.setText(details.getDate());
    }
}

内容提供商:

public class DataProvider extends ContentProvider
{
    static final String ProviderName = "com.example.mrudu.accounts.provider";
    static final String URLPerson = "content://"+ProviderName+"/Person_Detail";
    static final String URLDetails = "content://"+ProviderName+"/Details";
    static final Uri ContentUri_Person = Uri.parse(URLPerson);
    static final Uri ContentUri_Details = Uri.parse(URLDetails);

    //Tables
    private static String PTableName = "Person_Detail";
    private static String DTableName = "Details";

    public static long insertId = 0;
    public static long logid = 0;

    //Person_Detail Coloumns
    public static String PID = "_Id";
    public static String Pname = "PName";
    public static String Pphone = "PMobile";
    public static String Paddress = "PCity";
    public static String PCategory = "PCategory";
    public static String Pamount = "PAmount";

    //Details coloumn
    public static String DID = "_Id";
    public static String Dname = "DName";
    public static String Damount = "DAmount";
    public static String Ddate = "DDate";
    public static String DCategory = "DCategory";
    public static String Per_In = "Per_In";

    private static final int Person = 1;
    private static final int Person_ID = 2;
    private static final int Details = 3;
    private static final int Details_Id = 4;

    static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    static
    {
        uriMatcher.addURI(ProviderName,PTableName,Person);
        uriMatcher.addURI(ProviderName,PTableName+"/#",Person_ID);
        uriMatcher.addURI(ProviderName,DTableName,Details);
        uriMatcher.addURI(ProviderName,DTableName+"/#",Details_Id);
    }

    public static SQLiteDatabase sqLiteDatabase;
    private static String Databasename = "Accounts";
    private static int DatabaseVersion = 1;

    private class DatabaseHelper extends SQLiteOpenHelper
    {

        public DatabaseHelper(Context context)
        {
            super(context, Databasename, null, DatabaseVersion);
        }

        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase)
        {
            String Create_Person = " Create Table "+PTableName+"("+PID+" INTEGER PRIMARYKEY ,"+Pname+" TEXT ,"+Pphone+" TEXT ,"+Paddress+" TEXT ,"+PCategory+" TEXT ,"+Pamount+" REAL"+")";
            String Create_Details = " Create Table "+DTableName+"("+DID+" INTEGER PRIMARYKEY ,"+Dname+" TEXT ,"+DCategory+" TEXT ,"+Damount+" REAl ,"+Ddate+" TEXT ,"+Per_In+" INTEGER )";
            sqLiteDatabase.execSQL(Create_Person);
            sqLiteDatabase.execSQL(Create_Details);
        }

        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1)
        {
            sqLiteDatabase.execSQL("Drop TABLE if exists"+PTableName);
            sqLiteDatabase.execSQL("Drop TABLE if exists"+DTableName);
            onCreate(sqLiteDatabase);
        }
    }
    @Override
    public boolean onCreate()
    {
        Context context = getContext();
        DatabaseHelper databaseHelper = new DatabaseHelper(context);
        sqLiteDatabase = databaseHelper.getWritableDatabase();
        return (sqLiteDatabase==null)?false:true;
    }
    @Override
    public Uri insert(Uri uri, ContentValues values)
    {
        switch (uriMatcher.match(uri))
        {
            case Person:
                long rowId = sqLiteDatabase.insert(PTableName,null,values);
                insertId = rowId;
                if (rowId>0)
                {
                   Uri _uri = ContentUris.withAppendedId(ContentUri_Person,rowId);
                    getContext().getContentResolver().notifyChange(_uri,null);
                    return _uri;
                }
                break;
            case Details:
                long rowId1 = sqLiteDatabase.insert(DTableName,null,values);
                if (rowId1>0)
                {
                    Uri _uri = ContentUris.withAppendedId(ContentUri_Details,rowId1);
                    getContext().getContentResolver().notifyChange(_uri,null);
                    return _uri;
                }
                break;
        }
        return null;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder)
    {
        SQLiteQueryBuilder sqLiteQueryBuilder = new SQLiteQueryBuilder();

        switch (uriMatcher.match(uri))
        {
            case Person_ID:
                sqLiteQueryBuilder.setTables(PTableName);
                sqLiteQueryBuilder.appendWhere(PID+ "="+ uri.getPathSegments().get(1));
                break;
            case Person:
                sqLiteQueryBuilder.setTables(PTableName);
                break;
            case Details_Id:
                sqLiteQueryBuilder.setTables(DTableName);
                sqLiteQueryBuilder.appendWhere(Per_In +"="+ uri.getPathSegments().get(1));
                break;
            case Details:
                sqLiteQueryBuilder.setTables(DTableName);
                break;
            default:
                throw new UnsupportedOperationException("Not yet implemented");
        }
        Cursor cursor = sqLiteQueryBuilder.query(sqLiteDatabase,projection,selection,selectionArgs,null,null,"_ID");
        cursor.setNotificationUri(getContext().getContentResolver(),uri);
        return cursor;

    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs)
    {
        int count = 0;
        switch (uriMatcher.match(uri))
        {
            case Person:
                count = sqLiteDatabase.update(PTableName,values,selection,selectionArgs);
                break;
            case Person_ID:
                count = sqLiteDatabase.update(PTableName,values,PID+" = "+uri.getPathSegments().get(1)+(!TextUtils.isEmpty(selection)?" AND (" + selection + ')':""),selectionArgs);
                break;
            case Details:
                count = sqLiteDatabase.update(DTableName,values,selection,selectionArgs);
                break;
            case Details_Id:
                count = sqLiteDatabase.update(DTableName,values,Per_In+" = "+uri.getPathSegments().get(1)+(!TextUtils.isEmpty(selection)?" AND (" + selection + ')':""),selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI " + uri );
        }
        getContext().getContentResolver().notifyChange(uri,null);
        return count;
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // Implement this to handle requests to delete one or more rows.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public String getType(Uri uri) {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

谢谢

1 个答案:

答案 0 :(得分:0)

问题出在旁边。在ContentProvider中更新数据期间,您发送通知:

getContext().getContentResolver().notifyChange(uri,null);

但你没有听取这些改变。请在此处查看更多信息:How do CursorLoader automatically updates the view even if the app is inactive?