1 package com.android.car.media; 2 3 import android.content.Context; 4 import android.content.pm.PackageManager; 5 import android.os.Bundle; 6 import android.support.annotation.Nullable; 7 import android.support.v4.app.Fragment; 8 import android.support.v7.widget.GridLayoutManager; 9 import android.support.v7.widget.RecyclerView; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.ViewGroup; 13 import android.widget.ImageView; 14 import android.widget.TextView; 15 16 import com.android.car.media.common.MediaSource; 17 18 import java.util.ArrayList; 19 import java.util.List; 20 import java.util.Set; 21 import java.util.stream.Collectors; 22 23 import androidx.car.widget.PagedListView; 24 25 /** 26 * A {@link Fragment} that implements the app selection UI 27 */ 28 public class AppSelectionFragment extends Fragment { 29 private AppGridAdapter mGridAdapter; 30 @Nullable 31 private Callbacks mCallbacks; 32 33 private class AppGridAdapter extends RecyclerView.Adapter<AppItemViewHolder> { 34 private final LayoutInflater mInflater; 35 private List<MediaSource> mMediaSources; 36 AppGridAdapter()37 AppGridAdapter() { 38 mInflater = LayoutInflater.from(getContext()); 39 } 40 41 /** 42 * Triggers a refresh of media sources 43 */ updateSources(List<MediaSource> mediaSources)44 void updateSources(List<MediaSource> mediaSources) { 45 mMediaSources = new ArrayList<>(mediaSources); 46 notifyDataSetChanged(); 47 } 48 49 @Override onCreateViewHolder(ViewGroup parent, int viewType)50 public AppItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 51 View view = mInflater.inflate(R.layout.app_selection_item, parent, false); 52 return new AppItemViewHolder(view, getContext()); 53 54 } 55 56 @Override onBindViewHolder(AppItemViewHolder vh, int position)57 public void onBindViewHolder(AppItemViewHolder vh, int position) { 58 vh.bind(mMediaSources.get(position)); 59 } 60 61 @Override getItemCount()62 public int getItemCount() { 63 return mMediaSources.size(); 64 } 65 } 66 67 private class AppItemViewHolder extends RecyclerView.ViewHolder { 68 private final Context mContext; 69 public View mAppItem; 70 public ImageView mAppIconView; 71 public TextView mAppNameView; 72 AppItemViewHolder(View view, Context context)73 public AppItemViewHolder(View view, Context context) { 74 super(view); 75 mContext = context; 76 mAppItem = view.findViewById(R.id.app_item); 77 mAppIconView = mAppItem.findViewById(R.id.app_icon); 78 mAppNameView = mAppItem.findViewById(R.id.app_name); 79 } 80 81 /** 82 * Binds a media source to a view 83 */ bind(MediaSource mediaSource)84 public void bind(MediaSource mediaSource) { 85 // Empty out the view 86 mAppItem.setOnClickListener(v -> { 87 if (mCallbacks != null) { 88 mCallbacks.onMediaSourceSelected(mediaSource); 89 } 90 }); 91 mAppIconView.setImageDrawable(mediaSource.getPackageIcon()); 92 mAppNameView.setText(mediaSource.getName());; 93 } 94 } 95 96 /** 97 * Fragment callbacks (implemented by the hosting Activity) 98 */ 99 public interface Callbacks { 100 /** 101 * Invoked whenever this fragment requires to obtain the list of media source to select 102 * from. 103 */ getMediaSources()104 List<MediaSource> getMediaSources(); 105 106 /** 107 * Invoked when the user makes a selection 108 */ onMediaSourceSelected(MediaSource mediaSource)109 void onMediaSourceSelected(MediaSource mediaSource); 110 } 111 112 @Override onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState)113 public View onCreateView(LayoutInflater inflater, final ViewGroup container, 114 Bundle savedInstanceState) { 115 View view = inflater.inflate(R.layout.fragment_app_selection, container, false); 116 int columnNumber = getResources().getInteger(R.integer.num_app_selector_columns); 117 mGridAdapter = new AppGridAdapter(); 118 PagedListView gridView = view.findViewById(R.id.apps_grid); 119 120 GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), columnNumber); 121 gridView.getRecyclerView().setLayoutManager(gridLayoutManager); 122 gridView.setAdapter(mGridAdapter); 123 return view; 124 } 125 126 @Override onAttach(Context context)127 public void onAttach(Context context) { 128 super.onAttach(context); 129 mCallbacks = (Callbacks) context; 130 } 131 132 @Override onDetach()133 public void onDetach() { 134 super.onDetach(); 135 mCallbacks = null; 136 } 137 138 @Override onResume()139 public void onResume() { 140 super.onResume(); 141 refresh(); 142 } 143 144 /** 145 * Refreshes the list of media sources. 146 */ refresh()147 public void refresh() { 148 if (mCallbacks != null) { 149 mGridAdapter.updateSources(mCallbacks.getMediaSources()); 150 } 151 } 152 } 153