1 // CHECKSTYLE:OFF Generated code 2 /* This file is auto-generated from SearchFragment.java. DO NOT MODIFY. */ 3 4 package com.example.android.leanback; 5 6 import static com.example.android.leanback.CardPresenter.CONTENT; 7 import static com.example.android.leanback.CardPresenter.IMAGE; 8 import static com.example.android.leanback.CardPresenter.TITLE; 9 10 import android.content.Context; 11 import android.content.Intent; 12 import android.os.Bundle; 13 import android.os.Handler; 14 import android.text.TextUtils; 15 import android.util.Log; 16 17 import androidx.core.app.ActivityOptionsCompat; 18 import androidx.core.content.res.ResourcesCompat; 19 import androidx.leanback.widget.ArrayObjectAdapter; 20 import androidx.leanback.widget.DiffCallback; 21 import androidx.leanback.widget.HeaderItem; 22 import androidx.leanback.widget.ImageCardView; 23 import androidx.leanback.widget.ListRow; 24 import androidx.leanback.widget.ListRowPresenter; 25 import androidx.leanback.widget.ObjectAdapter; 26 import androidx.leanback.widget.OnItemViewClickedListener; 27 import androidx.leanback.widget.Presenter; 28 import androidx.leanback.widget.Row; 29 import androidx.leanback.widget.RowPresenter; 30 31 import org.jspecify.annotations.NonNull; 32 import org.jspecify.annotations.Nullable; 33 34 import java.util.ArrayList; 35 36 public class SearchSupportFragment extends androidx.leanback.app.SearchSupportFragment 37 implements androidx.leanback.app.SearchSupportFragment.SearchResultProvider { 38 private static final String TAG = "leanback.SearchSupportFragment"; 39 private static final int NUM_ROWS = 3; 40 private static final int SEARCH_DELAY_MS = 1000; 41 42 private ArrayObjectAdapter mRowsAdapter; 43 private Handler mHandler = new Handler(); 44 private String mQuery; 45 46 // Flag to represent if data set one is presented in the fragment 47 private boolean mIsDataSetOnePresented; 48 49 // Adapter for first row 50 private ArrayObjectAdapter mFirstRowAdapter; 51 52 // The diff callback which defines the standard to judge if two items are the same or if 53 // two items have the same content. 54 private DiffCallback<PhotoItem> mDiffCallback = new DiffCallback<PhotoItem>() { 55 56 // when two photo items have the same id, they are the same from adapter's 57 // perspective 58 @Override 59 public boolean areItemsTheSame(@NonNull PhotoItem oldItem, @NonNull PhotoItem newItem) { 60 return oldItem.getId() == newItem.getId(); 61 } 62 63 // when two photo items is equal to each other (based on the equal method defined in 64 // PhotoItem), they have the same content. 65 @Override 66 public boolean areContentsTheSame(@NonNull PhotoItem oldItem, @NonNull PhotoItem newItem) { 67 return oldItem.equals(newItem); 68 } 69 70 @Override 71 public @Nullable Object getChangePayload(@NonNull PhotoItem oldItem, 72 @NonNull PhotoItem newItem) { 73 Bundle diff = new Bundle(); 74 if (oldItem.getImageResourceId() 75 != newItem.getImageResourceId()) { 76 diff.putLong(IMAGE, newItem.getImageResourceId()); 77 } 78 79 if (oldItem.getTitle() != null && newItem.getTitle() != null 80 && !oldItem.getTitle().equals(newItem.getTitle())) { 81 diff.putString(TITLE, newItem.getTitle()); 82 } 83 84 if (oldItem.getContent() != null && newItem.getContent() != null 85 && !oldItem.getContent().equals(newItem.getContent())) { 86 diff.putString(CONTENT, newItem.getContent()); 87 } 88 return diff; 89 } 90 }; 91 92 @Override onCreate(Bundle savedInstanceState)93 public void onCreate(Bundle savedInstanceState) { 94 super.onCreate(savedInstanceState); 95 96 mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); 97 98 final Context context = getActivity(); 99 setBadgeDrawable(ResourcesCompat.getDrawable(context.getResources(), 100 R.drawable.ic_title, context.getTheme())); 101 setTitle("Leanback Sample App"); 102 setSearchResultProvider(this); 103 setOnItemViewClickedListener(new ItemViewClickedListener()); 104 } 105 106 @Override getResultsAdapter()107 public ObjectAdapter getResultsAdapter() { 108 return mRowsAdapter; 109 } 110 111 @Override onQueryTextChange(String newQuery)112 public boolean onQueryTextChange(String newQuery) { 113 Log.i(TAG, String.format("Search Query Text Change %s", newQuery)); 114 mRowsAdapter.clear(); 115 loadQuery(newQuery); 116 return true; 117 } 118 119 @Override onQueryTextSubmit(String query)120 public boolean onQueryTextSubmit(String query) { 121 Log.i(TAG, String.format("Search Query Text Submit %s", query)); 122 mRowsAdapter.clear(); 123 loadQuery(query); 124 return true; 125 } 126 loadQuery(String query)127 private void loadQuery(String query) { 128 mQuery = query; 129 mHandler.removeCallbacks(mDelayedLoad); 130 if (!TextUtils.isEmpty(query) && !query.equals("nil")) { 131 mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS); 132 } 133 } 134 loadRows()135 private void loadRows() { 136 HeaderItem header = new HeaderItem(0, mQuery + " results row " + 0); 137 138 // Every time when the query event is fired, we will update the fake search result in the 139 // first row based on the flag mIsDataSetOnePresented flag. 140 // Also the first row adapter will only be created once so the animation will be triggered 141 // when the items in the adapter changed. 142 if (!mIsDataSetOnePresented) { 143 if (mFirstRowAdapter == null) { 144 mFirstRowAdapter = createFirstListRowAdapter(); 145 } else { 146 mFirstRowAdapter.setItems(createDataSetOneDebug(), mDiffCallback); 147 } 148 mIsDataSetOnePresented = true; 149 } else { 150 mFirstRowAdapter.setItems(createDataSetTwoDebug(), mDiffCallback); 151 mIsDataSetOnePresented = false; 152 } 153 mRowsAdapter.add(new ListRow(header, mFirstRowAdapter)); 154 for (int i = 1; i < NUM_ROWS + 1; ++i) { 155 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter()); 156 listRowAdapter.add(new PhotoItem("Hello world", R.drawable.gallery_photo_1)); 157 listRowAdapter.add(new PhotoItem("This is a test", R.drawable.gallery_photo_2)); 158 header = new HeaderItem(i, mQuery + " results row " + i); 159 mRowsAdapter.add(new ListRow(header, listRowAdapter)); 160 } 161 } 162 163 private Runnable mDelayedLoad = new Runnable() { 164 @Override 165 public void run() { 166 loadRows(); 167 } 168 }; 169 170 private final class ItemViewClickedListener implements OnItemViewClickedListener { 171 @Override onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row)172 public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, 173 RowPresenter.ViewHolder rowViewHolder, Row row) { 174 Intent intent = new Intent(getActivity(), DetailsSupportActivity.class); 175 intent.putExtra(DetailsSupportActivity.EXTRA_ITEM, (PhotoItem) item); 176 177 Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( 178 getActivity(), 179 ((ImageCardView) itemViewHolder.view).getMainImageView(), 180 DetailsSupportActivity.SHARED_ELEMENT_NAME).toBundle(); 181 getActivity().startActivity(intent, bundle); 182 } 183 } 184 185 createFirstListRowAdapter()186 private ArrayObjectAdapter createFirstListRowAdapter() { 187 ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter()); 188 listRowAdapter.setItems(createDataSetOneDebug(), mDiffCallback); 189 mIsDataSetOnePresented = true; 190 return listRowAdapter; 191 } 192 createDataSetOneDebug()193 private ArrayList<PhotoItem> createDataSetOneDebug() { 194 ArrayList<PhotoItem> photoItems = new ArrayList<>(); 195 photoItems.add(new PhotoItem( 196 "Hello world", 197 R.drawable.gallery_photo_1, 198 1)); 199 return photoItems; 200 } 201 202 /** 203 * Create a new data set (data set one) for the last row of this browse fragment. It will be 204 * changed by another set of data when user click one of the photo items in the list. 205 * Different with other rows in the browsing fragment, the photo item in last row all have been 206 * allocated with a unique id. And the id will be used to jduge if two photo items are the same 207 * or not. 208 * 209 * @return List of photoItem 210 */ createDataSetTwoDebug()211 private ArrayList<PhotoItem> createDataSetTwoDebug() { 212 ArrayList<PhotoItem> photoItems = new ArrayList<>(); 213 photoItems.add(new PhotoItem( 214 "Hello world Hello world", 215 R.drawable.gallery_photo_1, 216 1)); 217 return photoItems; 218 } 219 } 220