新ListFragement使用的ContentProvider

新ListFragement使用的ContentProvider

本文介绍了安卓:刷新ListFragement使用的ContentProvider和装载机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的SQLite数据库和ContentProvider的填充ListFragment。现在的问题是,经过我添加了一个项目ListFragment是没有得到刷新。该ListFragment是空的。我必须关闭并重新打开该应用显示在列表中添加的项目。

我试着喜欢这个更新它:

 公共类RoomListFragment扩展ListFragment实现LoaderManager.LoaderCallbacks<&光标GT; {            使用SQLite和ContentProvider的填补ListFragment //适配器
            私人SimpleCursorAdapter DataAdapter的;            //需要创造空间对话框
            私人的EditText enter_room;
            私有静态视图textEntryView;        @覆盖
        公共无效的onCreate(捆绑savedInstanceState){
            super.onCreate(savedInstanceState);            //显示动作条项目
            setHasOptionsMenu(真);            // TODO:一个真正的名单适配器更换。
            displayListView();
        }
    @覆盖
        公共无效onResume(){
          super.onResume();
          //开始一个新的或在这个管理器重新启动现有的装载机
          getLoaderManager()restartLoader(0,null,则此)。
         }        @覆盖
        公共无效的onDestroy(){
          super.onDestroy();
         }         私人无效displayListView(){
          //所需的列被绑定
          的String [] =列新的String [] {
            Database.KEY_GROUPADDRESS,
            Database.KEY_NAME,
            Database.KEY_DPT
          };          //该数据将被绑定到XML定义的视图
          INT []为= INT新[] {
            R.id.groupaddress,
            R.id.name,
            R.id.dpt,
          };          //创建从SimpleCursorAdapter适配器
          DataAdapter的=新SimpleCursorAdapter(
            getActivity(),
            R.layout.device_info,
            空值,
            列,
            至,
            0);          //设置SimpleCursorAdapter为ListFragmentAdapter
          setListAdapter(DataAdapter的);          //确保装载机初始化和积极的。
          getLoaderManager()initLoader(0,null,则此)。
         }         //这就是所谓当一个新的Loader需要创建。
         @覆盖
         公共装载机<&光标GT; onCreateLoader(INT ID,捆绑参数){
             的String [] =投影{
                  Database.KEY_ROWID,
                  Database.KEY_GROUPADDRESS,
                  Database.KEY_NAME,
                  Database.KEY_DPT};
             CursorLoader cursorLoader =新CursorLoader(getActivity()
                     MyContentProvider.CONTENT_URI,投影,NULL,NULL,NULL);
             返回cursorLoader;
         }         @覆盖
         公共无效onLoadFinished(装载机<&光标GT;装载机,游标数据){
             //交换新的光标(该框架将采取关闭照顾
             //老光标一旦我们回来。)
             dataAdapter.swapCursor(数据);
             dataAdapter.notifyDataSetChanged();                如果(isResumed()){
                    setListShown(真);
                }其他{
                    setListShownNoAnimation(真);
             }
         }         @覆盖
         公共无效onLoaderReset(装载机<&光标GT;装载机){
             //这就是所谓的当提供给onLoadFinished一个光标()
             //上述即将被关闭。我们需要确保我们没有
             //不再使用它。
             dataAdapter.swapCursor(NULL);
         }

我添加了一个项目与此code:

动作条上的项目

  //处理的onclick事件
            @覆盖
            公共布尔onOptionsItemSelected(菜单项项){
               //处理项目选择
               开关(item.getItemId()){
                  案例R.id.menu_add:
                     //Toast.makeText(getActivity(),点击,Toast.LENGTH_SHORT).show();                     LayoutInflater工厂= LayoutInflater.from(getActivity());                     // textEntryView是包含文本字段的布局XML文件中警告对话框显示
                     textEntryView = factory.inflate(R.layout.dialog_add_room,NULL);                     //从布局控制
                     enter_room =(EditText上)textEntryView.findViewById(R.id.enter_room);                     //创建对话框
                     最后AlertDialog.Builder报警1 =新AlertDialog.Builder(getActivity());
                     //配置对话框
                     alert1.setTitle(RAUMhinzufügen:)。的setView(textEntryView)
                     .setPositiveButton(Hinzufügen
                            新DialogInterface.OnClickListener(){
                        公共无效的onClick(DialogInterface对话框,
                                INT whichButton){
                            。字符串ROOMNAME = enter_room.getText()的toString();                            Log.d(插入,插入..);                            ContentValues​​值=新ContentValues​​();
                            // TODO Richtige Spalte献给Raumname verwenden
                            values​​.put(Database.KEY_NAME,ROOMNAME);                            。getActivity()getContentResolver()插入(MyContentProvider.CONTENT_URI,价值观);                            dataAdapter.notifyDataSetChanged();                        }
                     })。setNegativeButton(Abbrechen,
                            新DialogInterface.OnClickListener(){
                        公共无效的onClick(DialogInterface对话框,
                                INT whichButton){
                            //取消对话框
                        }
                     });
                     alert1.show();
                     返回true;
                  默认:
                     返回super.onOptionsItemSelected(项目);
               }
            }

我的ContentProvider:

 进口android.content.ContentProvider;
进口android.content.ContentValues​​;
进口android.content.UriMatcher;
进口android.database.Cursor;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteQueryBuilder;
进口android.net.Uri;
进口android.text.TextUtils;公共类MyContentProvider扩展ContentProvider的{
     私人MyDatabaseHelper dbHelper;     私有静态最终诠释ALL_COUNTRIES = 1;
     私有静态最终诠释SINGLE_COUNTRY = 2;     //权威是你的供应商的符号名
     //为了避免与其他供应商的冲突,你应该使用
     //互联网域名所有权(反向)作为您的供应商权力的基础。
     私有静态最后弦乐AUTHORITY =de.mokkapps.fixknxdemo.contentprovider;     //通过追加路径数据库表创建从权威内容的URI
     公共静态最终乌里CONTENT_URI =
      Uri.parse(内容://+ AUTHORITY +/国家);     //内容URI模式匹配使用通配符内容的URI:
     // *:匹配任意长度的任何有效字符的字符串。
        //#:匹配任意长度的数字字符的字符串。
     私有静态最终UriMatcher uriMatcher;
     静态{
      uriMatcher =新UriMatcher(UriMatcher.NO_MATCH);
      uriMatcher.addURI(权威,国家,ALL_COUNTRIES);
      uriMatcher.addURI(权威国家/#,SINGLE_COUNTRY);
     }     //系统调用的onCreate(),当它启动的供应商。
     @覆盖
     公共布尔的onCreate(){
      //获取对数据库的访问帮手
      dbHelper =新MyDatabaseHelper(的getContext());
      返回false;
     }     //返回对应于内容URI MIME类型
     @覆盖
     公共字符串的getType(URI URI){      开关(uriMatcher.match(URI)){
      案例ALL_COUNTRIES:
       返回vnd.android.cursor.dir / vnd.com.as400sample code.contentprovider.countries
      案例SINGLE_COUNTRY:
       返回vnd.android.cursor.item / vnd.com.as400sample code.contentprovider.countries
      默认:
       抛出新抛出:IllegalArgumentException(不支持的URI:+ URI);
      }
     }     //插入()方法添加一个新行相应的表格,用价值观
     //在ContentValues​​说法。如果列名是不是在ContentValues​​说法,
     //你可能需要为它无论是在您的提供商code或提供一个默认值
     //你的数据库模式。
     @覆盖
     公共乌里插入(URI URI,ContentValues​​值){      SQLiteDatabase分贝= dbHelper.getWritableDatabase();
      开关(uriMatcher.match(URI)){
      案例ALL_COUNTRIES:
       //没做什么
       打破;
      默认:
       抛出新抛出:IllegalArgumentException(不支持的URI:+ URI);
      }
      长ID = db.insert(Database.SQLITE_TABLE,空,价值);
      的getContext()getContentResolver()有NotifyChange(URI,空)。
      返回Uri.parse(CONTENT_URI +/+ ID);
     }     //查询()方法必须返回一个游标对象,如果失败,
     //抛出一个异常。如果您正在使用的SQLite数据库作为数据存储,
     //你可以简单地返回由查询之一(返回光标)的方法
     // SQLiteDatabase类。如果查询不匹配任何行,你应该返回
     //光标实例,其getCount将()方法返回0。您应该返回null只
     在查询过程//如果发生内部错误。
     @覆盖
     公共光标查询(URI URI,字符串[]投影,字符串的选择,
       的String [] selectionArgs两个,字符串中将sortOrder){      SQLiteDatabase分贝= dbHelper.getWritableDatabase();
      SQLiteQueryBuilder的QueryBuilder =新SQLiteQueryBuilder();
      queryBuilder.setTables(Database.SQLITE_TABLE);      开关(uriMatcher.match(URI)){
      案例ALL_COUNTRIES:
       //没做什么
       打破;
      案例SINGLE_COUNTRY:
       。字符串ID = uri.getPathSegments()得到(1);
       queryBuilder.appendWhere(Database.KEY_ROWID +=+ ID);
       打破;
      默认:
       抛出新抛出:IllegalArgumentException(不支持的URI:+ URI);
      }      光标光标= queryBuilder.query(分贝,投影,选择,
        selectionArgs两个,NULL,NULL,中将sortOrder);
      返回游标;     }     //删除()方法删除基于选择,或者如果一个id为行
     //提供那么它删除的一行。该方法返回的数字
     //记录:从数据库中删除。如果您选择不删除数据
     //物理然后就在这里更新的标志。
     @覆盖
     公众诠释删除(URI URI,选择字符串,字符串[] selectionArgs两个){      SQLiteDatabase分贝= dbHelper.getWritableDatabase();
      开关(uriMatcher.match(URI)){
      案例ALL_COUNTRIES:
       //没做什么
       打破;
      案例SINGLE_COUNTRY:
       。字符串ID = uri.getPathSegments()得到(1);
       选择= Database.KEY_ROWID +=+ ID
       +(!TextUtils.isEmpty(选择)?
         AND(+选择+')':);
       打破;
      默认:
       抛出新抛出:IllegalArgumentException(不支持的URI:+ URI);
      }
      INT deleteCount = db.delete(Database.SQLITE_TABLE,选择selectionArgs两个);
      的getContext()getContentResolver()有NotifyChange(URI,空)。
      返回deleteCount;
     }     //更新()的方法是一样的delete()用于更新多行
     //基于选择或如果提供的行ID的单个行。该
     //更新方法返回更新的行数。
     @覆盖
     公众诠释更新(开放的URI,ContentValues​​值,字符串的选择,
       的String [] selectionArgs两个){
      SQLiteDatabase分贝= dbHelper.getWritableDatabase();
      开关(uriMatcher.match(URI)){
      案例ALL_COUNTRIES:
       //没做什么
       打破;
      案例SINGLE_COUNTRY:
       。字符串ID = uri.getPathSegments()得到(1);
       选择= Database.KEY_ROWID +=+ ID
       +(!TextUtils.isEmpty(选择)?
         AND(+选择+')':);
       打破;
      默认:
       抛出新抛出:IllegalArgumentException(不支持的URI:+ URI);
      }
      INT使用UpdateCount = db.update(Database.SQLITE_TABLE,价值观,选择,selectionArgs两个);
      的getContext()getContentResolver()有NotifyChange(URI,空)。
      返回使用UpdateCount;
     }
}


解决方案

您应该叫 notifyDataSetChanged(); 从内容提供商的插入方法中并提供URI作为一个参数。

在某个时间你正在调用notifyDataSetChanged()点;方法插入可能没有实际发生作为内容提供商的呼叫接入将被异步处理。

一个例子可能看起来像这样

  @覆盖
公共乌里插入(URI URI,ContentValues​​值){
    SQLiteDatabase SQLDB = mDB.getWritableDatabase();
    INT uriType = sURIMatcher.match(URI);
    长ID;
    开关(uriType){
        案例小组:
            ID = sqlDB.replace(TeamModel.TEAM_TABLE_NAME,空,价值);
            打破;
        案例CARS:
            ID = sqlDB.replace(CarModel.CAR_TABLE_NAME,空,价值);
            打破;
        案例TEAM_ERRORS:
            ID = sqlDB.replace(TeamErrorModel.TEAMS_ERRORS_TABLE_NAME,空,价值);
            串teamId = values​​.get(TeamErrorModel.COL_TEAM_ID)的ToString();
            字符串选择= TeamModel.COL_ID +=;
            的String [] = selectionArgs两个{teamId};
            setErrorFlagTeamModel(SQLDB,真实,选择selectionArgs两个);
            打破;
        默认:
            抛出新抛出:IllegalArgumentException(未知URI:+ URI);
    }
    的getContext()getContentResolver()有NotifyChange(URI,空,假)。
    返回Uri.parse(URI +/+ ID);
}

第一个参数是URI传递到插入的方法,并会告诉所有适配器听音两方面对特定URI来更新他们的数据。

最后一个参数(假)告诉同步适配器忽略这种变化。我假设你不使用同步适配器

在的ContentProvider所有方法应该调用以类似的方式将有NotifyChange方法

您可能会发现,插入居然失败了。所以确认实际被插入的记录。

更新
根据从@zapi下面的评论

Since answering your question you have posted your content provider and I can now see that in fact as per the above quote this is in fact your missing link

这篇关于安卓:刷新ListFragement使用的ContentProvider和装载机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 19:01