mario595
mario595

Reputation: 3761

Fragment view not refreshing

I've got the following fragment class:

/**
 * A fragment representing a single Walk detail screen.
 * This fragment is either contained in a {@link WalkListActivity}
 * in two-pane mode (on tablets) or a {@link WalkDetailActivity}
 * on handsets.
 */
public class WalkDetailFragment extends Fragment {
    /**
     * The fragment argument representing the item ID that this fragment
     * represents.
     */
    public static final String ARG_ITEM_ID = "item_id";

    private static final String LOG_PREFIX = "WalkDetailFragment";

    private WalkDetails walkDetails;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public WalkDetailFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments().containsKey(ARG_ITEM_ID)) {
            long id = getArguments().getLong(ARG_ITEM_ID);
            GsonRequest<WalkDetails> request =
            new GsonRequest<WalkDetails>(getResources().getString(R.string.walk_details_url, id),
                    WalkDetails.class, null, new Response.Listener<WalkDetails>() {
                @Override
                public void onResponse(WalkDetails response) {
                    Log.d(LOG_PREFIX, "Received walk details with id " + response.getId());
                    walkDetails = response;


                    Fragment currentFragment = getFragmentManager().findFragmentByTag("FRAGMENT_TAG");
                    FragmentTransaction fragTransaction = getFragmentManager().beginTransaction();
                    fragTransaction.detach(currentFragment);
                    fragTransaction.attach(currentFragment);
                    fragTransaction.commit();
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    //TODO implement me!!
                    Log.e(LOG_PREFIX, error.getMessage());
                }
            });
            RequestQueue queue = Volley.newRequestQueue(getActivity());
            queue.add(request);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_walk_detail, container, false);


        if (walkDetails != null) {
            ((TextView) rootView.findViewById(R.id.walk_detail_walk_name)).setText(walkDetails.getName());
            ((TextView) rootView.findViewById(R.id.walk_detail_walk_difficulty)).setText(String.valueOf(walkDetails.getDifficulty()));
            ((TextView) rootView.findViewById(R.id.walk_detail_walk_length)).setText(String.valueOf(walkDetails.getLength()));
            ((TextView) rootView.findViewById(R.id.walk_detail_walk_region)).setText(walkDetails.getRegion());
            ((TextView) rootView.findViewById(R.id.walk_detail_walk_travel_info)).setText(walkDetails.getTravelInformation());
        }

        return rootView;
    }
}

fragment_walk_detail.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/walk_detail_walk_name"
        style="?android:attr/textAppearanceLarge"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@string/walk_detail_walk_name_placeholder"
        android:textIsSelectable="true"
        tools:context=".WalkDetailFragment" />

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/walk_detail_walk_difficulty"
        style="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@string/walk_detail_walk_difficulty_placeholder"
        android:textIsSelectable="true"
        tools:context=".WalkDetailFragment" />

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/walk_detail_walk_region"
        style="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@string/walk_detail_walk_region_placeholder"
        android:textIsSelectable="true"
        tools:context=".WalkDetailFragment" />

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/walk_detail_walk_length"
        style="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@string/walk_detail_walk_length_placeholder"
        android:textIsSelectable="true"
        tools:context=".WalkDetailFragment" />

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/walk_detail_walk_travel_info"
        style="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@string/walk_detail_walk_travel_info_placeholder"
        android:textIsSelectable="true"
        tools:context=".WalkDetailFragment" />
</LinearLayout>

As you can see, in the onCreate I am making an async call for some Json. When I first come to the fragment view, as the async call has not being made yet, I see the default layout for the fragment, with no data in (see how in the onCreateView if walkDetails is null, I am doing nothing).

When the call returns and executes the onResponse, I am refreshing the fragment by detach and re-attach it. This is apparently working fine, and the onCreateView is being executed again.

This time, walkDetails is no longer null, and has values for all its fields, so it comes into the if clause and sets the textViews. This works fine, the textViews exist and there is no exception raised.

But for some reason, I am keep seeing the default layout, without the values I've set for the textViews.

Anyone knows why the layout is not being refreshed? Thanks!

Upvotes: 0

Views: 95

Answers (1)

hrskrs
hrskrs

Reputation: 4490

No need to attach/detach current fragment for refreshing data. You can simply set the data onResponse():

public class WalkDetailFragment extends Fragment {

    public static final String ARG_ITEM_ID = "item_id";

    private static final String LOG_PREFIX = "WalkDetailFragment";

    private WalkDetails walkDetails;

    private TextView name;
    private TextView difficulty;
    private TextView length;
    private TextView region;
    private TextView info;


    public WalkDetailFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments().containsKey(ARG_ITEM_ID)) {
            long id = getArguments().getLong(ARG_ITEM_ID);
            GsonRequest<WalkDetails> request =
                    new GsonRequest<WalkDetails>(getResources().getString(R.string.walk_details_url, id),
                            WalkDetails.class, null, new Response.Listener<WalkDetails>() {
                        @Override
                        public void onResponse(WalkDetails response) {
                            Log.d(LOG_PREFIX, "Received walk details with id " + response.getId());
                            walkDetails = response;

                            setData(walkDetails);
                        }
                    },
                            new Response.ErrorListener() {
                                @Override
                                public void onErrorResponse(VolleyError error) {
                                    //TODO implement me!!
                                    Log.e(LOG_PREFIX, error.getMessage());
                                }
                            });
            RequestQueue queue = Volley.newRequestQueue(getActivity());
            queue.add(request);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_walk_detail, container, false);

        name = ((TextView) rootView.findViewById(R.id.walk_detail_walk_name));
        difficulty = ((TextView) rootView.findViewById(R.id.walk_detail_walk_difficulty));
        length = ((TextView) rootView.findViewById(R.id.walk_detail_walk_length));
        region = ((TextView) rootView.findViewById(R.id.walk_detail_walk_region));
        info = ((TextView) rootView.findViewById(R.id.walk_detail_walk_travel_info));

        return rootView;
    }

    private void setData(WalkDetails walkDetails) {
        if (walkDetails != null) {
            name.setText(walkDetails.getName());
            difficulty.setText(String.valueOf(walkDetails.getDifficulty()));
            length.setText(String.valueOf(walkDetails.getLength()));
            region.setText(walkDetails.getRegion());
            info.setText(walkDetails.getTravelInformation());
        }
    }
}

Upvotes: 1

Related Questions