Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 通知RecyclerView适配器数据库已更改_Android_Database_Android Fragments_Android Adapter_Android Recyclerview - Fatal编程技术网

Android 通知RecyclerView适配器数据库已更改

Android 通知RecyclerView适配器数据库已更改,android,database,android-fragments,android-adapter,android-recyclerview,Android,Database,Android Fragments,Android Adapter,Android Recyclerview,我的main活动调用一个片段 @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction()

我的
main活动
调用一个片段

@Override
public void onNavigationDrawerItemSelected(int position) {
    // update the main content by replacing fragments
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.container, PlaceholderFragment.newInstance(position + 1),
                    "placeHolderFragmentTag")
            .commit();
}
占位符片段
用适配器填充
回收视图

    public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

@Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            dbHelper = new DatabaseHelper(getActivity().getApplicationContext());
            dbHelper.getWritableDatabase();
            dbHelper.openDataBase();

            adapterUpcomingGames = new AdapterUpcomingGames(retrieveGames(dbHelper.getUpcomingGames()));
        }
适配器PCominggames
。适配器从用户输入的数据库中获取数据,即即将到来的体育赛事的列表

@Override   // still placeholderFragment
        public void onActivityCreated(Bundle savedInstanceState)
        {
            super.onActivityCreated(savedInstanceState);

            mRecyclerView.setHasFixedSize(true);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
            mRecyclerView.setItemAnimator(new DefaultItemAnimator());

            switch(getArguments().getInt(ARG_SECTION_NUMBER))
            {
                case 1:     // This will be upcoming games
                    mRecyclerView.setAdapter(adapterUpcomingGames);
                    break;
                case 2:     // This will be past games
                    AdapterPastGames adapterPastGames;
                    adapterPastGames = new AdapterPastGames(retrieveGames(dbHelper.getPastGames()));
                    mRecyclerView.setAdapter(adapterPastGames);
                    break;
                default:    // Default is, well, anything that will work.
                    adapterUpcomingGames1 = new AdapterUpcomingGames(retrieveGames(dbHelper.getGames()));
                    mRecyclerView.setAdapter(adapterUpcomingGames1);
            }

            newGame.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View arg0){

                    Intent createGame = new Intent(getActivity(),
                            ActivityCreateGame.class);
                    startActivity(createGame);
                    adapterUpcomingGames.notifyDataSetChanged();
                }
            });

            setRetainInstance(true);
        }
在该视图中,有一个按钮用于添加游戏,即修改数据库。我通过调用一个新活动来实现这一点,
activityCreateGame
,它承载一个片段

@Override // activityCreateGame
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_create_game);

    fragmentCreateGame = new FragmentCreateGame();
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .attach(fragmentCreateGame)
            .replace(R.id.newGameContainer, fragmentCreateGame)
            .commit();

    restoreActionBar();
}
fragmentCreateGame
,允许用户输入所需信息,然后将其附加到数据库中。用户使用该活动中导航栏上的选项保存此信息

@Override  // activityCreateGame
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
            case R.id.action_save:
                // check if an error has occured
                if (fragmentCreateGame.CreateNewGame())
                {
                    Toast toast = Toast.makeText(this, R.string.toast_success_game_create,
                            Toast.LENGTH_SHORT);
                    toast.show();

                    finish();
                }
                else{
                    Toast toast = Toast.makeText(this, R.string.toast_failed_game_create,
                            Toast.LENGTH_SHORT);
                    toast.show();
                }
                break;
        }
        return super.onOptionsItemSelected(item);
    }

该操作将完成
activityCreateGame
。现在,我如何通知适配器,回到
占位符片段
中,数据库已经更新,从而更新
回收视图
以更新自身?

通过查看您的代码,我可以为您想出三种解决方案。按照(我的意见)解决方案的质量从最低到最佳的顺序

  • 将您的片段
    fragmentCreateGame
    移动到第一个活动托管的位置
  • 使用。我推荐奥托。尤其是当您可能有多个对象侦听一个事件时
  • 首先将Otto添加到您的项目中。在您的
    build.gradle
    中,将其添加到依赖项中

    dependencies {
       ....
       compile 'com.squareup:otto:1.3.6'
       ....
    } 
    
    在需要通知的活动中,在onCreate的开头添加以下内容:

     Bus bus = new Bus();
     bus.register(this);
    
    然后,创建一个“事件”类。它只是您传递给订阅者以通知订阅者的对象。您也可以向这些添加信息,以传递更多信息

    public class SomeCoolEvent{
          private String yourWisdom;
          public SomeCoolEvent(String yourWisdom){
               this.yourWisdom = yourWisdom;
          }
    
          public String getWisdom(){
              return yourWisdom;
          }
     }
    
    然后,在您正在做一些事情通知其他类的类中,执行以下操作:

    Bus bus = new Bus();
    bus.post(new SomeCoolEvent(yourWisdomStringFromThisClass));
    
    现在,回到您的第一个活动,添加一个用
    @Subscribe

     @Subscribe
     public void onAnyMethodNameYouWantCauseItDoesntMatter(SomeCoolEvent event){
           //this will be called when ANY class calls bus.post(SomeCoolEvent)
           String boomYouAreNotified = event.getWisdom();
      }
    
    在您的
    @Subscribe
    方法中,没有什么需要注意的。 *方法名并不重要,所以请给它一些对您有意义的东西。我喜欢在它前面加上“
    on
    ”,因为它就像一个回调。 *方法必须是
    public
    并返回
    void
    。 *您没有显式调用此方法,因此某些IDE可能会显示它未使用。Android studio将允许您使用“ALT+ENTER”来修复此问题,然后选择“\u忽略使用Subscribe注释的方法的警告”。 *您应该在销毁时调用
    bus.unregister(this)
    。 *你可以让多个班级听一篇文章


    现在,如果您开始在不同的线程上运行,事情可能会变得更加复杂。如果你这样做了,在我提供的Otto页面底部有一些解决方案

    在一些代码中帮助理解它的声音,从接口中考虑一个定制的侦听器,或者我想知道是否可能有类似的东西。我已经添加了一些代码,但我也会看一看。奥托现在可能有点超过我了。但我会看看的。做了一些修改,我的ActivityForResult运行得很好,但是RecyclerView没有更新。适配器似乎正在更改NOTIFYDATASETCHANGE,但视图没有更新。@JoshuaSutherland,因为您没有向适配器添加任何项目。创建适配器时,您正在查询数据库。这对第一个有效。但是当你调用notifiyDataSetChanged时,它不会再调用它。您需要创建数据的ArrayList,然后创建适配器,并传入此列表。然后将新数据添加到此列表,然后调用notifyDataSetChanged.OK。这是有道理的。那么,在这种情况下,什么是最好的呢?我应该重新查询数据库的结果吗?好的。请注意适配器、listView和list的实例。如果您重新查询列表,并将列表设置为您的结果,您的适配器可能在“查看”此更改时遇到问题。如果是这样,只需重新创建适配器并将其设置为列表视图。因此,如果可以管理所有实例,只需将项目添加到列表中即可。没有将它们设置到列表中。