diff options
Diffstat (limited to 'samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java')
-rw-r--r-- | samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java b/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java new file mode 100644 index 000000000..525ed4035 --- /dev/null +++ b/samples/browseable/AdapterTransition/src/com.example.android.adaptertransition/AdapterTransitionFragment.java @@ -0,0 +1,244 @@ +/* + * 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.example.android.adaptertransition; + +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.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.FrameLayout; +import android.widget.GridView; +import android.widget.ListView; + +/** + * 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; + + /** + * 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; + + public static AdapterTransitionFragment newInstance() { + return new AdapterTransitionFragment(); + } + + public AdapterTransitionFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // We use a ListView at first + mAbsListView = (AbsListView) inflater.inflate(R.layout.fragment_meat_list, container, false); + mAdapter = new MeatAdapter(inflater, R.layout.item_meat_list); + return inflater.inflate(R.layout.fragment_adapter_transition, container, false); + } + + @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. + mAbsListView.setAdapter(mAdapter); + mContent.addView(mAbsListView); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.fragment_adapter_transition, menu); + } + + @Override + public void onPrepareOptionsMenu(Menu menu) { + // We change the look of the icon every time the user toggles between list and grid. + MenuItem item = menu.findItem(R.id.action_toggle); + if (null != item) { + if (mAbsListView instanceof ListView) { + item.setIcon(R.drawable.ic_action_grid); + } else { + item.setIcon(R.drawable.ic_action_list); + } + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_toggle: { + toggle(); + return true; + } + } + return false; + } + + @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) { + } + + /** + * Toggle the UI between ListView and GridView. + */ + private 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()); + if (mAbsListView instanceof GridView) { + mAbsListView = (AbsListView) inflater.inflate( + R.layout.fragment_meat_list, (ViewGroup) mAbsListView.getParent(), false); + mAdapter = new MeatAdapter(inflater, R.layout.item_meat_list); + } else { + mAbsListView = (AbsListView) inflater.inflate( + R.layout.fragment_meat_grid, (ViewGroup) mAbsListView.getParent(), false); + mAdapter = new MeatAdapter(inflater, R.layout.item_meat_grid); + } + 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; + } + +} |