0

Мои MainActivity называет фрагмент,Уведомлять базы данных RecyclerView адаптер изменен

@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, чтобы обновить себя?

+0

Опубликовать код, который поможет понять –

+0

Из его звуков, рассмотрите пользовательский встроенный прослушиватель из интерфейса или [Activity for Reuslt] (http://developer.android.com/training/basics/intents/result. html) –

+0

Мне было интересно, возможно, что-то подобное. Я добавил код, но я также посмотрю на это. –

ответ

0

От взгляда на ваш код я могу представить три решения для вас. В порядке (по моему мнению) качество решения от наименее до лучших.

  1. Переместите фрагмент fragmentCreateGame быть организовано вами первое мероприятие
  2. Start Activity For Result
  3. Использование Otto Event Bus. Я бы рекомендовал отто. Особенно, если у вас может быть несколько объектов, слушающих событие.

Сначала добавьте Отто в свой проект. В своем 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», затем выберите «_ignore warnings для методов, аннотированных с помощью Subscribe». * Вы должны позвонить bus.unregister(this) об уничтожении. * Вы можете использовать несколько классов для прослушивания одного сообщения.

Теперь все может усложниться, если вы начнете работать на разных потоках. Если вы это сделаете, есть решения для этого в нижней части страницы Отто, которую я предоставил.

+0

Отто, вероятно, немного передо мной. Но я посмотрю на это. Сделали некоторые изменения, и у меня ActivityForResult работает довольно хорошо, но RecyclerView не обновляется. Кажется, что адаптер получает notifyDataSetChanged, но никакого обновления не происходит с представлением. –

+0

@JoshuaSutherland Причина, по которой вы не добавляете какие-либо предметы в свой адаптер. Когда вы создаете свой адаптер, вы запрашиваете свою базу данных. Это работает для первого. Но когда вы вызываете notifiyDataSetChanged, он не вызывает это снова. Вам нужно создать ArrayList ваших данных, затем создать свой адаптер и передать этот список. Затем добавьте новые данные в этот список, затем вызовите notifyDataSetChanged. –

+0

ОК. В этом есть смысл. Что было бы лучше в этом случае? Должен ли я просто запрашивать базу данных на RESULT_OK? –

Смежные вопросы