1f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo/* 2f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * Copyright (C) 2015 The Android Open Source Project 3f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * 4f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * Licensed under the Apache License, Version 2.0 (the "License"); 5f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * you may not use this file except in compliance with the License. 6f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * You may obtain a copy of the License at 7f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * 8f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * http://www.apache.org/licenses/LICENSE-2.0 9f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * 10f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * Unless required by applicable law or agreed to in writing, software 11f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * distributed under the License is distributed on an "AS IS" BASIS, 12f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * See the License for the specific language governing permissions and 14f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo * limitations under the License. 15f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo */ 16f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 17f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seopackage android.support.v7.app; 18f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 19f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.content.Context; 201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.Bitmap; 211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.Canvas; 221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.Rect; 231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.graphics.drawable.BitmapDrawable; 24f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.support.v7.mediarouter.R; 25f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.util.DisplayMetrics; 26f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.util.TypedValue; 271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.view.View; 28f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seoimport android.view.ViewGroup; 291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.widget.ArrayAdapter; 301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport android.widget.ListView; 311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.HashMap; 331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.HashSet; 341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.List; 351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Choimport java.util.Set; 36f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 37f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seofinal class MediaRouteDialogHelper { 388d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang /** 398d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang * The framework should set the dialog width properly, but somehow it doesn't work, hence 408d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang * duplicating a similar logic here to determine the appropriate dialog width. 418d6734a1a6da41bf7a9fbfda0ab05e1fa5ab84d9Dongwon Kang */ 42f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo public static int getDialogWidth(Context context) { 43f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo DisplayMetrics metrics = context.getResources().getDisplayMetrics(); 44f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo boolean isPortrait = metrics.widthPixels < metrics.heightPixels; 45f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 46f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo TypedValue value = new TypedValue(); 47f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo context.getResources().getValue(isPortrait ? R.dimen.mr_dialog_fixed_width_minor 48f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo : R.dimen.mr_dialog_fixed_width_major, value, true); 49f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo if (value.type == TypedValue.TYPE_DIMENSION) { 50f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) value.getDimension(metrics); 51f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo } else if (value.type == TypedValue.TYPE_FRACTION) { 52f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) value.getFraction(metrics.widthPixels, metrics.widthPixels); 53f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo } 54f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return ViewGroup.LayoutParams.WRAP_CONTENT; 55f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo } 561c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 571c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho /** 581c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * Compares two lists regardless of order. 591c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * 601c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param list1 A list 611c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param list2 A list to be compared with {@code list1} 621c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @return True if two lists have exactly same items regardless of order, false otherwise. 631c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho */ 641c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public static <E> boolean listUnorderedEquals(List<E> list1, List<E> list2) { 651c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashSet<E> set1 = new HashSet<>(list1); 661c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashSet<E> set2 = new HashSet<>(list2); 671c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return set1.equals(set2); 681c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 691c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 701c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho /** 711c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * Compares two lists and returns a set of items which exist 721c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * after-list but before-list, which means newly added items. 731c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * 741c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param before A list 751c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param after A list to be compared with {@code before} 761c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @return A set of items which contains newly added items while 771c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * comparing {@code after} to {@code before}. 781c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho */ 791c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public static <E> Set<E> getItemsAdded(List<E> before, List<E> after) { 801c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashSet<E> set = new HashSet<>(after); 811c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho set.removeAll(before); 821c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return set; 831c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 841c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 851c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho /** 861c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * Compares two lists and returns a set of items which exist 871c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * before-list but after-list, which means removed items. 881c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * 891c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param before A list 901c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param after A list to be compared with {@code before} 911c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @return A set of items which contains removed items while 921c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * comparing {@code after} to {@code before}. 931c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho */ 941c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public static <E> Set<E> getItemsRemoved(List<E> before, List<E> after) { 951c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashSet<E> set = new HashSet<>(before); 961c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho set.removeAll(after); 971c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return set; 981c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 991c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 1001c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho /** 1011c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * Generates an item-Rect map which indicates where member 1021c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * items are located in the given ListView. 1031c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * 1041c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param listView A list view 1051c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param adapter An array adapter which contains an array of items. 1061c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @return A map of items and bounds of their views located in the given list view. 1071c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho */ 1081c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public static <E> HashMap<E, Rect> getItemBoundMap(ListView listView, 1091c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ArrayAdapter<E> adapter) { 1101c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashMap<E, Rect> itemBoundMap = new HashMap<>(); 1111c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int firstVisiblePosition = listView.getFirstVisiblePosition(); 1121c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho for (int i = 0; i < listView.getChildCount(); ++i) { 1131c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int position = firstVisiblePosition + i; 1141c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho E item = adapter.getItem(position); 1151c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho View view = listView.getChildAt(i); 1161c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho itemBoundMap.put(item, 1171c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom())); 1181c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 1191c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return itemBoundMap; 1201c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 1211c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 1221c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho /** 1231c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * Generates an item-BitmapDrawable map which stores snapshots 1241c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * of member items in the given ListView. 1251c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * 1261c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param context A context 1271c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param listView A list view 1281c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @param adapter An array adapter which contains an array of items. 1291c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho * @return A map of items and snapshots of their views in the given list view. 1301c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho */ 1311c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho public static <E> HashMap<E, BitmapDrawable> getItemBitmapMap(Context context, 1321c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho ListView listView, ArrayAdapter<E> adapter) { 1331c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho HashMap<E, BitmapDrawable> itemBitmapMap = new HashMap<>(); 1341c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int firstVisiblePosition = listView.getFirstVisiblePosition(); 1351c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho for (int i = 0; i < listView.getChildCount(); ++i) { 1361c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho int position = firstVisiblePosition + i; 1371c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho E item = adapter.getItem(position); 1381c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho View view = listView.getChildAt(i); 1391c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho itemBitmapMap.put(item, getViewBitmap(context, view)); 1401c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 1411c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return itemBitmapMap; 1421c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 1431c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho 1441c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho private static BitmapDrawable getViewBitmap(Context context, View view) { 1451c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), 1461c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Bitmap.Config.ARGB_8888); 1471c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho Canvas canvas = new Canvas(bitmap); 1481c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho view.draw(canvas); 1491c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho return new BitmapDrawable(context.getResources(), bitmap); 1501c4fce94062e162e579d20134f0bac767bdf0964Donghyun Cho } 151f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo} 152