RecyclerView перезагружается при нажатии элемента

Я использую Firebase для серверной части своих приложений и получаю свои данные как исключение. После того, как я получу свои данные, я отправляю их с помощью otto bus, и код можно увидеть ниже.

@Subscribe
public void loadBrothers(ServiceCalls.SearchBrothersRequest request) {
  final ServiceCalls.SearchBrothersResponse response = new ServiceCalls.SearchBrothersResponse();
  response.Brothers = new ArrayList<>();
  Firebase reference = new Firebase("my data's url here");

  reference.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
      int index = 0;

      for (DataSnapshot brotherSnapchat : dataSnapshot.getChildren()) {
        BrotherFireBase bro = brotherSnapchat.getValue(BrotherFireBase.class);
        Log.i(LOG_TAG, bro.getName());
        Log.i(LOG_TAG, bro.getWhy());
        Log.i(LOG_TAG, bro.getPicture());
        Log.i(LOG_TAG, bro.getMajor());
        Log.i(LOG_TAG, bro.getCross());
        Log.i(LOG_TAG, bro.getFact());

        Brother brother = new Brother(
                        index,
                        bro.getName(),
                        bro.getWhy(),
                        bro.getPicture(),
                        bro.getMajor(),
                        bro.getCross(),
                        bro.getFact());

        response.Brothers.add(brother);
        index++;
      }

      bus.post(response);
    }

    @Override
    public void onCancelled(FirebaseError firebaseError) {

    }
  });

Как только данные находятся в моем RecyclerView, я должен щелкнуть элемент, и его соответствующее действие должно появиться в диалоговом окне пользовательского действия. Однако, поскольку действие является диалоговым, вы можете увидеть перезагрузку RecyclerView в фоновом режиме. Этого не происходит, когда я не получаю данные из Интернета. После нескольких кликов приложение вылетает из-за исключения нехватки памяти. Есть ли что-то, что мне не хватает?

Вот активность, в которой находится recyclerView:

@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View view = inflater.inflate(R.layout.fragment_meet_a_brother, container, false);
  adapter = new BrotherRecycleAdapter((BaseActivity) getActivity(),this);
  brothers = adapter.getBrothers();
  recyclerView =(RecyclerView) view.findViewById(R.id.fragment_meet_a_brother_recycleView);
  recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),3));
  setUpAdapter();
  bus.post(new ServiceCalls.SearchBrothersRequest("Hello"));
  return view;
}

private void setUpAdapter(){
  if(isAdded()){
    recyclerView.setAdapter(adapter);
  }
}


@Subscribe
public void onBrosLoaded(final ServiceCalls.SearchBrothersResponse response){
  int oldBrotherLength = brothers.size();
  brothers.clear();
  adapter.notifyItemRangeRemoved(0, oldBrotherLength);
  brothers.addAll(response.Brothers);

  //Delete for Debug method...
  adapter.notifyItemRangeChanged(0,brothers.size());
  Log.i(LOG_TAG, Integer.toString(brothers.size()));
}


@Override
public void onBrotherClicked(Brother brother) {
  Intent intent = BrotherPagerActivity.newIntent(getActivity(),brother);
  Log.i(LOG_TAG,brother.getBrotherName() + " was Clicked");
  startActivity(intent);
}

На всякий случай, вот также действие, которое запускается при нажатии на элемент списка, это viewPager activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_brother_pager);

  brothers = new ArrayList<>();
  bus.post(new ServiceCalls.SearchBrothersRequest("Hello"));

  FragmentManager fragmentManager = getSupportFragmentManager();
  viewPager = (ViewPager) findViewById(R.id.activity_brother_viewPager);
  viewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
    @Override
    public Fragment getItem(int position) {
      Brother brother = brothers.get(position);
      return BrotherDetailsFragment.newInstance(brother);
    }

    @Override
    public int getCount() {
      return brothers.size();
    }
  });

}

@Subscribe
public void onBrosLoad(final ServiceCalls.SearchBrothersResponse response){
  brothers.clear();
  brothers.addAll(response.Brothers);
  viewPager.getAdapter().notifyDataSetChanged();
  Brother brother = getIntent().getParcelableExtra(BROTHER_EXTRA_INFO);
  int brotherId = brother.getBrotherId();

  for(int i=0;i<brothers.size();i++){
    if(brothers.get(i).getBrotherId() == brotherId){
      viewPager.setCurrentItem(i);
      break;
    }
  }
  Log.i(LOG_TAG, Integer.toString(brothers.size()));
}

