0

I am using Firebase for my apps back end and I am retrieving my data as excepted. After I retrieve my data, I am posting it by using otto bus and the code can be seen below.

@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) {

    }
  });

Once the data is in my RecyclerView, I am to click an item and it's respective activity is to pop up in a custom activity dialog. However, since the activity is a dialog, you can see the RecyclerView reloading in the background. This does not happen when I do not retrieve the data from the internet. After a few clicks around, the app crashes due to an out of memory exception. Is there something I am missing?

Here is the activity where the recyclerView is found:

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

Just in case, here is also the activity that is started when a list item is clicked, it is a 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;
}

Any help is greatly appreciated thank you!

ישו אוהב אותך
  • 22,515
  • 9
  • 59
  • 80
CV_Res
  • 3
  • 5

2 Answers2

0

in public void onBrotherClicked(Brother brother) where RecyclerView resides, you call:

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

which will call

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

in newIntent of your viewPager activity.

This could be a recursive call.

try adding:

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

in Activity where your RecyclerView resides. And call your ViewPage activity there.

-- UPDATE --

Call your viewpager activity (which is used to show Brother data) with the following code:

private void showBrotherData(Brother brother){
  Intent intent = new Intent(this, BrotherPagerActivity.class);
  intent.putExtra(BROTHER_EXTRA_INFO, brother);
  this.startActivity(intent);
}
ישו אוהב אותך
  • 22,515
  • 9
  • 59
  • 80
  • so I should put the newIntent method where the recyclerview is and then call the method on the OnBrotherClicked? – CV_Res Jul 20 '16 at 05:56
  • You should put it in where your RecyclerView reside. Btw, `I forget to add context.startActivity(intent);` in newIntent, will update it. – ישו אוהב אותך Jul 20 '16 at 06:13
  • still no luck, I have a feeling it's where I put the bus.post call – CV_Res Jul 20 '16 at 06:27
  • It looks like your right, try to commenting code which not used for Event busing to make sure your `post` work correctly. And in **onBrosLoaded** you use a slightly wrong code, read more http://stackoverflow.com/a/30057015/4758255 – ישו אוהב אותך Jul 20 '16 at 06:32
  • I reason the recyclerView is reloading is because I am calling notifydataSetChanged in the recyclerView. However, when I take this code off in the live service, the app crashes. Any ideas? – CV_Res Jul 21 '16 at 02:43
0

I found the answer! I changed my recyclerView to only updated if the size of the array was zero.

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

I don't know how good this solution is in terms of cleaness but it works for me. I hope this helps someone.

CV_Res
  • 3
  • 5