13f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song/* 23f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * Copyright (C) 2015 The Android Open Source Project 33f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * 43f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * Licensed under the Apache License, Version 2.0 (the "License"); 53f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * you may not use this file except in compliance with the License. 63f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * You may obtain a copy of the License at 73f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * 83f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * http://www.apache.org/licenses/LICENSE-2.0 93f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * 103f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * Unless required by applicable law or agreed to in writing, software 113f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * distributed under the License is distributed on an "AS IS" BASIS, 123f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * See the License for the specific language governing permissions and 143f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * limitations under the License. 153f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song */ 163f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songpackage com.android.launcher3.widget; 173f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 18abef55a1c1f1fda4f42e4b4223534dd21f3dc19fAndrew Sappersteinimport android.content.Context; 190e08f166fafd5e2a0d32e27ea510516e3f762221Sunny Goyalimport android.support.v7.widget.RecyclerView; 203f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport android.support.v7.widget.RecyclerView.Adapter; 213f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport android.util.Log; 223f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport android.view.LayoutInflater; 233f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport android.view.View; 248e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Songimport android.view.View.OnClickListener; 258e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Songimport android.view.View.OnLongClickListener; 263f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport android.view.ViewGroup; 27f52abd7758b8f245522936e941336e574debabf5Sunny Goyal 283f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.R; 293f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport com.android.launcher3.WidgetPreviewLoader; 30d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport com.android.launcher3.compat.AlphabeticIndexCompat; 31d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport com.android.launcher3.model.PackageItemInfo; 324ddc40130aa0460924364eab3557088421eebe0cSunny Goyalimport com.android.launcher3.model.WidgetItem; 33d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport com.android.launcher3.util.LabelComparator; 34d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport com.android.launcher3.util.MultiHashMap; 3526b1746593851e239bfff65ae7a69b809ad87b99Tony Wickhamimport com.android.launcher3.util.PackageUserKey; 36f52abd7758b8f245522936e941336e574debabf5Sunny Goyal 37d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport java.util.ArrayList; 38d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport java.util.Collections; 39d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport java.util.Comparator; 4026b1746593851e239bfff65ae7a69b809ad87b99Tony Wickhamimport java.util.Iterator; 413f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songimport java.util.List; 42d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyalimport java.util.Map; 433f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 443f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song/** 453f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * List view adapter for the widget tray. 463f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * 473f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * <p>Memory vs. Performance: 483f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * The less number of types of views are inserted into a {@link RecyclerView}, the more recycling 493f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * happens and less memory is consumed. {@link #getItemViewType} was not overridden as there is 503f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song * only a single type of view. 513f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song */ 523f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Songpublic class WidgetsListAdapter extends Adapter<WidgetsRowViewHolder> { 533f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 543f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song private static final String TAG = "WidgetsListAdapter"; 55289ec3af9a1cd121a221235e0a27d4455e85efdfHyunyoung Song private static final boolean DEBUG = false; 563f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 5781259cd086f8d7a0451f32d6e09cbda26f85ee38Sunny Goyal private final WidgetPreviewLoader mWidgetPreviewLoader; 5881259cd086f8d7a0451f32d6e09cbda26f85ee38Sunny Goyal private final LayoutInflater mLayoutInflater; 59d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal private final AlphabeticIndexCompat mIndexer; 603f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 618e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song private final OnClickListener mIconClickListener; 628e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song private final OnLongClickListener mIconLongClickListener; 63756cd26592dee6b956becdc24d60995c64de9153Sunny Goyal private final int mIndent; 648e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song private ArrayList<WidgetListRowEntry> mEntries = new ArrayList<>(); 658e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song private final WidgetsDiffReporter mDiffReporter; 668e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song 678e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song public WidgetsListAdapter(Context context, LayoutInflater layoutInflater, 688e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetPreviewLoader widgetPreviewLoader, AlphabeticIndexCompat indexCompat, 698e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song OnClickListener iconClickListener, OnLongClickListener iconLongClickListener, 708e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetsDiffReporter diffReporter) { 718e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song mLayoutInflater = layoutInflater; 728e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song mWidgetPreviewLoader = widgetPreviewLoader; 738e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song mIndexer = indexCompat; 743f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song mIconClickListener = iconClickListener; 753f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song mIconLongClickListener = iconLongClickListener; 76abef55a1c1f1fda4f42e4b4223534dd21f3dc19fAndrew Sapperstein mIndent = context.getResources().getDimensionPixelSize(R.dimen.widget_section_indent); 778e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song mDiffReporter = diffReporter; 783f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 793f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 808e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song public void setNotifyListener() { 818e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song mDiffReporter.setListener(new WidgetsDiffReporter.NotifyListener() { 828e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song @Override 838e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song public void notifyDataSetChanged() { 848e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetsListAdapter.this.notifyDataSetChanged(); 858e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song } 868e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song 878e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song @Override 888e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song public void notifyItemChanged(int index) { 898e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetsListAdapter.this.notifyItemChanged(index); 908e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song } 918e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song 928e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song @Override 938e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song public void notifyItemInserted(int index) { 948e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetsListAdapter.this.notifyItemInserted(index); 958e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song } 968e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song 978e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song @Override 988e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song public void notifyItemRemoved(int index) { 998e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetsListAdapter.this.notifyItemRemoved(index); 1008e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song } 1018e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song }); 1028e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song } 1038e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song 1048e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song /** 1058e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song * Update the widget list. 1068e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song */ 107d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal public void setWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets) { 1088e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song ArrayList<WidgetListRowEntry> tempEntries = new ArrayList<>(); 109d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal 1108e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetItemComparator widgetComparator = new WidgetItemComparator(); 111d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : widgets.entrySet()) { 112d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue()); 113d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal row.titleSectionName = mIndexer.computeSectionName(row.pkgItem.title); 114d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal Collections.sort(row.widgets, widgetComparator); 1158e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song tempEntries.add(row); 116d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal } 1178e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song WidgetListRowEntryComparator rowComparator = new WidgetListRowEntryComparator(); 1188e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song Collections.sort(tempEntries, rowComparator); 1198e5464b544a54813fc2492dd6f916c596effb676Hyunyoung Song mDiffReporter.process(mEntries, tempEntries, rowComparator); 1203f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 1213f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 1223f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song @Override 1233f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song public int getItemCount() { 124d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal return mEntries.size(); 125d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal } 126d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal 127d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal public String getSectionName(int pos) { 128d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal return mEntries.get(pos).titleSectionName; 1293f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 1303f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 13126b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham /** 13226b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham * Copies and returns the widgets associated with the package and user of the ComponentKey. 13326b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham */ 13426b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham public List<WidgetItem> copyWidgetsForPackageUser(PackageUserKey packageUserKey) { 13526b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham for (WidgetListRowEntry entry : mEntries) { 13626b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham if (entry.pkgItem.packageName.equals(packageUserKey.mPackageName)) { 13726b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham ArrayList<WidgetItem> widgets = new ArrayList<>(entry.widgets); 13826b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham // Remove widgets not associated with the correct user. 13926b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham Iterator<WidgetItem> iterator = widgets.iterator(); 14026b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham while (iterator.hasNext()) { 14126b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham if (!iterator.next().user.equals(packageUserKey.mUser)) { 14226b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham iterator.remove(); 14326b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham } 14426b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham } 14526b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham return widgets.isEmpty() ? null : widgets; 14626b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham } 14726b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham } 14826b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham return null; 14926b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham } 15026b1746593851e239bfff65ae7a69b809ad87b99Tony Wickham 1513f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song @Override 1523f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song public void onBindViewHolder(WidgetsRowViewHolder holder, int pos) { 153d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal WidgetListRowEntry entry = mEntries.get(pos); 154d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal List<WidgetItem> infoList = entry.widgets; 1553f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 15681259cd086f8d7a0451f32d6e09cbda26f85ee38Sunny Goyal ViewGroup row = holder.cellContainer; 1573f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song if (DEBUG) { 1583f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song Log.d(TAG, String.format( 1594e8fb91cf19b7d621de8cbed2bde2c8dac734121Hyunyoung Song "onBindViewHolder [pos=%d, widget#=%d, row.getChildCount=%d]", 1604e8fb91cf19b7d621de8cbed2bde2c8dac734121Hyunyoung Song pos, infoList.size(), row.getChildCount())); 1613f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 1623f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 1633f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song // Add more views. 1643f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song // if there are too many, hide them. 165d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal int expectedChildCount = infoList.size() + Math.max(0, infoList.size() - 1); 166d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal int childCount = row.getChildCount(); 167d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal 168d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal if (expectedChildCount > childCount) { 169d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal for (int i = childCount ; i < expectedChildCount; i++) { 170d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal if ((i & 1) == 1) { 171d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal // Add a divider for odd index 172d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal mLayoutInflater.inflate(R.layout.widget_list_divider, row); 173d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal } else { 174d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal // Add cell for even index 175d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal WidgetCell widget = (WidgetCell) mLayoutInflater.inflate( 176d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal R.layout.widget_cell, row, false); 177d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal 178d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal // set up touch. 179d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal widget.setOnClickListener(mIconClickListener); 180d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal widget.setOnLongClickListener(mIconLongClickListener); 181d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal row.addView(widget); 182d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal } 1833f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 184d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal } else if (expectedChildCount < childCount) { 185d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal for (int i = expectedChildCount ; i < childCount; i++) { 1863f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song row.getChildAt(i).setVisibility(View.GONE); 1873f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 1883f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 1893f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 1903f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song // Bind the views in the application info section. 191d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal holder.title.applyFromPackageItemInfo(entry.pkgItem); 1923f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 1933f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song // Bind the view in the widget horizontal tray region. 1943f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song for (int i=0; i < infoList.size(); i++) { 195d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal WidgetCell widget = (WidgetCell) row.getChildAt(2*i); 1964ddc40130aa0460924364eab3557088421eebe0cSunny Goyal widget.applyFromCellItem(infoList.get(i), mWidgetPreviewLoader); 1973f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song widget.ensurePreview(); 1986babf2e27e6260f02751413b8f7a55e46659af27Hyunyoung Song widget.setVisibility(View.VISIBLE); 199d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal 200d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal if (i > 0) { 201d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal row.getChildAt(2*i - 1).setVisibility(View.VISIBLE); 202d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal } 2033f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 2043f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 2053f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 2063f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song @Override 2073f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song public WidgetsRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 2083f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song if (DEBUG) { 209559d90d0dafbac1d97a1e6f18062309831a25d51Hyunyoung Song Log.v(TAG, "\nonCreateViewHolder"); 2103f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 2113f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 2123f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song ViewGroup container = (ViewGroup) mLayoutInflater.inflate( 2133f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song R.layout.widgets_list_row_view, parent, false); 2146fdc2035ea04aefc09d54a1943eef168ca270d6dHyunyoung Song 2156fdc2035ea04aefc09d54a1943eef168ca270d6dHyunyoung Song // if the end padding is 0, then container view (horizontal scroll view) doesn't respect 2166fdc2035ea04aefc09d54a1943eef168ca270d6dHyunyoung Song // the end of the linear layout width + the start padding and doesn't allow scrolling. 217d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal container.findViewById(R.id.widgets_cell_list).setPaddingRelative(mIndent, 0, 1, 0); 2186fdc2035ea04aefc09d54a1943eef168ca270d6dHyunyoung Song 2193f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song return new WidgetsRowViewHolder(container); 2203f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 2213f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song 2223f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song @Override 223f17a1c9ad99d46a65de797422fd439382114b348Hyunyoung Song public void onViewRecycled(WidgetsRowViewHolder holder) { 22481259cd086f8d7a0451f32d6e09cbda26f85ee38Sunny Goyal int total = holder.cellContainer.getChildCount(); 225d5d5e22715c19c361d264693929c15c4325e80faSunny Goyal for (int i = 0; i < total; i+=2) { 22681259cd086f8d7a0451f32d6e09cbda26f85ee38Sunny Goyal WidgetCell widget = (WidgetCell) holder.cellContainer.getChildAt(i); 227559d90d0dafbac1d97a1e6f18062309831a25d51Hyunyoung Song widget.clear(); 228f17a1c9ad99d46a65de797422fd439382114b348Hyunyoung Song } 229f17a1c9ad99d46a65de797422fd439382114b348Hyunyoung Song } 230f17a1c9ad99d46a65de797422fd439382114b348Hyunyoung Song 2312d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung public boolean onFailedToRecycleView(WidgetsRowViewHolder holder) { 2322d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung // If child views are animating, then the RecyclerView may choose not to recycle the view, 2332d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung // causing extraneous onCreateViewHolder() calls. It is safe in this case to continue 2342d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung // recycling this view, and take care in onViewRecycled() to cancel any existing 2352d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung // animations. 2362d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung return true; 2372d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung } 2382d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung 2392d58471e8d3da621e209cec58a43d159778f8a0eWinson Chung @Override 2403f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song public long getItemId(int pos) { 2413f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song return pos; 2423f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song } 243d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal 244d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal /** 245d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal * Comparator for sorting WidgetListRowEntry based on package title 246d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal */ 247d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal public static class WidgetListRowEntryComparator implements Comparator<WidgetListRowEntry> { 248d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal 249d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal private final LabelComparator mComparator = new LabelComparator(); 250d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal 251d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal @Override 252d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal public int compare(WidgetListRowEntry a, WidgetListRowEntry b) { 253d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal return mComparator.compare(a.pkgItem.title.toString(), b.pkgItem.title.toString()); 254d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal } 255d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal } 256d164b7f4abcba6cc965c2264257569f88ad5e4a5Sunny Goyal 2573f471440a8b6b71d4c15501a96befd3b715c9e8fHyunyoung Song} 258