简体   繁体   中英

Refresh or redraw Fragment's View

I've searched around but have been unable to find a solution to this problem. I have a Fragment that is being shown and when you press a button it opens a new Activity on top of that. Then when that Activity is finished it returns some intent data back to the Fragment/Parent Activity. That data will sometimes change a TextView or add a button to the Fragment. However, I haven't been able to get the Fragment's view to update without re-adding the Fragment to the backstack (popBackStack then replace or add).

A couple things I've tried is to call invalidate() and requestLayout() on the Fragment's base layout but the only way to refresh the view seems to have it call the onCreateView() again by removing and re-adding it. Is there a way to specify the Fragment's "content view" without reloading it?

Parent Activity code:

// Used to retrieve the data from the first Activity
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        // Try to update the Fragment's view here
        mMyFragment.refreshView(data.getString(NEW_BUTTON_TEXT));
    }
}

Fragment code (MyFragment):

private View mBaseLayout;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    mBaseLayout = inflater.inflate(R.layout.my_layout, container, false);
    ...
    return mBaseLayout;
}

public void refreshView(String newButtonText) {
    Button button = mBaseLayout.findViewById(R.id.new_button);
    button.setText(newButtonText);
    button.setVisibility(View.VISIBLE);
    // TODO Reset the Fragment's view with the update mBaseLayout view
    // ? ? ?
    // Tried mBaseLayout.invalidate() and mBaseLayout.requestLayout() here 
}

Any thoughts on this would be really helpful, thanks!

Since there doesn't appear to be a way to force the Fragment's view to be refreshed I ended up just detaching and re-attaching the fragment so the onCreateView() is called again. This seems to work just how I wanted it to. I used this solution as a starting point but needed to add commitAllowingStateLoss() to prevent a crash: https://stackoverflow.com/a/19409266/1234752 . Allowing state loss is fine here because the Fragment is just reused and the data is still contained in it.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == Activity.RESULT_OK) {
        myFragment.updateData(data.getString(NEW_BUTTON_TEXT));
        // Need to use commitAllowingStateLoss() to prevent an IllegalStateException 
        // from being thrown
        getSupportFragmentManager()
            .beginTransaction()
            .detach(mContactDetailsFragment)
            .attach(mContactDetailsFragment)
            .commitAllowingStateLoss();
    }
}
Is there a way to specify the Fragment's "content view" without reloading it?

No, That is because fragments are getting redrawn each time your activity changes, so when you open and finished an activity you fragment oncreateView will be called thus redrawing it each time.

solution:

You can make your fragment as an inner class of your activity and set a FLAG in your onActivityResult to check that it is needed to refresh.

if (resultCode == Activity.RESULT_OK) {
    isRefresh = true;
    stringData = data.getString(NEW_BUTTON_TEXT));
}

and when the onCreateView of the fragment gets called

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mBaseLayout = inflater.inflate(R.layout.my_layout, container, false);
...
if(isRefresh)
   refreshView(stringData)
return mBaseLayout;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM