aurochs
aurochs

Reputation: 13

Refresh fragments after coming back from an activity

I'm working on an activity which uses a TabLayout to house two fragments. Each of the fragments uses RecyclerView. The activity also has an options menu. When any of the options is clicked, a new activity will start. One of the new activities has a "Save" button which when clicked will update the first activity's data set and return to the first activity. However, the first activity's fragments don't show the changed data set even though the data set itself changes.

RecordAddActivity.java (First Activity)

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FileUtils.initDataDir(this);
    MySQLiteHelper db = new MySQLiteHelper(this);
    Bundle bundle = getIntent().getExtras();
    siteID = bundle.getLong(Constants.INTENT_EXTRA_SITE_ID);
    site = db.getSiteByID(siteID);
    trapFileName = site.getId() + "_" + site.getName() + ".csv";
    inputString = site.getName();

    setContentView(R.layout.activity_add_record_new);
    viewPager = (ViewPager) findViewById(R.id.view_pager);
    adapter = new PagerAdapter(getSupportFragmentManager());

    insectsAddRecordFragment = new InsectsAddRecordFragment();
    naturalPestsAddRecordFragment = new NaturalPestsAddRecordFragment();

    if (!doesRecordExist) {
        insectsAddRecordFragment.setInsects(site.getInsectsNames());
        naturalPestsAddRecordFragment.setNaturalPests(site.getNaturalPestsNames());
    } else {
        IsDefaultInsectTypes isDefaultInsectTypes = new IsDefaultInsectTypes(trapFileName);
        insectsAddRecordFragment.setInsects(isDefaultInsectTypes.getInsectNamesList());
        naturalPestsAddRecordFragment.setNaturalPests(isDefaultInsectTypes.getPestNamesList());
        site.setInsects(isDefaultInsectTypes.getInsectNamesList());
        site.setNaturalPests(isDefaultInsectTypes.getPestNamesList());
    }

    adapter.addFragment(insectsAddRecordFragment, "Serangga Perosak");
    adapter.addFragment(naturalPestsAddRecordFragment, "Musuh Semulajadi");
    viewPager.setAdapter(adapter);

    final TabLayout tabLayout = (TabLayout) findViewById(R.id.tablayoutbar);
    tabLayout.setTabTextColors(Color.BLACK, Color.WHITE);
    tabLayout.setupWithViewPager(viewPager);
    tabLayout.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager) {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            super.onTabSelected(tab);
            tabLayout.requestFocus();
            hideKeyboard(viewPager);
        }
    });
} 

//The options menu which start the new activity

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_edit_insects_type){
        final int EDIT_INSECT_TYPE_REQUEST = 1;
        Intent intent = new Intent(RecordAddActivity.this, EditInsectsTypeActivity.class);
        intent.putExtra(Constants.INTENT_EXTRA_REPORT_TRAP_FILE, trapFileName);
        intent.putExtra(Constants.INTENT_EXTRA_SITE_OBJECT, site);
        startActivityForResult(intent, EDIT_INSECT_TYPE_REQUEST);
        return true;
    }
}

//The FragmentPagerAdapter

 public class PagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> mFragmentList = new ArrayList<>();

    private List<String> mFragmentTitleNames = new ArrayList<>();

    public PagerAdapter(FragmentManager fm) {
        super(fm);
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleNames.add(title);
    }

    public void swapItems(Fragment insectFragment, Fragment naturalPestFragment) {
        mFragmentList.clear();
        mFragmentList.add(insectFragment);
        mFragmentList.add(naturalPestFragment);
        Log.d(TAG, "Items swapped");
        notifyDataSetChanged();
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleNames.get(position);
    }

}

