1 /* 2 * Copyright (C) 2022 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 17 package com.android.settings.dream; 18 19 import android.annotation.LayoutRes; 20 import android.content.Context; 21 import android.graphics.drawable.Drawable; 22 import android.text.TextUtils; 23 import android.util.SparseIntArray; 24 import android.view.LayoutInflater; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.widget.Button; 28 import android.widget.ImageView; 29 import android.widget.TextView; 30 31 import androidx.annotation.NonNull; 32 import androidx.recyclerview.widget.RecyclerView; 33 34 import com.android.settings.R; 35 import com.android.settingslib.utils.ColorUtil; 36 37 import java.util.List; 38 39 /** 40 * RecyclerView adapter which displays list of items for the user to select. 41 */ 42 public class DreamAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { 43 private final List<IDreamItem> mItemList; 44 private int mLastSelectedPos = -1; 45 private boolean mEnabled = true; 46 private SparseIntArray mLayouts = new SparseIntArray(); 47 48 /** 49 * View holder for each {@link IDreamItem}. 50 */ 51 private class DreamViewHolder extends RecyclerView.ViewHolder { 52 private final TextView mTitleView; 53 private final TextView mSummaryView; 54 private final ImageView mPreviewView; 55 private final ImageView mPreviewPlaceholderView; 56 private final Button mCustomizeButton; 57 private final Context mContext; 58 private final float mDisabledAlphaValue; 59 DreamViewHolder(View view, Context context)60 DreamViewHolder(View view, Context context) { 61 super(view); 62 mContext = context; 63 mPreviewView = view.findViewById(R.id.preview); 64 mPreviewPlaceholderView = view.findViewById(R.id.preview_placeholder); 65 mTitleView = view.findViewById(R.id.title_text); 66 mSummaryView = view.findViewById(R.id.summary_text); 67 mCustomizeButton = view.findViewById(R.id.customize_button); 68 mDisabledAlphaValue = ColorUtil.getDisabledAlpha(context); 69 } 70 71 /** 72 * Bind the view at the given position, populating the view with the provided data. 73 */ bindView(IDreamItem item, int position)74 public void bindView(IDreamItem item, int position) { 75 mTitleView.setText(item.getTitle()); 76 77 final CharSequence summary = item.getSummary(); 78 if (TextUtils.isEmpty(summary)) { 79 mSummaryView.setVisibility(View.GONE); 80 } else { 81 mSummaryView.setText(summary); 82 mSummaryView.setVisibility(View.VISIBLE); 83 } 84 85 final Drawable icon = item.isActive() 86 ? mContext.getDrawable(R.drawable.ic_dream_check_circle) 87 : item.getIcon().mutate(); 88 final int iconSize = mContext.getResources().getDimensionPixelSize( 89 R.dimen.dream_item_icon_size); 90 icon.setBounds(0, 0, iconSize, iconSize); 91 mTitleView.setCompoundDrawablesRelative(icon, null, null, null); 92 93 itemView.setOnClickListener(v -> { 94 item.onItemClicked(); 95 if (mLastSelectedPos > -1 && mLastSelectedPos != position) { 96 notifyItemChanged(mLastSelectedPos); 97 } 98 notifyItemChanged(position); 99 }); 100 101 if (item.isActive()) { 102 mLastSelectedPos = position; 103 itemView.setSelected(true); 104 itemView.setClickable(false); 105 } else { 106 itemView.setSelected(false); 107 itemView.setClickable(true); 108 } 109 110 if (item.viewType() != DreamItemViewTypes.NO_DREAM_ITEM) { 111 final Drawable previewImage = item.getPreviewImage(); 112 if (previewImage != null) { 113 mPreviewView.setImageDrawable(previewImage); 114 mPreviewView.setClipToOutline(true); 115 mPreviewPlaceholderView.setVisibility(View.GONE); 116 } else { 117 mPreviewView.setImageDrawable(null); 118 mPreviewPlaceholderView.setVisibility(View.VISIBLE); 119 } 120 121 mCustomizeButton.setOnClickListener(v -> item.onCustomizeClicked()); 122 mCustomizeButton.setVisibility( 123 item.allowCustomization() && mEnabled ? View.VISIBLE : View.GONE); 124 // This must be called AFTER itemView.setSelected above, in order to keep the 125 // customize button in an unselected state. 126 mCustomizeButton.setSelected(false); 127 mCustomizeButton.setContentDescription( 128 mContext.getResources().getString(R.string.customize_button_description, 129 item.getTitle())); 130 } 131 132 setEnabledStateOnViews(itemView, mEnabled); 133 } 134 135 /** 136 * Makes sure the view (and any children) get the enabled state changed. 137 */ setEnabledStateOnViews(@onNull View v, boolean enabled)138 private void setEnabledStateOnViews(@NonNull View v, boolean enabled) { 139 v.setEnabled(enabled); 140 141 if (v instanceof ViewGroup) { 142 final ViewGroup vg = (ViewGroup) v; 143 for (int i = vg.getChildCount() - 1; i >= 0; i--) { 144 setEnabledStateOnViews(vg.getChildAt(i), enabled); 145 } 146 } else { 147 v.setAlpha(enabled ? 1 : mDisabledAlphaValue); 148 } 149 } 150 } 151 DreamAdapter(SparseIntArray layouts, List<IDreamItem> itemList)152 public DreamAdapter(SparseIntArray layouts, List<IDreamItem> itemList) { 153 mItemList = itemList; 154 mLayouts = layouts; 155 } 156 DreamAdapter(@ayoutRes int layoutRes, List<IDreamItem> itemList)157 public DreamAdapter(@LayoutRes int layoutRes, List<IDreamItem> itemList) { 158 mItemList = itemList; 159 mLayouts.append(DreamItemViewTypes.DREAM_ITEM, layoutRes); 160 } 161 162 @NonNull 163 @Override onCreateViewHolder(@onNull ViewGroup viewGroup, @DreamItemViewTypes.ViewType int viewType)164 public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, 165 @DreamItemViewTypes.ViewType int viewType) { 166 View view = LayoutInflater.from(viewGroup.getContext()) 167 .inflate(mLayouts.get(viewType), viewGroup, false); 168 return new DreamViewHolder(view, viewGroup.getContext()); 169 } 170 171 @Override onBindViewHolder(@onNull RecyclerView.ViewHolder viewHolder, int i)172 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { 173 ((DreamViewHolder) viewHolder).bindView(mItemList.get(i), i); 174 } 175 176 @Override getItemViewType(int position)177 public @DreamItemViewTypes.ViewType int getItemViewType(int position) { 178 return mItemList.get(position).viewType(); 179 } 180 181 @Override getItemCount()182 public int getItemCount() { 183 return mItemList.size(); 184 } 185 186 /** 187 * Sets the enabled state of all items. 188 */ setEnabled(boolean enabled)189 public void setEnabled(boolean enabled) { 190 if (mEnabled != enabled) { 191 mEnabled = enabled; 192 notifyDataSetChanged(); 193 } 194 } 195 196 /** 197 * Gets the enabled state of all items. 198 */ getEnabled()199 public boolean getEnabled() { 200 return mEnabled; 201 } 202 } 203