1 /* 2 * Copyright (C) 2024 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.notification.modes; 18 19 import android.content.Context; 20 import android.view.LayoutInflater; 21 import android.view.View; 22 import android.view.ViewGroup; 23 import android.widget.ImageView; 24 25 import androidx.annotation.DrawableRes; 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 import androidx.annotation.VisibleForTesting; 29 import androidx.preference.Preference; 30 import androidx.preference.PreferenceScreen; 31 import androidx.recyclerview.widget.GridLayoutManager; 32 import androidx.recyclerview.widget.RecyclerView; 33 34 import com.android.settings.R; 35 import com.android.settings.dashboard.DashboardFragment; 36 import com.android.settingslib.widget.LayoutPreference; 37 38 import com.google.common.collect.ImmutableList; 39 40 class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenceController { 41 42 private final DashboardFragment mFragment; 43 private final IconOptionsProvider mIconOptionsProvider; 44 @Nullable private IconAdapter mAdapter; 45 ZenModeIconPickerListPreferenceController(@onNull Context context, @NonNull String key, @NonNull DashboardFragment fragment, @NonNull IconOptionsProvider iconOptionsProvider, @Nullable ZenModesBackend backend)46 ZenModeIconPickerListPreferenceController(@NonNull Context context, @NonNull String key, 47 @NonNull DashboardFragment fragment, @NonNull IconOptionsProvider iconOptionsProvider, 48 @Nullable ZenModesBackend backend) { 49 super(context, key, backend); 50 mFragment = fragment; 51 mIconOptionsProvider = iconOptionsProvider; 52 } 53 54 @Override displayPreference(PreferenceScreen screen)55 public void displayPreference(PreferenceScreen screen) { 56 super.displayPreference(screen); 57 LayoutPreference pref = screen.findPreference(getPreferenceKey()); 58 if (pref == null) { 59 return; 60 } 61 62 if (mAdapter == null) { 63 mAdapter = new IconAdapter(mIconOptionsProvider); 64 } 65 RecyclerView recyclerView = pref.findViewById(R.id.icon_list); 66 recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext)); 67 recyclerView.setAdapter(mAdapter); 68 recyclerView.setHasFixedSize(true); 69 } 70 71 @VisibleForTesting onIconSelected(@rawableRes int resId)72 void onIconSelected(@DrawableRes int resId) { 73 saveMode(mode -> { 74 mode.getRule().setIconResId(resId); 75 return mode; 76 }); 77 mFragment.finish(); 78 } 79 80 @Override updateState(Preference preference, @NonNull ZenMode zenMode)81 void updateState(Preference preference, @NonNull ZenMode zenMode) { 82 // Nothing to do, the current icon is shown in a different preference. 83 } 84 85 private class IconHolder extends RecyclerView.ViewHolder { 86 87 private final ImageView mImageView; 88 IconHolder(@onNull View itemView)89 IconHolder(@NonNull View itemView) { 90 super(itemView); 91 mImageView = itemView.findViewById(R.id.icon_image_view); 92 } 93 bindIcon(IconOptionsProvider.IconInfo icon)94 void bindIcon(IconOptionsProvider.IconInfo icon) { 95 mImageView.setImageDrawable( 96 IconUtil.makeIconCircle(itemView.getContext(), icon.resId())); 97 itemView.setContentDescription(icon.description()); 98 itemView.setOnClickListener(v -> onIconSelected(icon.resId())); 99 } 100 } 101 102 private class IconAdapter extends RecyclerView.Adapter<IconHolder> { 103 104 private final ImmutableList<IconOptionsProvider.IconInfo> mIconResources; 105 IconAdapter(IconOptionsProvider iconOptionsProvider)106 private IconAdapter(IconOptionsProvider iconOptionsProvider) { 107 mIconResources = iconOptionsProvider.getIcons(); 108 } 109 110 @NonNull 111 @Override onCreateViewHolder(@onNull ViewGroup parent, int viewType)112 public IconHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 113 View itemView = LayoutInflater.from(parent.getContext()).inflate( 114 R.layout.modes_icon_list_item, parent, false); 115 return new IconHolder(itemView); 116 } 117 118 @Override onBindViewHolder(@onNull IconHolder holder, int position)119 public void onBindViewHolder(@NonNull IconHolder holder, int position) { 120 holder.bindIcon(mIconResources.get(position)); 121 } 122 123 @Override getItemCount()124 public int getItemCount() { 125 return mIconResources.size(); 126 } 127 } 128 129 private static class AutoFitGridLayoutManager extends GridLayoutManager { 130 private final float mColumnWidth; 131 AutoFitGridLayoutManager(Context context)132 AutoFitGridLayoutManager(Context context) { 133 super(context, /* spanCount= */ 1); 134 this.mColumnWidth = context 135 .getResources() 136 .getDimensionPixelSize(R.dimen.zen_mode_icon_list_item_size); 137 } 138 139 @Override onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state)140 public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 141 final int totalSpace = getWidth() - getPaddingRight() - getPaddingLeft(); 142 final int spanCount = Math.max(1, (int) (totalSpace / mColumnWidth)); 143 setSpanCount(spanCount); 144 super.onLayoutChildren(recycler, state); 145 } 146 } 147 } 148