1/* 2 * Copyright (C) 2015 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 17package android.support.v7.app; 18 19import android.content.Context; 20import android.graphics.Bitmap; 21import android.graphics.Canvas; 22import android.graphics.Rect; 23import android.graphics.drawable.BitmapDrawable; 24import android.support.v7.mediarouter.R; 25import android.util.DisplayMetrics; 26import android.util.TypedValue; 27import android.view.View; 28import android.view.ViewGroup; 29import android.widget.ArrayAdapter; 30import android.widget.ListView; 31 32import java.util.HashMap; 33import java.util.HashSet; 34import java.util.List; 35import java.util.Set; 36 37final class MediaRouteDialogHelper { 38 /** 39 * The framework should set the dialog width properly, but somehow it doesn't work, hence 40 * duplicating a similar logic here to determine the appropriate dialog width. 41 */ 42 public static int getDialogWidth(Context context) { 43 DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 44 boolean isPortrait = metrics.widthPixels < metrics.heightPixels; 45 46 TypedValue value = new TypedValue(); 47 context.getResources().getValue(isPortrait ? R.dimen.mr_dialog_fixed_width_minor 48 : R.dimen.mr_dialog_fixed_width_major, value, true); 49 if (value.type == TypedValue.TYPE_DIMENSION) { 50 return (int) value.getDimension(metrics); 51 } else if (value.type == TypedValue.TYPE_FRACTION) { 52 return (int) value.getFraction(metrics.widthPixels, metrics.widthPixels); 53 } 54 return ViewGroup.LayoutParams.WRAP_CONTENT; 55 } 56 57 /** 58 * Compares two lists regardless of order. 59 * 60 * @param list1 A list 61 * @param list2 A list to be compared with {@code list1} 62 * @return True if two lists have exactly same items regardless of order, false otherwise. 63 */ 64 public static <E> boolean listUnorderedEquals(List<E> list1, List<E> list2) { 65 HashSet<E> set1 = new HashSet<>(list1); 66 HashSet<E> set2 = new HashSet<>(list2); 67 return set1.equals(set2); 68 } 69 70 /** 71 * Compares two lists and returns a set of items which exist 72 * after-list but before-list, which means newly added items. 73 * 74 * @param before A list 75 * @param after A list to be compared with {@code before} 76 * @return A set of items which contains newly added items while 77 * comparing {@code after} to {@code before}. 78 */ 79 public static <E> Set<E> getItemsAdded(List<E> before, List<E> after) { 80 HashSet<E> set = new HashSet<>(after); 81 set.removeAll(before); 82 return set; 83 } 84 85 /** 86 * Compares two lists and returns a set of items which exist 87 * before-list but after-list, which means removed items. 88 * 89 * @param before A list 90 * @param after A list to be compared with {@code before} 91 * @return A set of items which contains removed items while 92 * comparing {@code after} to {@code before}. 93 */ 94 public static <E> Set<E> getItemsRemoved(List<E> before, List<E> after) { 95 HashSet<E> set = new HashSet<>(before); 96 set.removeAll(after); 97 return set; 98 } 99 100 /** 101 * Generates an item-Rect map which indicates where member 102 * items are located in the given ListView. 103 * 104 * @param listView A list view 105 * @param adapter An array adapter which contains an array of items. 106 * @return A map of items and bounds of their views located in the given list view. 107 */ 108 public static <E> HashMap<E, Rect> getItemBoundMap(ListView listView, 109 ArrayAdapter<E> adapter) { 110 HashMap<E, Rect> itemBoundMap = new HashMap<>(); 111 int firstVisiblePosition = listView.getFirstVisiblePosition(); 112 for (int i = 0; i < listView.getChildCount(); ++i) { 113 int position = firstVisiblePosition + i; 114 E item = adapter.getItem(position); 115 View view = listView.getChildAt(i); 116 itemBoundMap.put(item, 117 new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); 118 } 119 return itemBoundMap; 120 } 121 122 /** 123 * Generates an item-BitmapDrawable map which stores snapshots 124 * of member items in the given ListView. 125 * 126 * @param context A context 127 * @param listView A list view 128 * @param adapter An array adapter which contains an array of items. 129 * @return A map of items and snapshots of their views in the given list view. 130 */ 131 public static <E> HashMap<E, BitmapDrawable> getItemBitmapMap(Context context, 132 ListView listView, ArrayAdapter<E> adapter) { 133 HashMap<E, BitmapDrawable> itemBitmapMap = new HashMap<>(); 134 int firstVisiblePosition = listView.getFirstVisiblePosition(); 135 for (int i = 0; i < listView.getChildCount(); ++i) { 136 int position = firstVisiblePosition + i; 137 E item = adapter.getItem(position); 138 View view = listView.getChildAt(i); 139 itemBitmapMap.put(item, getViewBitmap(context, view)); 140 } 141 return itemBitmapMap; 142 } 143 144 private static BitmapDrawable getViewBitmap(Context context, View view) { 145 Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), 146 Bitmap.Config.ARGB_8888); 147 Canvas canvas = new Canvas(bitmap); 148 view.draw(canvas); 149 return new BitmapDrawable(context.getResources(), bitmap); 150 } 151} 152