Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2016 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.deskclock.settings;
     18 
     19 import android.content.Context;
     20 import android.support.annotation.NonNull;
     21 import android.support.v4.content.ContextCompat;
     22 import android.support.v7.preference.DropDownPreference;
     23 import android.util.AttributeSet;
     24 import android.view.View;
     25 import android.view.ViewGroup;
     26 import android.widget.ArrayAdapter;
     27 
     28 import com.android.deskclock.R;
     29 import com.android.deskclock.Utils;
     30 
     31 /**
     32  * Bend {@link DropDownPreference} to support
     33  * <a href="https://material.google.com/components/menus.html#menus-behavior">Simple Menus</a>.
     34  */
     35 public class SimpleMenuPreference extends DropDownPreference {
     36 
     37     private SimpleMenuAdapter mAdapter;
     38 
     39     public SimpleMenuPreference(Context context) {
     40         this(context, null);
     41     }
     42 
     43     public SimpleMenuPreference(Context context, AttributeSet attrs) {
     44         this(context, attrs, R.attr.dropdownPreferenceStyle);
     45     }
     46 
     47     public SimpleMenuPreference(Context context, AttributeSet attrs, int defStyle) {
     48         this(context, attrs, defStyle, 0);
     49     }
     50 
     51     public SimpleMenuPreference(Context context, AttributeSet attrs, int defStyleAttr,
     52             int defStyleRes) {
     53         super(context, attrs, defStyleAttr, defStyleRes);
     54     }
     55 
     56     @Override
     57     protected ArrayAdapter createAdapter() {
     58         mAdapter = new SimpleMenuAdapter(getContext(), R.layout.simple_menu_dropdown_item);
     59         return mAdapter;
     60     }
     61 
     62     private static void restoreOriginalOrder(CharSequence[] array,
     63             int lastSelectedOriginalPosition) {
     64         final CharSequence item = array[0];
     65         System.arraycopy(array, 1, array, 0, lastSelectedOriginalPosition);
     66         array[lastSelectedOriginalPosition] = item;
     67     }
     68 
     69     private static void swapSelectedToFront(CharSequence[] array, int position) {
     70         final CharSequence item = array[position];
     71         System.arraycopy(array, 0, array, 1, position);
     72         array[0] = item;
     73     }
     74 
     75     private static void setSelectedPosition(CharSequence[] array, int lastSelectedOriginalPosition,
     76             int position) {
     77         final CharSequence item = array[position];
     78         restoreOriginalOrder(array, lastSelectedOriginalPosition);
     79         final int originalPosition = Utils.indexOf(array, item);
     80         swapSelectedToFront(array, originalPosition);
     81     }
     82 
     83     @Override
     84     public void setSummary(CharSequence summary) {
     85         final CharSequence[] entries = getEntries();
     86         final int index = Utils.indexOf(entries, summary);
     87         if (index == -1) {
     88             throw new IllegalArgumentException("Illegal Summary");
     89         }
     90         final int lastSelectedOriginalPosition = mAdapter.getLastSelectedOriginalPosition();
     91         mAdapter.setSelectedPosition(index);
     92         setSelectedPosition(entries, lastSelectedOriginalPosition, index);
     93         setSelectedPosition(getEntryValues(), lastSelectedOriginalPosition, index);
     94         super.setSummary(summary);
     95     }
     96 
     97     private final static class SimpleMenuAdapter extends ArrayAdapter<CharSequence> {
     98 
     99         /** The original position of the last selected element */
    100         private int mLastSelectedOriginalPosition = 0;
    101 
    102         SimpleMenuAdapter(Context context, int resource) {
    103             super(context, resource);
    104         }
    105 
    106         private void restoreOriginalOrder() {
    107             final CharSequence item = getItem(0);
    108             remove(item);
    109             insert(item, mLastSelectedOriginalPosition);
    110         }
    111 
    112         private void swapSelectedToFront(int position) {
    113             final CharSequence item = getItem(position);
    114             remove(item);
    115             insert(item, 0);
    116             mLastSelectedOriginalPosition = position;
    117         }
    118 
    119         int getLastSelectedOriginalPosition() {
    120             return mLastSelectedOriginalPosition;
    121         }
    122 
    123         void setSelectedPosition(int position) {
    124             setNotifyOnChange(false);
    125             final CharSequence item = getItem(position);
    126             restoreOriginalOrder();
    127             final int originalPosition = getPosition(item);
    128             swapSelectedToFront(originalPosition);
    129             notifyDataSetChanged();
    130         }
    131 
    132         @Override
    133         public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
    134             final View view = super.getDropDownView(position, convertView, parent);
    135             if (position == 0) {
    136                 view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.white_08p));
    137             } else {
    138                 view.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.transparent));
    139             }
    140             return view;
    141         }
    142     }
    143 }
    144