Home | History | Annotate | Download | only in leanback
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
      5  * in compliance with the License. You may obtain a copy of the License at
      6  *
      7  * http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software distributed under the License
     10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
     11  * or implied. See the License for the specific language governing permissions and limitations under
     12  * the License.
     13  */
     14 package com.example.android.leanback;
     15 
     16 import android.app.Fragment;
     17 import android.content.Intent;
     18 import android.os.Bundle;
     19 import android.os.Handler;
     20 import android.support.v17.leanback.app.GuidedStepFragment;
     21 import android.support.v17.leanback.app.RowsFragment;
     22 import android.support.v17.leanback.widget.ArrayObjectAdapter;
     23 import android.support.v17.leanback.widget.DividerRow;
     24 import android.support.v17.leanback.widget.HeaderItem;
     25 import android.support.v17.leanback.widget.ImageCardView;
     26 import android.support.v17.leanback.widget.ListRow;
     27 import android.support.v17.leanback.widget.ListRowPresenter;
     28 import android.support.v17.leanback.widget.OnItemViewClickedListener;
     29 import android.support.v17.leanback.widget.OnItemViewSelectedListener;
     30 import android.support.v17.leanback.widget.PageRow;
     31 import android.support.v17.leanback.widget.Presenter;
     32 import android.support.v17.leanback.widget.Row;
     33 import android.support.v17.leanback.widget.RowPresenter;
     34 import android.support.v17.leanback.widget.SectionRow;
     35 import android.support.v4.app.ActivityOptionsCompat;
     36 import android.util.Log;
     37 import android.view.LayoutInflater;
     38 import android.view.View;
     39 import android.view.ViewGroup;
     40 
     41 public class BrowseFragment extends android.support.v17.leanback.app.BrowseFragment {
     42     private static final String TAG = "leanback.BrowseFragment";
     43 
     44     private static final boolean TEST_ENTRANCE_TRANSITION = true;
     45     private static final int NUM_ROWS = 8;
     46     private static final long HEADER_ID1 = 1001;
     47     private static final long HEADER_ID2 = 1002;
     48     private static final long HEADER_ID3 = 1003;
     49 
     50     private ArrayObjectAdapter mRowsAdapter;
     51     private BackgroundHelper mBackgroundHelper = new BackgroundHelper();
     52 
     53     // For good performance, it's important to use a single instance of
     54     // a card presenter for all rows using that presenter.
     55     final CardPresenter mCardPresenter = new CardPresenter();
     56     final CardPresenter mCardPresenter2 = new CardPresenter(R.style.MyImageCardViewTheme);
     57 
     58     public BrowseFragment() {
     59         getMainFragmentRegistry().registerFragment(PageRow.class, new PageRowFragmentFactory());
     60     }
     61 
     62     @Override
     63     public void onCreate(Bundle savedInstanceState) {
     64         Log.i(TAG, "onCreate");
     65         super.onCreate(savedInstanceState);
     66 
     67         setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ic_title));
     68         setTitle("Leanback Sample App");
     69         setHeadersState(HEADERS_ENABLED);
     70         setOnSearchClickedListener(new View.OnClickListener() {
     71             @Override
     72             public void onClick(View view) {
     73                 Intent intent = new Intent(getActivity(), SearchActivity.class);
     74                 startActivity(intent);
     75             }
     76         });
     77 
     78         setOnItemViewClickedListener(new ItemViewClickedListener());
     79         setOnItemViewSelectedListener(new OnItemViewSelectedListener() {
     80             @Override
     81             public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
     82                     RowPresenter.ViewHolder rowViewHolder, Row row) {
     83                 Log.i(TAG, "onItemSelected: " + item + " row " + row);
     84 
     85                 if (isShowingHeaders()) {
     86                     mBackgroundHelper.setBackground(getActivity(), null);
     87                 } else if (item instanceof PhotoItem) {
     88                     mBackgroundHelper.setBackground(
     89                             getActivity(), ((PhotoItem) item).getImageResourceId());
     90                 }
     91             }
     92         });
     93         if (TEST_ENTRANCE_TRANSITION) {
     94             // don't run entrance transition if fragment is restored.
     95             if (savedInstanceState == null) {
     96                 prepareEntranceTransition();
     97             }
     98         }
     99 
    100         // simulates in a real world use case  data being loaded two seconds later
    101         new Handler().postDelayed(new Runnable() {
    102             public void run() {
    103                 setupRows();
    104                 loadData();
    105                 startEntranceTransition();
    106             }
    107         }, 2000);
    108     }
    109 
    110     @Override
    111     public View onCreateView(
    112             LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    113         return super.onCreateView(inflater, container, savedInstanceState);
    114     }
    115 
    116     private void setupRows() {
    117         ListRowPresenter listRowPresenter = new ListRowPresenter();
    118         listRowPresenter.setNumRows(2);
    119         mRowsAdapter = new ArrayObjectAdapter(listRowPresenter);
    120         setAdapter(mRowsAdapter);
    121     }
    122 
    123     private void loadData() {
    124         int i = 0;
    125 
    126         mRowsAdapter.add(new PageRow(new HeaderItem(HEADER_ID1, "Page Row 0")));
    127         mRowsAdapter.add(new DividerRow());
    128 
    129         mRowsAdapter.add(new SectionRow(new HeaderItem("section 0")));
    130         for (; i < NUM_ROWS; ++i) {
    131             mRowsAdapter.add(new ListRow(new HeaderItem(i, "Row " + i), createListRowAdapter(i)));
    132         }
    133 
    134         mRowsAdapter.add(new DividerRow());
    135         mRowsAdapter.add(new PageRow(new HeaderItem(HEADER_ID2, "Page Row 1")));
    136 
    137         mRowsAdapter.add(new PageRow(new HeaderItem(HEADER_ID3, "Page Row 2")));
    138     }
    139 
    140     private ArrayObjectAdapter createListRowAdapter(int i) {
    141         ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter((i & 1) == 0 ?
    142                 mCardPresenter : mCardPresenter2);
    143         listRowAdapter.add(new PhotoItem(
    144                 "Hello world",
    145                 R.drawable.gallery_photo_1));
    146         listRowAdapter.add(new PhotoItem(
    147                 "This is a test",
    148                 "Only a test",
    149                 R.drawable.gallery_photo_2));
    150         listRowAdapter.add(new PhotoItem(
    151                 "Android TV",
    152                 "by Google",
    153                 R.drawable.gallery_photo_3));
    154         listRowAdapter.add(new PhotoItem(
    155                 "Leanback",
    156                 R.drawable.gallery_photo_4));
    157         listRowAdapter.add(new PhotoItem(
    158                 "GuidedStep (Slide left/right)",
    159                 R.drawable.gallery_photo_5));
    160         listRowAdapter.add(new PhotoItem(
    161                 "GuidedStep (Slide bottom up)",
    162                 "Open GuidedStepFragment",
    163                 R.drawable.gallery_photo_6));
    164         listRowAdapter.add(new PhotoItem(
    165                 "Android TV",
    166                 "open RowsActivity",
    167                 R.drawable.gallery_photo_7));
    168         listRowAdapter.add(new PhotoItem(
    169                 "Leanback",
    170                 "open BrowseActivity",
    171                 R.drawable.gallery_photo_8));
    172         listRowAdapter.add(new PhotoItem(
    173                 "Hello world",
    174                 R.drawable.gallery_photo_1));
    175         listRowAdapter.add(new PhotoItem(
    176                 "This is a test",
    177                 "Only a test",
    178                 R.drawable.gallery_photo_2));
    179         listRowAdapter.add(new PhotoItem(
    180                 "Android TV",
    181                 "by Google",
    182                 R.drawable.gallery_photo_3));
    183         listRowAdapter.add(new PhotoItem(
    184                 "Leanback",
    185                 R.drawable.gallery_photo_4));
    186         return listRowAdapter;
    187     }
    188 
    189     private final class ItemViewClickedListener implements OnItemViewClickedListener {
    190         @Override
    191         public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
    192                 RowPresenter.ViewHolder rowViewHolder, Row row) {
    193 
    194             Intent intent;
    195             Bundle bundle;
    196             if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_6) {
    197                 GuidedStepFragment.add(getFragmentManager(),
    198                         new GuidedStepHalfScreenActivity.FirstStepFragment(),
    199                         R.id.lb_guidedstep_host);
    200                 return;
    201             } else if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_5) {
    202                 GuidedStepFragment.add(getFragmentManager(),
    203                         new GuidedStepActivity.FirstStepFragment(), R.id.lb_guidedstep_host);
    204                 return;
    205             } else if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_8) {
    206                 intent = new Intent(getActivity(), BrowseActivity.class);
    207                 bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
    208                         .toBundle();
    209             } else if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_7) {
    210                 intent = new Intent(getActivity(), RowsActivity.class);
    211                 bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
    212                         .toBundle();
    213             } else {
    214                 intent = new Intent(getActivity(), DetailsActivity.class);
    215                 intent.putExtra(DetailsActivity.EXTRA_ITEM, (PhotoItem) item);
    216                 bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
    217                         getActivity(),
    218                         ((ImageCardView) itemViewHolder.view).getMainImageView(),
    219                         DetailsActivity.SHARED_ELEMENT_NAME).toBundle();
    220             }
    221             getActivity().startActivity(intent, bundle);
    222         }
    223     }
    224 
    225     public static class PageRowFragmentFactory extends FragmentFactory {
    226 
    227         @Override
    228         public Fragment createFragment(Object rowObj) {
    229             Row row = (Row) rowObj;
    230             if (row.getHeaderItem().getId() == HEADER_ID1) {
    231                 return new SampleRowsFragment();
    232             } else if (row.getHeaderItem().getId() == HEADER_ID2) {
    233                 return new SampleRowsFragment();
    234             } else if (row.getHeaderItem().getId() == HEADER_ID3) {
    235                 return new SampleFragment();
    236             }
    237 
    238             return null;
    239         }
    240     }
    241 
    242     public static class SampleRowsFragment extends RowsFragment {
    243         final CardPresenter mCardPresenter = new CardPresenter();
    244         final CardPresenter mCardPresenter2 = new CardPresenter(R.style.MyImageCardViewTheme);
    245 
    246         void loadFragmentData() {
    247             ArrayObjectAdapter adapter = (ArrayObjectAdapter) getAdapter();
    248             for (int i = 0; i < 4; i++) {
    249                 ListRow row = new ListRow(new HeaderItem("Row " + i), createListRowAdapter(i));
    250                 adapter.add(row);
    251             }
    252             if (getMainFragmentAdapter() != null) {
    253                 getMainFragmentAdapter().getFragmentHost()
    254                         .notifyDataReady(getMainFragmentAdapter());
    255             }
    256         }
    257 
    258         public SampleRowsFragment() {
    259             ArrayObjectAdapter adapter = new ArrayObjectAdapter(new ListRowPresenter());
    260             setAdapter(adapter);
    261             // simulates late data loading:
    262             new Handler().postDelayed(new Runnable() {
    263                 public void run() {
    264                     loadFragmentData();
    265                 }
    266             }, 500);
    267 
    268             setOnItemViewClickedListener(new OnItemViewClickedListener() {
    269                 @Override
    270                 public void onItemClicked(
    271                         Presenter.ViewHolder itemViewHolder,
    272                         Object item,
    273                         RowPresenter.ViewHolder rowViewHolder,
    274                         Row row) {
    275                     Intent intent;
    276                     Bundle bundle;
    277                     if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_6) {
    278                         GuidedStepFragment.add(getActivity().getFragmentManager(),
    279                                 new GuidedStepHalfScreenActivity.FirstStepFragment(),
    280                                 R.id.lb_guidedstep_host);
    281                         return;
    282                     } else if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_5) {
    283                         GuidedStepFragment.add(getActivity().getFragmentManager(),
    284                                 new GuidedStepActivity.FirstStepFragment(), R.id.lb_guidedstep_host);
    285                         return;
    286                     } else if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_8) {
    287                         intent = new Intent(getActivity(), BrowseActivity.class);
    288                         bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
    289                                 .toBundle();
    290                     } else if (((PhotoItem) item).getImageResourceId() == R.drawable.gallery_photo_7) {
    291                         intent = new Intent(getActivity(), RowsActivity.class);
    292                         bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity())
    293                                 .toBundle();
    294                     } else {
    295                         intent = new Intent(getActivity(), DetailsActivity.class);
    296                         intent.putExtra(DetailsActivity.EXTRA_ITEM, (PhotoItem) item);
    297                         bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
    298                                 getActivity(),
    299                                 ((ImageCardView) itemViewHolder.view).getMainImageView(),
    300                                 DetailsActivity.SHARED_ELEMENT_NAME).toBundle();
    301                     }
    302                     getActivity().startActivity(intent, bundle);
    303                 }
    304             });
    305         }
    306 
    307         private ArrayObjectAdapter createListRowAdapter(int i) {
    308             ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter((i & 1) == 0 ?
    309                     mCardPresenter : mCardPresenter2);
    310             listRowAdapter.add(new PhotoItem(
    311                     "Hello world",
    312                     R.drawable.gallery_photo_1));
    313             listRowAdapter.add(new PhotoItem(
    314                     "This is a test",
    315                     "Only a test",
    316                     R.drawable.gallery_photo_2));
    317             listRowAdapter.add(new PhotoItem(
    318                     "Android TV",
    319                     "by Google",
    320                     R.drawable.gallery_photo_3));
    321             listRowAdapter.add(new PhotoItem(
    322                     "Leanback",
    323                     R.drawable.gallery_photo_4));
    324             listRowAdapter.add(new PhotoItem(
    325                     "GuidedStep (Slide left/right)",
    326                     R.drawable.gallery_photo_5));
    327             listRowAdapter.add(new PhotoItem(
    328                     "GuidedStep (Slide bottom up)",
    329                     "Open GuidedStepFragment",
    330                     R.drawable.gallery_photo_6));
    331             listRowAdapter.add(new PhotoItem(
    332                     "Android TV",
    333                     "open RowsActivity",
    334                     R.drawable.gallery_photo_7));
    335             listRowAdapter.add(new PhotoItem(
    336                     "Leanback",
    337                     "open BrowseActivity",
    338                     R.drawable.gallery_photo_8));
    339             return listRowAdapter;
    340         }
    341     }
    342 
    343     public static class PageFragmentAdapterImpl extends MainFragmentAdapter<SampleFragment> {
    344 
    345         public PageFragmentAdapterImpl(SampleFragment fragment) {
    346             super(fragment);
    347             setScalingEnabled(true);
    348         }
    349 
    350         @Override
    351         public void setEntranceTransitionState(boolean state) {
    352             getFragment().setEntranceTransitionState(state);
    353         }
    354     }
    355 
    356     public static class SampleFragment extends Fragment implements MainFragmentAdapterProvider {
    357 
    358         final PageFragmentAdapterImpl mMainFragmentAdapter = new PageFragmentAdapterImpl(this);
    359 
    360         public void setEntranceTransitionState(boolean state) {
    361             final View view = getView();
    362             int visibility = state ? View.VISIBLE : View.INVISIBLE;
    363             view.findViewById(R.id.tv1).setVisibility(visibility);
    364             view.findViewById(R.id.tv2).setVisibility(visibility);
    365             view.findViewById(R.id.tv3).setVisibility(visibility);
    366         }
    367 
    368         @Override
    369         public View onCreateView(
    370                 final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    371             View view = inflater.inflate(R.layout.page_fragment, container, false);
    372             view.findViewById(R.id.tv1).setOnClickListener(new View.OnClickListener() {
    373                 @Override
    374                 public void onClick(View view) {
    375                     Intent intent = new Intent(inflater.getContext(), GuidedStepActivity.class);
    376                     startActivity(intent);
    377                 }
    378             });
    379 
    380             return view;
    381         }
    382 
    383         @Override
    384         public void onViewCreated(View view, Bundle savedInstanceState) {
    385             // static layout has view and data ready immediately
    386             mMainFragmentAdapter.getFragmentHost().notifyViewCreated(mMainFragmentAdapter);
    387             mMainFragmentAdapter.getFragmentHost().notifyDataReady(mMainFragmentAdapter);
    388         }
    389 
    390         @Override
    391         public MainFragmentAdapter getMainFragmentAdapter() {
    392             return mMainFragmentAdapter;
    393         }
    394     }
    395 }
    396