1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 package com.android.settings.datausage; 15 16 import android.content.Context; 17 import android.util.Range; 18 19 import com.android.settings.Utils; 20 import com.android.settingslib.widget.SettingsSpinnerAdapter; 21 22 import java.util.List; 23 24 public class CycleAdapter extends SettingsSpinnerAdapter<CycleAdapter.CycleItem> { 25 26 private final SpinnerInterface mSpinner; 27 CycleAdapter(Context context, SpinnerInterface spinner)28 public CycleAdapter(Context context, SpinnerInterface spinner) { 29 super(context); 30 mSpinner = spinner; 31 mSpinner.setAdapter(this); 32 } 33 34 /** 35 * Find position of {@link CycleItem} in this adapter which is nearest 36 * the given {@link CycleItem}. 37 */ findNearestPosition(CycleItem target)38 public int findNearestPosition(CycleItem target) { 39 if (target != null) { 40 final int count = getCount(); 41 for (int i = count - 1; i >= 0; i--) { 42 final CycleItem item = getItem(i); 43 if (item.compareTo(target) >= 0) { 44 return i; 45 } 46 } 47 } 48 return 0; 49 } 50 setInitialCycleList(List<Long> cycles, long selectedCycle)51 void setInitialCycleList(List<Long> cycles, long selectedCycle) { 52 clear(); 53 for (int i = 0; i < cycles.size() - 1; i++) { 54 add(new CycleAdapter.CycleItem(getContext(), cycles.get(i + 1), cycles.get(i))); 55 if (cycles.get(i) == selectedCycle) { 56 mSpinner.setSelection(i); 57 } 58 } 59 } 60 61 /** 62 * Rebuild list based on network data. Always selects the newest item, 63 * updating the inspection range on chartData. 64 */ updateCycleList(List<Range<Long>> cycleData)65 public void updateCycleList(List<Range<Long>> cycleData) { 66 // stash away currently selected cycle to try restoring below 67 final CycleAdapter.CycleItem previousItem = (CycleAdapter.CycleItem) 68 mSpinner.getSelectedItem(); 69 clear(); 70 71 final Context context = getContext(); 72 for (Range<Long> cycle : cycleData) { 73 add(new CycleAdapter.CycleItem(context, cycle.getLower(), cycle.getUpper())); 74 } 75 76 // force pick the current cycle (first item) 77 if (getCount() > 0) { 78 final int position = findNearestPosition(previousItem); 79 mSpinner.setSelection(position); 80 } 81 } 82 83 /** 84 * List item that reflects a specific data usage cycle. 85 */ 86 public static class CycleItem implements Comparable<CycleItem> { 87 public CharSequence label; 88 public long start; 89 public long end; 90 CycleItem(Context context, long start, long end)91 public CycleItem(Context context, long start, long end) { 92 this.label = Utils.formatDateRange(context, start, end); 93 this.start = start; 94 this.end = end; 95 } 96 97 @Override toString()98 public String toString() { 99 return label.toString(); 100 } 101 102 @Override equals(Object o)103 public boolean equals(Object o) { 104 if (o instanceof CycleItem) { 105 final CycleItem another = (CycleItem) o; 106 return start == another.start && end == another.end; 107 } 108 return false; 109 } 110 111 @Override compareTo(CycleItem another)112 public int compareTo(CycleItem another) { 113 return Long.compare(start, another.start); 114 } 115 } 116 117 public interface SpinnerInterface { setAdapter(CycleAdapter cycleAdapter)118 void setAdapter(CycleAdapter cycleAdapter); 119 getSelectedItem()120 Object getSelectedItem(); 121 setSelection(int position)122 void setSelection(int position); 123 } 124 } 125