片段视图不令人耳目一新

时间:2016-01-22 08:15:41

标签: android android-fragments

我有以下片段类:

/**
 * 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>

正如你所看到的,在onCreate我正在为一些Json做异步调用。当我第一次进入片段视图时,由于尚未进行异步调用,我看到片段的默认布局,没有数据(请参阅onCreateView如果walkDetails为空,我什么也没做。)

当调用返回并执行onResponse时,我通过分离并重新附加它来刷新片段。这显然工作正常,onCreateView正在重新执行。

这一次,walkDetails不再为null,并且具有其所有字段的值,因此它进入if子句并设置textViews。这很好用,textViews存在,没有异常引发。

但出于某种原因,我一直看到默认布局,没有我为textViews设置的值。

任何人都知道为什么布局没有刷新? 谢谢!

1 个答案:

答案 0 :(得分:1)

无需attach/detach当前fragment来刷新数据。您只需设置数据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());
        }
    }
}