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 
15 package com.example.android.tvleanback.ui;
16 
17 import android.content.Intent;
18 import android.os.Bundle;
19 import android.os.Handler;
20 import android.support.v17.leanback.widget.ArrayObjectAdapter;
21 import android.support.v17.leanback.widget.HeaderItem;
22 import android.support.v17.leanback.widget.ImageCardView;
23 import android.support.v17.leanback.widget.ListRow;
24 import android.support.v17.leanback.widget.ListRowPresenter;
25 import android.support.v17.leanback.widget.ObjectAdapter;
26 import android.support.v17.leanback.widget.OnItemViewClickedListener;
27 import android.support.v17.leanback.widget.Presenter;
28 import android.support.v17.leanback.widget.Row;
29 import android.support.v17.leanback.widget.RowPresenter;
30 import android.support.v4.app.ActivityOptionsCompat;
31 import android.text.TextUtils;
32 import android.util.Log;
33 import android.widget.Toast;
34 
35 import com.example.android.tvleanback.R;
36 import com.example.android.tvleanback.data.VideoProvider;
37 import com.example.android.tvleanback.model.Movie;
38 import com.example.android.tvleanback.presenter.CardPresenter;
39 
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Locale;
43 import java.util.Map;
44 
45 /*
46  * This class demonstrates how to do in-app search
47  */
48 public class SearchFragment extends android.support.v17.leanback.app.SearchFragment
49         implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider {
50     private static final String TAG = "SearchFragment";
51     private static final int SEARCH_DELAY_MS = 1000;
52 
53     private ArrayObjectAdapter mRowsAdapter;
54     private Handler mHandler = new Handler();
55     private SearchRunnable mDelayedLoad;
56     private String mQuery;
57 
58     @Override
onCreate(Bundle savedInstanceState)59     public void onCreate(Bundle savedInstanceState) {
60         super.onCreate(savedInstanceState);
61 
62         mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
63         setSearchResultProvider(this);
64         setOnItemViewClickedListener(new ItemViewClickedListener());
65         mDelayedLoad = new SearchRunnable();
66     }
67 
68     @Override
getResultsAdapter()69     public ObjectAdapter getResultsAdapter() {
70         return mRowsAdapter;
71     }
72 
73     @Override
onQueryTextChange(String newQuery)74     public boolean onQueryTextChange(String newQuery) {
75         Log.i(TAG, String.format("Search Query Text Change %s", newQuery));
76         loadQuery(newQuery);
77         return true;
78     }
79 
80     @Override
onQueryTextSubmit(String query)81     public boolean onQueryTextSubmit(String query) {
82         Log.i(TAG, String.format("Search Query Text Submit %s", query));
83         loadQuery(query);
84         return true;
85     }
86 
loadQuery(String query)87     private void loadQuery(String query) {
88         mQuery = query;
89         mRowsAdapter.clear();
90         mHandler.removeCallbacks(mDelayedLoad);
91         if (!TextUtils.isEmpty(query) && !query.equals("nil")) {
92             mDelayedLoad.setSearchQuery(query);
93             mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
94         }
95     }
96 
loadRows(String query)97     private void loadRows(String query) {
98         HashMap<String, List<Movie>> movies = VideoProvider.getMovieList();
99         ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
100         for (Map.Entry<String, List<Movie>> entry : movies.entrySet()) {
101             for (Movie movie : entry.getValue()) {
102                 if (movie.getTitle().toLowerCase(Locale.ENGLISH)
103                         .contains(query.toLowerCase(Locale.ENGLISH))
104                         || movie.getDescription().toLowerCase(Locale.ENGLISH)
105                         .contains(query.toLowerCase(Locale.ENGLISH))) {
106                     listRowAdapter.add(movie);
107                 }
108             }
109         }
110         HeaderItem header = new HeaderItem(0, getResources().getString(R.string.search_results)
111                 + " '" + mQuery + "'");
112         mRowsAdapter.add(new ListRow(header, listRowAdapter));
113     }
114 
115     private class SearchRunnable implements Runnable {
116 
117         private volatile String searchQuery;
118 
SearchRunnable()119         public SearchRunnable() {
120         }
121 
run()122         public void run() {
123             loadRows(searchQuery);
124         }
125 
setSearchQuery(String value)126         public void setSearchQuery(String value) {
127             this.searchQuery = value;
128         }
129     }
130 
131     private final class ItemViewClickedListener implements OnItemViewClickedListener {
132         @Override
onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row)133         public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
134                                   RowPresenter.ViewHolder rowViewHolder, Row row) {
135 
136             if (item instanceof Movie) {
137                 Movie movie = (Movie) item;
138                 Log.d(TAG, "Movie: " + movie.toString());
139                 Intent intent = new Intent(getActivity(), MovieDetailsActivity.class);
140                 intent.putExtra(MovieDetailsActivity.MOVIE, movie);
141 
142                 Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(
143                         getActivity(),
144                         ((ImageCardView) itemViewHolder.view).getMainImageView(),
145                         MovieDetailsActivity.SHARED_ELEMENT_NAME).toBundle();
146                 getActivity().startActivity(intent, bundle);
147             } else {
148                 Toast.makeText(getActivity(), ((String) item), Toast.LENGTH_SHORT)
149                         .show();
150             }
151         }
152     }
153 
154 
155 }
156