1e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren/* 2e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * Copyright (C) 2012 The Android Open Source Project 3e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * 4e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * Licensed under the Apache License, Version 2.0 (the "License"); 5e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * you may not use this file except in compliance with the License. 6e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * You may obtain a copy of the License at 7e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * 8e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * http://www.apache.org/licenses/LICENSE-2.0 9e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * 10e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * Unless required by applicable law or agreed to in writing, software 11e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * distributed under the License is distributed on an "AS IS" BASIS, 12e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * See the License for the specific language governing permissions and 14e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * limitations under the License. 15e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren */ 16e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenpackage com.android.dreams.phototable; 17e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 18e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.content.Context; 19e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.content.SharedPreferences; 20e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.database.DataSetObserver; 21e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.util.Log; 22e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.view.LayoutInflater; 23e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.view.View; 24e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.view.ViewGroup; 25e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport android.widget.ListAdapter; 2688d80f4471c900628e2cb6eef23029b99af48e09Chris Wrenimport android.widget.TextView; 27e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 28e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport java.util.Arrays; 29e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenimport java.util.List; 30e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 31e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren/** 32e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren * Settings panel for photo flipping dream. 33e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren */ 34e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wrenpublic class SectionedAlbumDataAdapter extends DataSetObserver implements ListAdapter { 35e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private static final String TAG = "SectionedAlbumDataAdapter"; 36b7fe7200dcc6efc90aa5441bb8366d3205452c3eChris Wren private static final boolean DEBUG = false; 37e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 38e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final LayoutInflater mInflater; 39e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final int mLayout; 40e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final AlbumDataAdapter mAlbumData; 41e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private int[] sections; 42e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 43e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public SectionedAlbumDataAdapter(Context context, SharedPreferences settings, 44e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren int headerLayout, int itemLayout, List<PhotoSource.AlbumData> objects) { 45e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mLayout = headerLayout; 46e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 47e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mAlbumData = new AlbumDataAdapter(context, settings, itemLayout, objects); 48e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mAlbumData.sort(new AlbumDataAdapter.AccountComparator()); 49e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren onChanged(); 50e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mAlbumData.registerDataSetObserver(this); 51e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 52e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 532ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren boolean areAllSelected() { 542ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren return mAlbumData != null && mAlbumData.areAllSelected(); 552ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren } 562ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren 572ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren void selectAll(boolean select) { 582ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren if (mAlbumData != null) { 592ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren mAlbumData.selectAll(select); 602ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren } 612ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren } 622ccf92a79a2749a6fdaf5c1242f5d72de48ef111Chris Wren 63e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren // DataSetObserver 64e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 65e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 66e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public void onChanged() { 67e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, "onChanged"); 68e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren int numSections = 0; 69e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren String previous = ""; 70e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, "numAlbums = " + mAlbumData.getCount()); 71e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren for (int i = 0; i < mAlbumData.getCount(); i++) { 72e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren PhotoSource.AlbumData item = mAlbumData.getItem(i); 73e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (previous.isEmpty() || !previous.equals(item.account)) { 74e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, "previous = " + previous +", title = " + item.account); 75e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren previous = item.account; 76e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren numSections++; 77e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 78e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 79e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 80e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, "numSections = " + numSections); 81e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren sections = new int[numSections]; 82e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren numSections = 0; 83e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren previous = ""; 84e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 85e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren for (int i = 0; i < mAlbumData.getCount(); i++) { 86e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren PhotoSource.AlbumData item = mAlbumData.getItem(i); 87e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (previous.isEmpty() || !previous.equals(item.account)) { 88e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren previous = item.account; 89e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren sections[numSections] = i; 90e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren numSections++; 91e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 92e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 93e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 94e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren for (int i = 0; i < sections.length; i++) { 95e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren sections[i] += i; 96e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, i + ": " + sections[i]); 97e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 98e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 99e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 100e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 101e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public void onInvalidated() { 102e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren onChanged(); 103e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 104e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 105e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren // ListAdapter 106e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 107e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 108e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public boolean areAllItemsEnabled() { 109e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.areAllItemsEnabled(); 110e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 111e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 112e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 113e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public boolean isEnabled(int position) { 114e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (isHeader(position)) { 115e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return false; 116e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } else { 117e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.isEnabled(internalPosition(position)); 118e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 119e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 120e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 121e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren // Adapter 122e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 123e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 124e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public int getCount() { 125e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.getCount() + sections.length; 126e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 127e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 128e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 129e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public Object getItem(int position) { 130e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (isHeader(position)) { 131e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.getItem(internalPosition(position+1)).account; 132e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } else { 133e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.getItem(internalPosition(position)); 134e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 135e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 136e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 137e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 138e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public long getItemId(int position) { 139e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return position; 140e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 141e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 142e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 143e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public int getItemViewType(int position) { 144e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (isHeader(position)) { 145e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.getViewTypeCount(); 146e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } else { 147e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.getItemViewType(internalPosition(position)); 148e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 149e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 150e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 151e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 152e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public int getViewTypeCount() { 153e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.getViewTypeCount() + 1; 154e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 155e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 156e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 157e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public boolean hasStableIds() { 158e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.hasStableIds(); 159e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 160e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 161e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 162e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public boolean isEmpty() { 163e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return mAlbumData.isEmpty(); 164e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 165e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 166e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 167e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public void registerDataSetObserver(DataSetObserver observer) { 168e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mAlbumData.registerDataSetObserver(observer); 169e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 170e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 171e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 172e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public void unregisterDataSetObserver(DataSetObserver observer) { 173e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mAlbumData.unregisterDataSetObserver(observer); 174e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 175e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 176e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren @Override 177e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren public View getView (int position, View convertView, ViewGroup parent) { 178e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (isHeader(position)) { 179e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, "header at " + position); 180e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren View item = convertView; 181e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (item == null) { 182e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren item = mInflater.inflate(mLayout, parent, false); 183e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 184e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren View vTextView = item.findViewById(R.id.title); 185e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (vTextView != null && vTextView instanceof TextView) { 186e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren TextView textView = (TextView) vTextView; 187e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren textView.setText((String) getItem(position)); 188e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 189e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return item; 190e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } else { 191e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (DEBUG) Log.i(TAG, "non-header at " + position + 192e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren " fetching " + internalPosition(position)); 193e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren View item = mAlbumData.getView(internalPosition(position), convertView, parent); 194e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return item; 195e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 196e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 197e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 198e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren // internal 199e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 200e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private boolean isHeader(int position) { 201e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return (Arrays.binarySearch(sections, position) >= 0); 202e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 203e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 204e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private int internalPosition(int position) { 205e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren int offset = Arrays.binarySearch(sections, position); 206e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (offset < 0) { 207e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren offset = -(offset + 1); 208e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 209e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return position - offset; 210e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 211e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren} 212