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

时间:2015-01-28 01:23:56

标签: android database android-fragments android-adapter android-recyclerview

我的MainActivity调用片段

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

placeholderFragment使用适配器填充RecyclerView

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

adapterUpcomingGames。适配器从用户输入的数据库中获取数据,作为即将到来的体育赛事列表。

@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。现在,我如何通过placeholderFragment通知适配器数据库已更新,从而更新RecyclerView以更新自身?

1 个答案:

答案 0 :(得分:0)

从查看代码,我可以为您考虑三种解决方案。按照(我的意见)解决方案的质量从最小到最好。

  1. 将您的片段fragmentCreateGame移至由您第一个活动
  2. 托管
  3. Start Activity For Result
  4. 使用Otto Event Bus。我会推荐otto。特别是如果你有多个对象可以听一个事件。
  5. 首先将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工作室将允许您使用“ALT + ENTER”修复它,然后选择“使用Subscribe注释的方法的_ignore警告”。 *你应该在销毁时拨打bus.unregister(this)。 *您可以有多个班级听一个帖子。

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