导航抽屉片段 Sqlite

Posted

技术标签:

【中文标题】导航抽屉片段 Sqlite【英文标题】:Navigation Drawer Fragments Sqlite 【发布时间】:2018-01-16 08:12:45 【问题描述】:

我正在制作一个 TODO 应用程序。我有一个导航抽屉,其中包含工作、个人等项目。当您单击工作时,它会打开工作片段,您可以在其中添加任务。个人也是如此。在工作和个人Fragment 中,我将TODO 列表存储在SQLite 数据库中。我需要为每个片段创建一个单独的表吗? 现在我只创建一个表,当我添加一个任务时,它会同时添加到工作和个人中。

TaskContract.java

public final class TaskContract 

    private TaskContract()

    public static final String CONTENT_AUTHORITY="com.example.android.tasks";
    public static final Uri BASE_CONTENT_URI=Uri.parse("content://"+CONTENT_AUTHORITY);
    public static final String PATH_TASKS="tasks";

    public static final class TaskEntry implements BaseColumns
        public static final Uri CONTENT_URI=Uri.withAppendedPath(BASE_CONTENT_URI,PATH_TASKS);
        public static final String CONTENT_LIST_TYPE=
                ContentResolver.CURSOR_DIR_BASE_TYPE+"/"+CONTENT_AUTHORITY+"/"+PATH_TASKS;
        public static final String CONTENT_ITEM_TYPE=
                ContentResolver.CURSOR_ITEM_BASE_TYPE+"/"+CONTENT_AUTHORITY+"/"+PATH_TASKS;
        public static final String TABLE_NAME="tasks";

        public static final String _ID=BaseColumns._ID;
        public static final String NAME="taskname";
        public static final String DUEDATE="duedate";
        public static final String DUETIME="duetime";
    

TaskDBHelper.java

public class TaskDBHelper extends SQLiteOpenHelper 

    private static final String DATABASE_NAME="list.db";
    private static final int DATABASE_VERSION=1;

    public TaskDBHelper(Context context) 
        super(context, DATABASE_NAME,null,DATABASE_VERSION);
    

    @Override
    public void onCreate(SQLiteDatabase db) 

        String SQL_CREATE_TABLE="CREATE TABLE "+TaskContract.TaskEntry.TABLE_NAME+
                " ("+TaskContract.TaskEntry._ID+" INTEGER PRIMARY KEY AUTOINCREMENT,"
                +TaskContract.TaskEntry.NAME+" TEXT NOT NULL, "
                +TaskContract.TaskEntry.DUEDATE+" TEXT, "
                +TaskContract.TaskEntry.DUETIME+" TEXT);";


        db.execSQL(SQL_CREATE_TABLE);
    

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 

    

TaskProvider.java

