ProgramGuideSearchFragment.java revision 0645b17e2818b69b996da48fd93731bc8a01f114
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.tv.search; 18 19import android.content.res.Resources; 20import android.graphics.Bitmap; 21import android.graphics.drawable.BitmapDrawable; 22import android.os.AsyncTask; 23import android.os.Bundle; 24import android.support.v17.leanback.app.SearchFragment; 25import android.support.v17.leanback.widget.ArrayObjectAdapter; 26import android.support.v17.leanback.widget.HeaderItem; 27import android.support.v17.leanback.widget.ImageCardView; 28import android.support.v17.leanback.widget.ListRow; 29import android.support.v17.leanback.widget.ListRowPresenter; 30import android.support.v17.leanback.widget.ObjectAdapter; 31import android.support.v17.leanback.widget.OnItemViewClickedListener; 32import android.support.v17.leanback.widget.Presenter; 33import android.support.v17.leanback.widget.Row; 34import android.support.v17.leanback.widget.RowPresenter; 35import android.support.v17.leanback.widget.SearchBar; 36import android.text.TextUtils; 37import android.util.Log; 38import android.view.LayoutInflater; 39import android.view.View; 40import android.view.ViewGroup; 41import com.android.tv.MainActivity; 42import com.android.tv.R; 43import com.android.tv.common.util.PermissionUtils; 44import com.android.tv.util.ImageLoader; 45import java.util.List; 46 47public class ProgramGuideSearchFragment extends SearchFragment { 48 private static final String TAG = "ProgramGuideSearch"; 49 private static final boolean DEBUG = false; 50 private static final int SEARCH_RESULT_MAX = 10; 51 52 private final Presenter mPresenter = 53 new Presenter() { 54 @Override 55 public Presenter.ViewHolder onCreateViewHolder(ViewGroup viewGroup) { 56 if (DEBUG) Log.d(TAG, "onCreateViewHolder"); 57 58 ImageCardView cardView = new ImageCardView(mMainActivity); 59 cardView.setFocusable(true); 60 cardView.setFocusableInTouchMode(true); 61 cardView.setMainImageAdjustViewBounds(false); 62 63 Resources res = mMainActivity.getResources(); 64 cardView.setMainImageDimensions( 65 res.getDimensionPixelSize(R.dimen.card_image_layout_width), 66 res.getDimensionPixelSize(R.dimen.card_image_layout_height)); 67 68 return new Presenter.ViewHolder(cardView); 69 } 70 71 @Override 72 public void onBindViewHolder(ViewHolder viewHolder, Object o) { 73 ImageCardView cardView = (ImageCardView) viewHolder.view; 74 LocalSearchProvider.SearchResult result = (LocalSearchProvider.SearchResult) o; 75 if (DEBUG) Log.d(TAG, "onBindViewHolder result:" + result); 76 77 cardView.setTitleText(result.getTitle()); 78 if (!TextUtils.isEmpty(result.getImageUri())) { 79 ImageLoader.loadBitmap( 80 mMainActivity, 81 result.getImageUri(), 82 mMainCardWidth, 83 mMainCardHeight, 84 createImageLoaderCallback(cardView)); 85 } else { 86 cardView.setMainImage( 87 mMainActivity.getDrawable(R.drawable.ic_live_channels_96x96)); 88 } 89 } 90 91 @Override 92 public void onUnbindViewHolder(ViewHolder viewHolder) { 93 // Do nothing here. 94 } 95 }; 96 97 private static ImageLoader.ImageLoaderCallback<ImageCardView> createImageLoaderCallback( 98 ImageCardView cardView) { 99 return new ImageLoader.ImageLoaderCallback<ImageCardView>(cardView) { 100 @Override 101 public void onBitmapLoaded(ImageCardView cardView, Bitmap bitmap) { 102 cardView.setMainImage( 103 new BitmapDrawable(cardView.getContext().getResources(), bitmap)); 104 } 105 }; 106 } 107 108 private final SearchResultProvider mSearchResultProvider = 109 new SearchResultProvider() { 110 @Override 111 public ObjectAdapter getResultsAdapter() { 112 return mResultAdapter; 113 } 114 115 @Override 116 public boolean onQueryTextChange(String query) { 117 searchAndRefresh(query); 118 return true; 119 } 120 121 @Override 122 public boolean onQueryTextSubmit(String query) { 123 searchAndRefresh(query); 124 return true; 125 } 126 }; 127 128 private final OnItemViewClickedListener mItemClickedListener = 129 new OnItemViewClickedListener() { 130 @Override 131 public void onItemClicked( 132 Presenter.ViewHolder viewHolder, 133 Object o, 134 RowPresenter.ViewHolder viewHolder1, 135 Row row) { 136 LocalSearchProvider.SearchResult result = (LocalSearchProvider.SearchResult) o; 137 mMainActivity.getFragmentManager().popBackStack(); 138 mMainActivity.tuneToChannel( 139 mMainActivity.getChannelDataManager().getChannel( 140 result.getChannelId())); 141 } 142 }; 143 144 private final ArrayObjectAdapter mResultAdapter = 145 new ArrayObjectAdapter(new ListRowPresenter()); 146 private MainActivity mMainActivity; 147 private SearchInterface mSearch; 148 private int mMainCardWidth; 149 private int mMainCardHeight; 150 private SearchTask mSearchTask; 151 152 @Override 153 public void onCreate(Bundle savedInstanceState) { 154 super.onCreate(savedInstanceState); 155 156 mMainActivity = (MainActivity) getActivity(); 157 if (PermissionUtils.hasAccessAllEpg(mMainActivity)) { 158 mSearch = new TvProviderSearch(mMainActivity); 159 } else { 160 mSearch = new DataManagerSearch(mMainActivity); 161 } 162 Resources res = getResources(); 163 mMainCardWidth = res.getDimensionPixelSize(R.dimen.card_image_layout_width); 164 mMainCardHeight = res.getDimensionPixelSize(R.dimen.card_image_layout_height); 165 } 166 167 @Override 168 public View onCreateView( 169 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 170 View v = super.onCreateView(inflater, container, savedInstanceState); 171 v.setBackgroundResource(R.color.program_guide_scrim); 172 173 setBadgeDrawable(mMainActivity.getDrawable(R.drawable.ic_live_channels_96x96)); 174 setSearchResultProvider(mSearchResultProvider); 175 setOnItemViewClickedListener(mItemClickedListener); 176 return v; 177 } 178 179 @Override 180 public void onResume() { 181 super.onResume(); 182 183 SearchBar searchBar = (SearchBar) getView().findViewById(R.id.lb_search_bar); 184 searchBar.setSearchQuery(""); 185 mResultAdapter.clear(); 186 } 187 188 private void searchAndRefresh(String query) { 189 // TODO: Search directly from program data manager for performance. 190 // TODO: Search upcoming programs. 191 if (mSearchTask != null) { 192 mSearchTask.cancel(true); 193 } 194 mSearchTask = new SearchTask(query); 195 mSearchTask.execute(); 196 } 197 198 private class SearchTask extends AsyncTask<Void, Void, List<LocalSearchProvider.SearchResult>> { 199 private final String mQuery; 200 201 public SearchTask(String query) { 202 mQuery = query; 203 } 204 205 @Override 206 protected List<LocalSearchProvider.SearchResult> doInBackground(Void... params) { 207 return mSearch.search( 208 mQuery, SEARCH_RESULT_MAX, TvProviderSearch.ACTION_TYPE_AMBIGUOUS); 209 } 210 211 @Override 212 protected void onPostExecute(List<LocalSearchProvider.SearchResult> results) { 213 super.onPostExecute(results); 214 mResultAdapter.clear(); 215 216 if (DEBUG) { 217 Log.d( 218 TAG, 219 "searchAndRefresh query=" 220 + mQuery 221 + " results=" 222 + ((results == null) ? 0 : results.size())); 223 } 224 225 if (results == null || results.size() == 0) { 226 HeaderItem header = 227 new HeaderItem( 228 0, mMainActivity.getString(R.string.search_result_no_result)); 229 ArrayObjectAdapter resultsAdapter = new ArrayObjectAdapter(mPresenter); 230 mResultAdapter.add(new ListRow(header, resultsAdapter)); 231 } else { 232 HeaderItem header = 233 new HeaderItem(0, mMainActivity.getString(R.string.search_result_title)); 234 ArrayObjectAdapter resultsAdapter = new ArrayObjectAdapter(mPresenter); 235 resultsAdapter.addAll(0, results); 236 mResultAdapter.add(new ListRow(header, resultsAdapter)); 237 } 238 mSearchTask = null; 239 } 240 } 241} 242