Java tutorial
/* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.kai.uGuide.ui.fragment; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; import android.transition.AutoTransition; import android.transition.Scene; import android.transition.Transition; import android.transition.TransitionManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.FrameLayout; import android.widget.GridView; import android.widget.ListView; import com.kai.uGuide.R; import com.kai.uGuide.ui.adapter.Home; import com.kai.uGuide.ui.adapter.ListItem; import com.kai.uGuide.ui.adapter.MeatAdapter; /** * Main screen for AdapterTransition sample. */ public class AdapterTransitionFragment extends Fragment implements Transition.TransitionListener { /** * Since the transition framework requires all relevant views in a view hierarchy to be marked * with IDs, we use this ID to mark the root view. */ private static final int ROOT_ID = 1; private static final String ARG_POSITION = "position"; /** * A tag for saving state whether the mAbsListView is ListView or GridView. */ private static final String STATE_IS_LISTVIEW = "is_listview"; /** * This is where we place our AdapterView (ListView / GridView). */ private FrameLayout mContent; /** * This is where we carry out the transition. */ private FrameLayout mCover; /** * This list shows our contents. It can be ListView or GridView, and we toggle between them * using the transition framework. */ private AbsListView mAbsListView; /** * This is our contents. */ private MeatAdapter mAdapter; private ListItem[] data; public static AdapterTransitionFragment newInstance(int position) { AdapterTransitionFragment fragment = new AdapterTransitionFragment(); Bundle b = new Bundle(); b.putInt(ARG_POSITION, position); fragment.setArguments(b); return fragment; } public AdapterTransitionFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); data = getData(getArguments().getInt(ARG_POSITION)); } protected ListItem[] getData(int position) { switch (position) { case 0: return Home.Attractions; case 1: return Home.Tours; case 2: return Home.Foods; case 3: return Home.Hotels; case 4: return Home.Events; } return Home.Attractions; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // If savedInstanceState is available, we restore the state whether the list is a ListView // or a GridView. boolean isListView; if (null == savedInstanceState) { isListView = true; } else { isListView = savedInstanceState.getBoolean(STATE_IS_LISTVIEW, true); } inflateAbsList(inflater, container, isListView); return inflater.inflate(R.layout.fragment_adapter_transition, container, false); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(STATE_IS_LISTVIEW, mAbsListView instanceof ListView); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { // Retaining references for FrameLayouts that we use later. mContent = (FrameLayout) view.findViewById(R.id.content); mCover = (FrameLayout) view.findViewById(R.id.cover); // We are attaching the list to the screen here. mContent.addView(mAbsListView); } @Override public void onTransitionStart(Transition transition) { } // BEGIN_INCLUDE(on_transition_end) @Override public void onTransitionEnd(Transition transition) { // When the transition ends, we remove all the views from the overlay and hide it. mCover.removeAllViews(); mCover.setVisibility(View.INVISIBLE); } // END_INCLUDE(on_transition_end) @Override public void onTransitionCancel(Transition transition) { } @Override public void onTransitionPause(Transition transition) { } @Override public void onTransitionResume(Transition transition) { } /** * Inflate a ListView or a GridView with a corresponding ListAdapter. * * @param inflater The LayoutInflater. * @param container The ViewGroup that contains this AbsListView. The AbsListView won't be * attached to it. * @param inflateListView Pass true to inflate a ListView, or false to inflate a GridView. */ private void inflateAbsList(LayoutInflater inflater, ViewGroup container, boolean inflateListView) { if (inflateListView) { mAbsListView = (AbsListView) inflater.inflate(R.layout.fragment_meat_list, container, false); mAdapter = new MeatAdapter(data, inflater, R.layout.item_meat_list); } else { mAbsListView = (AbsListView) inflater.inflate(R.layout.fragment_meat_grid, container, false); mAdapter = new MeatAdapter(data, inflater, R.layout.item_meat_grid); } mAbsListView.setAdapter(mAdapter); mAbsListView.setOnItemClickListener(mAdapter); } /** * Toggle the UI between ListView and GridView. */ public void toggle() { // We use mCover as the overlay on which we carry out the transition. mCover.setVisibility(View.VISIBLE); // This FrameLayout holds all the visible views in the current list or grid. We use this as // the starting Scene of the Transition later. FrameLayout before = copyVisibleViews(); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT); mCover.addView(before, params); // Swap the actual list. swapAbsListView(); // We also swap the icon for the toggle button. ActivityCompat.invalidateOptionsMenu(getActivity()); // It is now ready to start the transition. mAbsListView.post(new Runnable() { @Override public void run() { // BEGIN_INCLUDE(transition_with_listener) Scene scene = new Scene(mCover, copyVisibleViews()); Transition transition = new AutoTransition(); transition.addListener(AdapterTransitionFragment.this); TransitionManager.go(scene, transition); // END_INCLUDE(transition_with_listener) } }); } /** * Swap ListView with GridView, or GridView with ListView. */ private void swapAbsListView() { // We save the current scrolling position before removing the current list. int first = mAbsListView.getFirstVisiblePosition(); // If the current list is a GridView, we replace it with a ListView. If it is a ListView, // a GridView. LayoutInflater inflater = LayoutInflater.from(getActivity()); inflateAbsList(inflater, (ViewGroup) mAbsListView.getParent(), mAbsListView instanceof GridView); mAbsListView.setAdapter(mAdapter); // We restore the scrolling position here. mAbsListView.setSelection(first); // The new list is ready, and we replace the existing one with it. mContent.removeAllViews(); mContent.addView(mAbsListView); } /** * Copy all the visible views in the mAbsListView into a new FrameLayout and return it. * * @return a FrameLayout with all the visible views inside. */ private FrameLayout copyVisibleViews() { // This is the FrameLayout we return afterwards. FrameLayout layout = new FrameLayout(getActivity()); // The transition framework requires to set ID for all views to be animated. layout.setId(ROOT_ID); // We only copy visible views. int first = mAbsListView.getFirstVisiblePosition(); int index = 0; while (true) { // This is one of the views that we copy. Note that the argument for getChildAt is a // zero-oriented index, and it doesn't usually match with its position in the list. View source = mAbsListView.getChildAt(index); if (null == source) { break; } // This is the copy of the original view. View destination = mAdapter.getView(first + index, null, layout); assert destination != null; destination.setId(ROOT_ID + first + index); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(source.getWidth(), source.getHeight()); params.leftMargin = (int) source.getX(); params.topMargin = (int) source.getY(); layout.addView(destination, params); ++index; } return layout; } }