How do I change the view inside a fragment?

You can use Fragment.getView(). This returns the view of the container which contains the Fragment. On that view, you can call removeAllViews. Then build your new views and add them to the view you got from getView().

http://developer.android.com/reference/android/app/Fragment.html#getView()


If for any reason, you want to change the whole fragment view (for example, asynchronous URL request that will change the view on success), you can either use the FragmentTransaction in the parent activity and create a new fragment on the fly.

Or you can keep the fragment and call a method of this fragment that will refresh itself. Example: In the parent activity, I build and store a list of fragments List<RefreshFragment> mFragmentList.

Here is the RefreshFragment class (and all my fragments extend this one in my example) :

public class RefreshFragment extends Fragment {
    protected Data data; // here your asynchronously loaded data

    public void setData(Data data) {
        this.data = data;
        // The reload fragment code here !
        if (! this.isDetached()) {
            getFragmentManager().beginTransaction()
               .detach(this)
               .attach(this)
               .commit();
        }
    }
}

Then in my activity asynchronous callback I can call :

for (RefreshFragment f : mFragmentList) f.setData(data);

So every fragment will be updated with the correct data and the currently attached fragment will update itself immediately. You have to provide you own onCreateView in the fragments of course.

The important thing is that a fragment can reload itself with getFragmentManager().

Nowdays, I would suggest using ViewModel for that purpose.


You could use a FrameLayout to switch between your progress bar and data view, e.g.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ImageView android:id="@+id/cover_image"
        android:scaleType="fitCenter"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
    <ProgressBar android:id="@+id/cover_progress"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:layout_gravity="center"/>
</FrameLayout>

In onViewCreate() you would then store both views into instance fields

public View onCreateView(LayoutInflater inflater,
        ViewGroup container, Bundle savedInstanceState) {
    ...
    image = (ImageView) container.findViewById(R.id.cover_image);
    progress = container.findViewById(R.id.cover_progress);
    ...
}

and whenever you want to switch between the two (remember to do this in your UI/main thread), just do something like

progress.setVisibility(View.INVISIBLE);
image.setVisibility(View.VISIBLE);

Create a "dummy" default view

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

</LinearLayout>

Inflate the "dummy" default view in the fragment's onCreateView method and use it as a placeholder to add views as needed

private LayoutInflater mInflater;
private ViewGroup mContainer;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
    mInflater = inflater;
    mContainer = container;

    View v =inflater.inflate(R.layout.home_view,container,false);
    placeholder = (ViewGroup) v;

    return placeholder;
}

To change the view to a new view you first remove all previous views then you inflate the new view and add

View newView = mInflater.inflate(R.layout.custom_dash, mContainer, false);
placeholder.removeAllViews();
placeholder.addView(newView);