3

I want to refresh just one fragment that in an tab bar activity when I press the back button. How can i achieve that? What I tried

java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentTransaction android.support.v4.app.FragmentManager.beginTransaction()' on a null object reference

Fragment Profile

public void refreshFragment(){
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.detach(this).attach(this).commit();
}

Edit profile activity

@Override
public void onBackPressed() {
    super.onBackPressed();
    FragmentProfile fragment = new FragmentProfile();
    fragment.refreshFragment();
}
Vikasdeep Singh
  • 20,983
  • 15
  • 78
  • 104
Lester
  • 701
  • 1
  • 9
  • 47
  • 1
    remove `super.onBackPressed();` line – Vinay Rathod Jul 05 '18 at 04:50
  • @VinayRathod not working.. – Lester Jul 05 '18 at 04:52
  • try declaring `FragmentProfile fragment = new FragmentProfile();` as global and onBackPressed just check `if(fragment!=null) fragment.refreshFragment();` – Nabil Jul 05 '18 at 04:53
  • @Override public void onBackPressed() { if(fragment!=null) fragment.refreshFragment(); } – Vinay Rathod Jul 05 '18 at 04:55
  • why would you think a newly created, not-attached fragment would have a fragment manager? You need to apply the refresh to the fragment that already exists, not to a random newly created one. – njzk2 Jul 05 '18 at 05:29
  • @Lester Your question was incomplete . This is a simple use case of `startActivityForResult();`. – ADM Jul 05 '18 at 09:53

3 Answers3

3

Although its a Conventional java.lang.NullPointerException: But I want make few things clear here for the cause of it .

1. super.onBackPressed(); will finish() the Activity so you can not make any transactions on its BackStack.

2. You want to refresh fragment then you should get the current fragment from FragmentManager to Refresh it .

FragmentProfile fragment = new FragmentProfile();

This will give you a new Fragment which is not attached yet and calling anything on it does not make any sense . This is the reason FragmentTransaction is null and getActivity() will be also null for new Fragment.

Cause getFragmentManager() by definition Returns the FragmentManager of Activity. And your new Fragment is not attached yet so it will return null.

getFragmentManager() Return the FragmentManager for interacting with fragments associated with this fragment's activity.

So your code should look like below .

 @Override
public void onBackPressed() {
    if(SomeCondition) {
        FragmentProfile fragment = //Get the Fragment from Fragment Manager Here
        fragment.refreshFragment();
    }else {
        super.onBackPressed();
    }
}

I have put a condition in onBackPressed() cause you do not want to completely disable the Back button. If you are using a Layout as container for Fragments you can get Fragment by following two methods in Activity.

getSupportFragmentManager().findFragmentById();
getSupportFragmentManager().findFragmentByTag();

EDIT:- Question wasn't clear enough . What OP want to achieve can be simply done with startActivityForResult();. Please see How to manage startActivityForResult on Android?.

ADM
  • 20,406
  • 11
  • 52
  • 83
1

You need to change to order inside onBackPressed(). Move super.onBackPressed(); at the end of function. Check below:

Current is:

@Override
public void onBackPressed() {
    super.onBackPressed();
    FragmentProfile fragment = new FragmentProfile();
    fragment.refreshFragment();
}

Change to:

@Override
public void onBackPressed() {
    FragmentProfile fragment = new FragmentProfile();
    fragment.refreshFragment();
    super.onBackPressed();
}

Also make below changes to refreshFragment() method. Get the Fragment you want to refresh by TAG.

public void refreshFragment(){
    Fragment fragment = null;
    fragment = getSupportFragmentManager().findFragmentByTag("Fragment_TAG_You_want_to_refresh");
    final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.detach(fragment).attach(fragment).commit();
}

Check here for how to add unique tag to a fragment.

Vikasdeep Singh
  • 20,983
  • 15
  • 78
  • 104
  • not working, the error message show the FragmentTransaction is null. why? – Lester Jul 05 '18 at 05:08
  • @WanJern please check my updated answer for `refreshFragment()` method. – Vikasdeep Singh Jul 05 '18 at 05:29
  • I assume you didn't read the question? the error is that the fragment manager is null, which is obvious given that the fragment it's being called from is a new Fragment, not yet attached. – njzk2 Jul 05 '18 at 05:30
  • I fail to see how that changes anything. You are not even using this `frg` Fragment you declared – njzk2 Jul 05 '18 at 05:33
  • I get this red error. Cannot resolve method 'getSupportFragmentManager()' – Lester Jul 05 '18 at 05:33
  • can't you see that the problem is in those 2 lines: `FragmentProfile fragment = new FragmentProfile(); fragment.refreshFragment();` ? – njzk2 Jul 05 '18 at 06:24
  • @njzk2 I don't find any problem here `FragmentProfile fragment = new FragmentProfile(); fragment.refreshFragment();` He is just calling `refreshFragment()` from **his** `FragmentProfile` using object of `FragmentProfile`. – Vikasdeep Singh Jul 05 '18 at 06:35
  • how do you expect to access a fragment manager from a fragment that was just created and has not been attached yet? – njzk2 Jul 05 '18 at 06:37
  • @Lester did you check my updated answer? Let me know if it is working or not. If not what error you are getting? – Vikasdeep Singh Jul 05 '18 at 06:41
  • @Lester can you please make sure that you have imported `android.support.v4.app.Fragment` & `android.support.v4.app.FragmentTransaction;` – Vikasdeep Singh Jul 05 '18 at 06:47
1

You can use SharedPreferences to do this.

Step 1: create a constants class.

public class Constants {
    public static final String REFRESH = "refresh_content";
}

Step 2: put boolean to the constants.REFRESH on Edit Profile Activity,

private SharedPreferences pref;

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    pref = PreferenceManager.getDefaultSharedPreferences(getContext());

    return inflater.inflate(R.layout.fragment_rostering, container, false);
}

public void onBackPressed() {
    SharedPreferences.Editor editor = pref.edit();
    editor.putBoolean(Constants.REFRESH, true);
    editor.commit();
    super.onBackPressed();
}

Step 3: Call refresh function on the onResume on Fragment Profile

private SharedPreferences pref;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    pref = PreferenceManager.getDefaultSharedPreferences(getContext());

    return inflater.inflate(R.layout.fragment_profile, container, false);
}

@Override
public void onResume() {
    super.onResume();
    if(pref.getBoolean(Constants.REFRESH, false)){
        SharedPreferences.Editor editor = pref.edit();
        editor.putBoolean(Constants.REFRESH, false);
        editor.commit();
        refreshFragment();
    }
}
Wan
  • 26
  • 1