public class TaskProvider extends ContentProvider 

    private static final String TAG = "TaskProvider";
    private static final int TASKS=100;
    private static final int TASK_ID=101;
    private static final UriMatcher URI_MATCHER=new UriMatcher(UriMatcher.NO_MATCH);

    static 
        URI_MATCHER.addURI(TaskContract.CONTENT_AUTHORITY,TaskContract.PATH_TASKS,TASKS);
        URI_MATCHER.addURI(TaskContract.CONTENT_AUTHORITY,TaskContract.PATH_TASKS+"/#",TASK_ID);
    

    private TaskDBHelper taskDBHelper;

    @Override
    public boolean onCreate() 

        taskDBHelper=new TaskDBHelper(getContext());
        return true;
    

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) 
       SQLiteDatabase sqLiteDatabase=taskDBHelper.getReadableDatabase();
        Cursor cursor;

        int match=URI_MATCHER.match(uri);
        switch (match)
            case TASKS:
                cursor=sqLiteDatabase.query(TaskContract.TaskEntry.TABLE_NAME,projection,selection,
                        selectionArgs,null,null,sortOrder);
                break;
            case TASK_ID:
                selection= TaskContract.TaskEntry._ID+"=?";
                selectionArgs=new String[]String.valueOf(ContentUris.parseId(uri));
                cursor=sqLiteDatabase.query(TaskContract.TaskEntry.TABLE_NAME,projection,selection,
                        selectionArgs,null,null,sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Cannot query Unknown Uri "+uri);
        
        cursor.setNotificationUri(getContext().getContentResolver(),uri);
        return cursor;
    

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) 
        final int match = URI_MATCHER.match(uri);
        switch (match) 
            case TASKS:
                return TaskContract.TaskEntry.CONTENT_LIST_TYPE;
            case TASK_ID:
                return TaskContract.TaskEntry.CONTENT_ITEM_TYPE;
            default:
                throw new IllegalStateException("Unknown URI " + uri + " with match " + match);
        
    

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) 
        final int match=URI_MATCHER.match(uri);
        switch (match)
            case TASKS:
                return insertTask(uri,values);
            default:
                throw new IllegalArgumentException("Insertion is not supported for "+uri);

        
    

    private Uri insertTask(Uri uri, ContentValues values) 
        String name=values.getAsString(TaskContract.TaskEntry.NAME);
        if(name==null)
            throw new IllegalArgumentException("Task Name is required");
        

       /* String duedate=values.getAsString(TaskContract.TaskEntry.DUEDATE);
        if(duedate==null)
            throw new IllegalArgumentException("DUEDATE is required");
        

        String duetime=values.getAsString(TaskContract.TaskEntry.DUETIME);
        if(duetime==null)
            throw new IllegalArgumentException("DUETIME is required");
        */

        SQLiteDatabase sqLiteDatabase=taskDBHelper.getWritableDatabase();
        long id=sqLiteDatabase.insert(TaskContract.TaskEntry.TABLE_NAME,
                null,values);
        if(id==-1)
            return null;
        
        getContext().getContentResolver().notifyChange(uri,null);
        return ContentUris.withAppendedId(uri,id);
    

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) 
        SQLiteDatabase database = taskDBHelper.getWritableDatabase();

        // Track the number of rows that were deleted
        int rowsDeleted;

        final int match = URI_MATCHER.match(uri);
        switch (match) 
            case TASKS:
                // Delete all rows that match the selection and selection args
                rowsDeleted = database.delete(TaskContract.TaskEntry.TABLE_NAME, selection, selectionArgs);
                break;
            case TASK_ID:
                // Delete a single row given by the ID in the URI
                selection = TaskContract.TaskEntry._ID + "=?";
                selectionArgs = new String[]  String.valueOf(ContentUris.parseId(uri)) ;
                rowsDeleted = database.delete(TaskContract.TaskEntry.TABLE_NAME, selection, selectionArgs);
                break;
            default:
                throw new IllegalArgumentException("Deletion is not supported for " + uri);
        

        // If 1 or more rows were deleted, then notify all listeners that the data at the
        // given URI has changed
        if (rowsDeleted != 0) 
            getContext().getContentResolver().notifyChange(uri, null);
        

        // Return the number of rows deleted
        return rowsDeleted;
    

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) 
        final int match=URI_MATCHER.match(uri);
        switch (match)
            case TASKS:
                return updateTask(uri,values,selection,selectionArgs);

            case TASK_ID:
                selection = TaskContract.TaskEntry._ID + "=?";
                selectionArgs = new String[]  String.valueOf(ContentUris.parseId(uri)) ;
                return updateTask(uri, values, selection, selectionArgs);
            default:
                throw new IllegalArgumentException("Update is not supported for " + uri);

        

    

    private int updateTask(Uri uri, ContentValues values, String selection, String[] selectionArgs) 
        if (values.containsKey(TaskContract.TaskEntry.NAME)) 
            String name = values.getAsString(TaskContract.TaskEntry.NAME);
            if (name == null) 
                throw new IllegalArgumentException("Task requires a name");
            
        

        if (values.containsKey(TaskContract.TaskEntry.DUEDATE)) 
            String duedate = values.getAsString(TaskContract.TaskEntry.DUEDATE);
            if (duedate == null) 
                throw new IllegalArgumentException("Task requires a duedate");
            
        

        if (values.containsKey(TaskContract.TaskEntry.DUETIME)) 
            String duetime = values.getAsString(TaskContract.TaskEntry.DUETIME);
            if (duetime == null) 
                throw new IllegalArgumentException("Task requires a duetime");
            
        


        // If there are no values to update, then don't try to update the database
        if (values.size() == 0) 
            return 0;
        

        // Otherwise, get writeable database to update the data
        SQLiteDatabase database = taskDBHelper.getWritableDatabase();

        // Perform the update on the database and get the number of rows affected
        int rowsUpdated = database.update(TaskContract.TaskEntry.TABLE_NAME, values, selection, selectionArgs);

        // If 1 or more rows were updated, then notify all listeners that the data at the
        // given URI has changed
        if (rowsUpdated != 0) 
            getContext().getContentResolver().notifyChange(uri, null);
        

        // Return the number of rows updated
        return rowsUpdated;

    

这是我的数据库和表创建代码。我应该为每个片段创建这些类吗?请帮忙? 我的应用类似于 Google Keep 应用

【问题讨论】:

【参考方案1】:

这不是为每个片段创建表的好方法。数据库设计应该独立于为其创建的视图。因此,您可以使用相同的表格根据表格字段显示不同的视图。

我认为你需要数据库模式设计来制作一个好的数据库。你可以参考这个链接-Where to find practical well-designed database schema examples to learn from?

在您的问题的上下文中,您将有一个表作为“节点”,其中将包含所有任务类型的公共列。假设“个人任务”类型包括与“工作”不同的提醒时间,那么您创建“提醒”表,将“node_id”与“时间”一起存储。通过这种方式,确定应用所需的表和列。

您必须根据您的应用要求决定database schema

希望这会有所帮助。

【讨论】:

以上是关于导航抽屉片段 Sqlite的主要内容,如果未能解决你的问题,请参考以下文章

带有嵌套片段的导航抽屉 (ViewPager)

Android:导航抽屉片段内的Viewpager

在导航抽屉关闭之前加载片段

导航架构组件 - 导航抽屉

使用导航抽屉旋转时的片段更改

带有许多片段的 Android 导航抽屉