public static Intent newIntent(Context context, Brother brother){
  Intent intent = new Intent(context,BrotherPagerActivity.class);
  intent.putExtra(BROTHER_EXTRA_INFO,brother);
  return intent;
}

Любая помощь очень ценится спасибо!


person CV_Res    schedule 20.07.2016    source источник


Ответы (2)


в public void onBrotherClicked(Brother brother), где находится RecyclerView, вы вызываете:

Intent intent = BrotherPagerActivity.newIntent(getActivity(),brother);

который позвонит

Intent intent = new Intent(context,BrotherPagerActivity.class);`

в newIntent вашего viewPager activity.

Это может быть рекурсивный вызов.

попробуйте добавить:

public static Intent newIntent(Context context, Brother brother){
  Intent intent = new Intent(context,BrotherPagerActivity.class);
  intent.putExtra(BROTHER_EXTRA_INFO,brother);
  return intent;
}

в Activity, где находится ваш RecyclerView. И вызовите туда свою активность ViewPage.

-- ОБНОВЛЕНИЕ --

Вызовите свою активность на странице просмотра (которая используется для отображения данных Brother) с помощью следующего кода:

private void showBrotherData(Brother brother){
  Intent intent = new Intent(this, BrotherPagerActivity.class);
  intent.putExtra(BROTHER_EXTRA_INFO, brother);
  this.startActivity(intent);
}
person ישו אוהב אותך    schedule 20.07.2016
comment
поэтому я должен поместить метод newIntent туда, где находится recyclerview, а затем вызвать метод для OnBrotherClicked? - person CV_Res; 20.07.2016
comment
Вы должны поместить его туда, где находится ваш RecyclerView. Кстати, I forget to add context.startActivity(intent); в newIntent обновит его. - person ישו אוהב אותך; 20.07.2016
comment
все еще не повезло, у меня такое чувство, что это то место, где я поставил автобус. почтовый звонок - person CV_Res; 20.07.2016
comment
Похоже, вы правы, попробуйте прокомментировать код, который не используется для распределения событий, чтобы убедиться, что ваш post работает правильно. А в onBrosLoaded вы используете немного неправильный код, читайте подробнее stackoverflow.com/a/30057015/4758255 - person ישו אוהב אותך; 20.07.2016
comment
Причина, по которой recyclerView перезагружается, заключается в том, что я вызываю notifydataSetChanged в recyclerView. Однако, когда я удаляю этот код в реальном сервисе, приложение вылетает. Любые идеи? - person CV_Res; 21.07.2016

Я нашел ответ! Я изменил свой recyclerView, чтобы он обновлялся только в том случае, если размер массива был равен нулю.

@Subscribe
public void onBrosLoaded(final ServiceCalls.SearchBrothersResponse response){
    int oldBrotherLength = brothers.size();
    Log.i(LOG_TAG, "Brother lists old size" + Integer.toString(oldBrotherLength));
    if(oldBrotherLength ==0){
        brothers.clear();
        adapter.notifyItemRangeRemoved(0, oldBrotherLength);
        brothers.addAll(response.Brothers);
        //Delete for Debug method...
        adapter.notifyItemRangeChanged(0,brothers.size());
    } else{
        return;
    }
    Log.i(LOG_TAG, Integer.toString(brothers.size()));
}

Я не знаю, насколько хорошо это решение с точки зрения чистоты, но оно работает для меня. Я надеюсь, что это помогает кому-то.

person CV_Res    schedule 21.07.2016
comment
Рад, что вы нашли ответ :). Но ваше решение может не работать, когда в RecyclerView уже есть некоторые данные. - person ישו אוהב אותך; 21.07.2016
comment
Я закрыл приложение и снова открыл его, и до сих пор ничего не разбилось, что является началом, лол, если вы можете сказать мне другой способ проверить, буду ли я в каких-либо проблемах, я буду очень признателен. - person CV_Res; 21.07.2016
comment
Пока что нет :P. Просто создайте еще один вопрос, если у вас есть проблемы. ;) - person ישו אוהב אותך; 22.07.2016
comment
Спасибо тебе за помощь! Если вам когда-нибудь понадобится другое мнение о вашем коде, дайте мне знать - person CV_Res; 22.07.2016