What I've tried:

  1. Using onResume()

    @Override
    public void onResume() {
    Log.d(TAG, "onResume");
    super.onResume();  // Always call the superclass method first
    doesRecordExist = FileUtils.doesRecordExists(trapFileName);
    if (doesRecordExist) {
        IsDefaultInsectTypes isDefaultInsectTypes = new IsDefaultInsectTypes(trapFileName);
        insectsAddRecordFragment = new InsectsAddRecordFragment();
        naturalPestsAddRecordFragment = new NaturalPestsAddRecordFragment();
    
        //The log shows that the data set has changed
        Log.d(TAG, "Nama serangga:" + isDefaultInsectTypes.getInsectNamesList());
    
    
        //Trying to update the fragments
        insectsAddRecordFragment.setInsects(isDefaultInsectTypes.getInsectNamesList());
        naturalPestsAddRecordFragment.setNaturalPests(isDefaultInsectTypes.getPestNamesList());
        adapter.swapItems(insectsAddRecordFragment, naturalPestsAddRecordFragment); 
        }
    }
    
  2. Using a Global variable to update the fragment

EditInsectsTypeActivity.java (The new activity)

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_save) {
        Globals2 allowRefresh = Globals2.getInstance();
        ArrayList<String> insectsNameList = insectsViewFragment.getInsectsNameList();
        ArrayList<String> pestsNameList = naturalPestsViewFragment.getInsectsNameList();
        FileUtils.updateSiteInsects(this, trapFileName, insectsNameList, pestsNameList);
        allowRefresh.setData(true);
        Log.d(TAG, "allowRefresh: " + allowRefresh.getData());
        finish();
        Utils.showToast(getBaseContext(), "Rekod disimpan");

    }
    return true;
}

InsectsAddRecordFragment.java (The fragment to be refreshed/updated)

@Override
public void onResume() {
    Log.d(TAG, "onResume");
    super.onResume();  // Always call the superclass method first
    Globals2 allowRefresh = Globals2.getInstance();
    IsDefaultInsectTypes isDefaultInsectTypes = new IsDefaultInsectTypes("27_Cgtv.csv");
    Log.d(TAG, "Nama serangga:" + isDefaultInsectTypes.getInsectNamesList());
    setInsects(isDefaultInsectTypes.getInsectNamesList());
    Log.d(TAG, "allowRefresh: " + allowRefresh.getData());
    if (allowRefresh.getData()) {
        allowRefresh.setData(false);
        getFragmentManager().beginTransaction().detach(this).attach(this).commit();

    }
}

I've spent hours trying to fix this without any luck. Any help will be much appreciated.

Upvotes: 0

Views: 1915

Answers (2)

Abbas
Abbas

Reputation: 3331

So here's what you need to do, in your Activity's onPause() method update the list in your InsectsAddRecordFragment like so:

public void onPause()
{
    ...                      // your logic for data-set changed.
    if (doesRecordExist)
        insectsAddRecordFragment.setInsects(isDefaultInsectTypes.get‌​InsectNamesList());
    ...
}

And within setInsects of InsectsAddRecordFragment something similar to this.

public void setInsects() {

    // Here adapter is the Adapter for the RecyclerView

    adapter.setAdapterList(isDefaultInsectTypes.get‌​InsectNamesList());
    // notifyDataSetChanged() is important here because without this the Adapter has no idea
    // that data has changed.
    adapter.notifyDataSetChanged();
}

While in your RecyclerViewAdapter for InsectsAddRecordFragment's RecyclerView items. Do the following.

// ArrayList<String> list is just an example you may have some different data set.
public void setAdapterList(ArrayList<String> list) {

    this.adapterList = list;
}

Using this approach there is no need recreate the fragment, instead you can just update the dataset within the Adapter.

I'd also suggest reading some blogs and how-to's on Fragments, RecyclerView and RecyclerView.Adapter before you work any further.

Upvotes: 1

Chris Ward
Chris Ward

Reputation: 101

Override:

protected void onActivityResult(int requestCode, int resultCode, Intent data)

In the first Activity.

[EDIT] More info on startActivityForResult() here: https://developer.android.com/training/basics/intents/result.html

Upvotes: 0

Related Questions