1da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.widget; 279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes/* 479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Copyright (C) 2006 The Android Open Source Project 579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * you may not use this file except in compliance with the License. 879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * You may obtain a copy of the License at 979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 1079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * http://www.apache.org/licenses/LICENSE-2.0 1179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 1279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Unless required by applicable law or agreed to in writing, software 1379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 1479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * See the License for the specific language governing permissions and 1679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * limitations under the License. 1779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 1879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 1979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.content.Context; 2079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.database.DataSetObserver; 2179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.os.Parcelable; 2279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.os.SystemClock; 2379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.util.AttributeSet; 2479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.util.SparseArray; 2579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.ContextMenu; 2679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.ContextMenu.ContextMenuInfo; 2779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.SoundEffectConstants; 2879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.View; 2979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.ViewDebug; 3079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.ViewGroup; 3179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.view.accessibility.AccessibilityEvent; 3279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.Adapter; 3379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.AdapterView; 3479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesimport android.widget.ListView; 3579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 3679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 3779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes/** 3879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * An AdapterView is a view whose children are determined by an {@link android.widget.Adapter}. 3979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 4079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <p> 4179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * See {@link ListView}, {@link android.widget.GridView}, {@link android.widget.Spinner} and 4279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * {@link android.widget.Gallery} for commonly used subclasses of AdapterView. 4379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 4479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <div class="special reference"> 4579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <h3>Developer Guides</h3> 4679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <p>For more information about using AdapterView, read the 4779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <a href="{@docRoot}guide/topics/ui/binding.html">Binding to Data with AdapterView</a> 4879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * developer guide.</p></div> 4979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 5079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesabstract class AdapterViewICS<T extends Adapter> extends ViewGroup { 5179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 5279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 5379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The item view type returned by {@link Adapter#getItemViewType(int)} when 5479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * the adapter does not want the item's view recycled. 5579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 5679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes static final int ITEM_VIEW_TYPE_IGNORE = -1; 5779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 5879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 5979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The item view type returned by {@link Adapter#getItemViewType(int)} when 6079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * the item is a header or footer. 6179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 6279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes static final int ITEM_VIEW_TYPE_HEADER_OR_FOOTER = -2; 6379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 6479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 6579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The position of the first child displayed 6679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 6779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.ExportedProperty(category = "scrolling") 6879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mFirstPosition = 0; 6979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 7079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 7179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The offset in pixels from the top of the AdapterView to the top 7279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * of the view to select during the next layout. 7379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 7479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mSpecificTop; 7579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 7679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 7779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Position from which to start looking for mSyncRowId 7879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 7979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mSyncPosition; 8079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 8179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 8279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Row id to look for when data has changed 8379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 8479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long mSyncRowId = INVALID_ROW_ID; 8579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 8679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 8779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Height of the view when mSyncPosition and mSyncRowId where set 8879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 8979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long mSyncHeight; 9079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 9179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 9279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * True if we need to sync to mSyncRowId 9379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 9479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean mNeedSync = false; 9579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 9679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 9779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Indicates whether to sync based on the selection or position. Possible 9879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * values are {@link #SYNC_SELECTED_POSITION} or 9979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * {@link #SYNC_FIRST_POSITION}. 10079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 10179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mSyncMode; 10279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 10379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 10479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Our height after the last layout 10579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 10679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private int mLayoutHeight; 10779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 10879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 10979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Sync based on the selected child 11079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 11179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes static final int SYNC_SELECTED_POSITION = 0; 11279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 11379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 11479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Sync based on the first child displayed 11579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 11679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes static final int SYNC_FIRST_POSITION = 1; 11779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 11879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 11979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Maximum amount of time to spend in {@link #findSyncPosition()} 12079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 12179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes static final int SYNC_MAX_DURATION_MILLIS = 100; 12279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 12379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 12479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Indicates that this view is currently being laid out. 12579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 12679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean mInLayout = false; 12779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 12879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 12979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The listener that receives notifications when an item is selected. 13079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 13179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes OnItemSelectedListener mOnItemSelectedListener; 13279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 13379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 13479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The listener that receives notifications when an item is clicked. 13579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 13679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes OnItemClickListener mOnItemClickListener; 13779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 13879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 13979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The listener that receives notifications when an item is long clicked. 14079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 14179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes OnItemLongClickListener mOnItemLongClickListener; 14279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 14379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 14479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * True if the data has changed since the last layout 14579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 14679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean mDataChanged; 14779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 14879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 14979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The position within the adapter's data set of the item to select 15079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * during the next layout. 15179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 15279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.ExportedProperty(category = "list") 15379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mNextSelectedPosition = INVALID_POSITION; 15479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 15579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 15679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The item id of the item to select during the next layout. 15779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 15879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long mNextSelectedRowId = INVALID_ROW_ID; 15979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 16079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 16179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The position within the adapter's data set of the currently selected item. 16279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 16379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.ExportedProperty(category = "list") 16479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mSelectedPosition = INVALID_POSITION; 16579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 16679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 16779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The item id of the currently selected item. 16879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 16979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long mSelectedRowId = INVALID_ROW_ID; 17079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 17179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 17279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * View to show if there are no items to show. 17379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 17479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private View mEmptyView; 17579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 17679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 17779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The number of items in the current adapter. 17879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 17979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.ExportedProperty(category = "list") 18079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mItemCount; 18179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 18279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 18379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The number of items in the adapter before a data changed event occurred. 18479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 18579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mOldItemCount; 18679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 18779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 18879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Represents an invalid position. All valid positions are in the range 0 to 1 less than the 18979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * number of items in the current adapter. 19079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 19179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public static final int INVALID_POSITION = -1; 19279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 19379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 19479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Represents an empty or invalid row id 19579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 19679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public static final long INVALID_ROW_ID = Long.MIN_VALUE; 19779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 19879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 19979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The last selected position we used when notifying 20079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 20179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int mOldSelectedPosition = INVALID_POSITION; 20279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 20379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 20479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The id of the last selected position we used when notifying 20579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 20679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long mOldSelectedRowId = INVALID_ROW_ID; 20779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 20879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 20979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Indicates what focusable state is requested when calling setFocusable(). 21079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * In addition to this, this view has other criteria for actually 21179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * determining the focusable state (such as whether its empty or the text 21279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * filter is shown). 21379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 21479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @see #setFocusable(boolean) 21579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @see #checkFocus() 21679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 21779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private boolean mDesiredFocusableState; 21879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private boolean mDesiredFocusableInTouchModeState; 21979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 22079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private SelectionNotifier mSelectionNotifier; 22179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 22279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * When set to true, calls to requestLayout() will not propagate up the parent hierarchy. 22379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This is used to layout the children during a layout pass. 22479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 22579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean mBlockLayoutRequests = false; 22679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 22779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes AdapterViewICS(Context context) { 22879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super(context); 22979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 23079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 23179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes AdapterViewICS(Context context, AttributeSet attrs) { 23279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super(context, attrs); 23379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 23479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 23579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes AdapterViewICS(Context context, AttributeSet attrs, int defStyle) { 23679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super(context, attrs, defStyle); 23779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 23879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 23979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 24079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Interface definition for a callback to be invoked when an item in this 24179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * AdapterView has been clicked. 24279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 24379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public interface OnItemClickListener { 24479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 24579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 24679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Callback method to be invoked when an item in this AdapterView has 24779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * been clicked. 24879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <p> 24979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Implementers can call getItemAtPosition(position) if they need 25079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * to access the data associated with the selected item. 25179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 25279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param parent The AdapterView where the click happened. 25379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param view The view within the AdapterView that was clicked (this 25479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * will be a view provided by the adapter) 25579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position The position of the view in the adapter. 25679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param id The row id of the item that was clicked. 25779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 25879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void onItemClick(AdapterViewICS<?> parent, View view, int position, long id); 25979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 26079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 26179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes class OnItemClickListenerWrapper implements AdapterView.OnItemClickListener { 26279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 26379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private final OnItemClickListener mWrappedListener; 26479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 26579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public OnItemClickListenerWrapper(OnItemClickListener listener) { 26679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mWrappedListener = listener; 26779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 26879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 26979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 27079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 27179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mWrappedListener.onItemClick(AdapterViewICS.this, view, position, id); 27279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 27379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 27479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 27579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 27679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Register a callback to be invoked when an item in this AdapterView has 27779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * been clicked. 27879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 27979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param listener The callback that will be invoked. 28079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 28179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setOnItemClickListener(OnItemClickListener listener) { 28279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOnItemClickListener = listener; 28379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 28479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 28579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 28679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The callback to be invoked with an item in this AdapterView has 28779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * been clicked, or null id no callback has been set. 28879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 28979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public final OnItemClickListener getOnItemClickListener() { 29079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mOnItemClickListener; 29179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 29279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 29379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 29479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Call the OnItemClickListener, if it is defined. 29579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 29679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param view The view within the AdapterView that was clicked. 29779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position The position of the view in the adapter. 29879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param id The row id of the item that was clicked. 29979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return True if there was an assigned OnItemClickListener that was 30079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * called, false otherwise is returned. 30179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 30279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public boolean performItemClick(View view, int position, long id) { 30379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mOnItemClickListener != null) { 30479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes playSoundEffect(SoundEffectConstants.CLICK); 30579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (view != null) { 30679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 30779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 30879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOnItemClickListener.onItemClick(this, view, position, id); 30979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return true; 31079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 31179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 31279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return false; 31379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 31479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 31579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 31679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Interface definition for a callback to be invoked when an item in this 31779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * view has been clicked and held. 31879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 31979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public interface OnItemLongClickListener { 32079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 32179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Callback method to be invoked when an item in this view has been 32279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * clicked and held. 32379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 32479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Implementers can call getItemAtPosition(position) if they need to access 32579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * the data associated with the selected item. 32679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 32779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param parent The AbsListView where the click happened 32879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param view The view within the AbsListView that was clicked 32979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position The position of the view in the list 33079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param id The row id of the item that was clicked 33179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 33279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return true if the callback consumed the long click, false otherwise 33379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 33479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean onItemLongClick(AdapterViewICS<?> parent, View view, int position, long id); 33579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 33679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 33779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 33879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 33979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Register a callback to be invoked when an item in this AdapterView has 34079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * been clicked and held 34179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 34279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param listener The callback that will run 34379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 34479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setOnItemLongClickListener(OnItemLongClickListener listener) { 34579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (!isLongClickable()) { 34679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes setLongClickable(true); 34779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 34879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOnItemLongClickListener = listener; 34979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 35079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 35179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 35279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The callback to be invoked with an item in this AdapterView has 35379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * been clicked and held, or null id no callback as been set. 35479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 35579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public final OnItemLongClickListener getOnItemLongClickListener() { 35679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mOnItemLongClickListener; 35779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 35879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 35979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 36079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Interface definition for a callback to be invoked when 36179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * an item in this view has been selected. 36279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 36379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public interface OnItemSelectedListener { 36479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 36579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * <p>Callback method to be invoked when an item in this view has been 36679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * selected. This callback is invoked only when the newly selected 36779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * position is different from the previously selected position or if 36879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * there was no selected item.</p> 36979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 37079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Impelmenters can call getItemAtPosition(position) if they need to access the 37179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * data associated with the selected item. 37279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 37379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param parent The AdapterView where the selection happened 37479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param view The view within the AdapterView that was clicked 37579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position The position of the view in the adapter 37679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param id The row id of the item that is selected 37779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 37879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void onItemSelected(AdapterViewICS<?> parent, View view, int position, long id); 37979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 38079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 38179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Callback method to be invoked when the selection disappears from this 38279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * view. The selection can disappear for instance when touch is activated 38379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * or when the adapter becomes empty. 38479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 38579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param parent The AdapterView that now contains no selected item. 38679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 38779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void onNothingSelected(AdapterViewICS<?> parent); 38879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 38979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 39079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 39179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 39279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Register a callback to be invoked when an item in this AdapterView has 39379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * been selected. 39479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 39579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param listener The callback that will run 39679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 39779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setOnItemSelectedListener(OnItemSelectedListener listener) { 39879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOnItemSelectedListener = listener; 39979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 40079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 40179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public final OnItemSelectedListener getOnItemSelectedListener() { 40279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mOnItemSelectedListener; 40379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 40479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 40579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 40679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Extra menu information provided to the 40779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu(ContextMenu, View, ContextMenuInfo) } 40879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * callback when a context menu is brought up for this AdapterView. 40979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 41079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 41179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public static class AdapterContextMenuInfo implements ContextMenu.ContextMenuInfo { 41279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 41379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public AdapterContextMenuInfo(View targetView, int position, long id) { 41479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes this.targetView = targetView; 41579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes this.position = position; 41679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes this.id = id; 41779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 41879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 41979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 42079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The child view for which the context menu is being displayed. This 42179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * will be one of the children of this AdapterView. 42279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 42379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public View targetView; 42479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 42579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 42679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The position in the adapter for which the context menu is being 42779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * displayed. 42879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 42979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public int position; 43079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 43179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 43279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * The row id of the item for which the context menu is being displayed. 43379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 43479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public long id; 43579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 43679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 43779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 43879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Returns the adapter currently associated with this widget. 43979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 44079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The adapter used to provide this view's content. 44179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 44279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public abstract T getAdapter(); 44379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 44479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 44579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Sets the adapter that provides the data and the views to represent the data 44679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * in this widget. 44779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 44879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param adapter The adapter to use to create this view's content. 44979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 45079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public abstract void setAdapter(T adapter); 45179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 45279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 45379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 45479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 45579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param child Ignored. 45679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 45779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 45879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 45979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 46079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void addView(View child) { 46179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("addView(View) is not supported in AdapterView"); 46279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 46379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 46479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 46579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 46679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 46779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param child Ignored. 46879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param index Ignored. 46979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 47079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 47179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 47279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 47379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void addView(View child, int index) { 47479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("addView(View, int) is not supported in AdapterView"); 47579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 47679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 47779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 47879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 47979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 48079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param child Ignored. 48179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param params Ignored. 48279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 48379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 48479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 48579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 48679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void addView(View child, LayoutParams params) { 48779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("addView(View, LayoutParams) " 48879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes + "is not supported in AdapterView"); 48979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 49079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 49179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 49279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 49379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 49479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param child Ignored. 49579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param index Ignored. 49679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param params Ignored. 49779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 49879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 49979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 50079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 50179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void addView(View child, int index, LayoutParams params) { 50279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("addView(View, int, LayoutParams) " 50379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes + "is not supported in AdapterView"); 50479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 50579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 50679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 50779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 50879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 50979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param child Ignored. 51079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 51179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 51279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 51379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 51479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void removeView(View child) { 51579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("removeView(View) is not supported in AdapterView"); 51679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 51779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 51879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 51979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 52079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 52179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param index Ignored. 52279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 52379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 52479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 52579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 52679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void removeViewAt(int index) { 52779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("removeViewAt(int) is not supported in AdapterView"); 52879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 52979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 53079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 53179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * This method is not supported and throws an UnsupportedOperationException when called. 53279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 53379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @throws UnsupportedOperationException Every time this method is invoked. 53479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 53579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 53679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void removeAllViews() { 53779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new UnsupportedOperationException("removeAllViews() is not supported in AdapterView"); 53879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 53979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 54079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 54179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 54279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mLayoutHeight = getHeight(); 54379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 54479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 54579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 54679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Return the position of the currently selected item within the adapter's data set 54779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 54879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return int Position (starting at 0), or {@link #INVALID_POSITION} if there is nothing selected. 54979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 55079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.CapturedViewProperty 55179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public int getSelectedItemPosition() { 55279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mNextSelectedPosition; 55379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 55479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 55579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 55679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The id corresponding to the currently selected item, or {@link #INVALID_ROW_ID} 55779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * if nothing is selected. 55879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 55979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.CapturedViewProperty 56079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public long getSelectedItemId() { 56179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mNextSelectedRowId; 56279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 56379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 56479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 56579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The view corresponding to the currently selected item, or null 56679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * if nothing is selected 56779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 56879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public abstract View getSelectedView(); 56979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 57079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 57179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The data corresponding to the currently selected item, or 57279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * null if there is nothing selected. 57379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 57479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public Object getSelectedItem() { 57579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes T adapter = getAdapter(); 57679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int selection = getSelectedItemPosition(); 57779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (adapter != null && adapter.getCount() > 0 && selection >= 0) { 57879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return adapter.getItem(selection); 57979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 58079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return null; 58179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 58279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 58379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 58479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 58579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The number of items owned by the Adapter associated with this 58679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * AdapterView. (This is the number of data items, which may be 58779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * larger than the number of visible views.) 58879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 58979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @ViewDebug.CapturedViewProperty 59079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public int getCount() { 59179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mItemCount; 59279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 59379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 59479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 59579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Get the position within the adapter's data set for the view, where view is a an adapter item 59679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * or a descendant of an adapter item. 59779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 59879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param view an adapter item, or a descendant of an adapter item. This must be visible in this 59979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * AdapterView at the time of the call. 60079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return the position within the adapter's data set of the view, or {@link #INVALID_POSITION} 60179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * if the view does not correspond to a list item (or it is not currently visible). 60279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 60379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public int getPositionForView(View view) { 60479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes View listItem = view; 60579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes try { 60679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes View v; 60779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes while (!(v = (View) listItem.getParent()).equals(this)) { 60879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes listItem = v; 60979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 61079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } catch (ClassCastException e) { 61179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // We made it up to the window without find this list view 61279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return INVALID_POSITION; 61379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 61479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 61579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Search the children for the list item 61679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final int childCount = getChildCount(); 61779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes for (int i = 0; i < childCount; i++) { 61879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (getChildAt(i).equals(listItem)) { 61979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mFirstPosition + i; 62079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 62179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 62279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 62379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Child not found! 62479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return INVALID_POSITION; 62579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 62679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 62779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 62879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Returns the position within the adapter's data set for the first item 62979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * displayed on screen. 63079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 63179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The position within the adapter's data set 63279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 63379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public int getFirstVisiblePosition() { 63479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mFirstPosition; 63579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 63679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 63779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 63879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Returns the position within the adapter's data set for the last item 63979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * displayed on screen. 64079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 64179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The position within the adapter's data set 64279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 64379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public int getLastVisiblePosition() { 64479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mFirstPosition + getChildCount() - 1; 64579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 64679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 64779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 64879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Sets the currently selected item. To support accessibility subclasses that 64979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * override this method must invoke the overriden super method first. 65079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 65179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position Index (starting at 0) of the data item to be selected. 65279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 65379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public abstract void setSelection(int position); 65479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 65579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 65679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Sets the view to show if the adapter is empty 65779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 65879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setEmptyView(View emptyView) { 65979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mEmptyView = emptyView; 66079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 66179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final T adapter = getAdapter(); 66279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final boolean empty = ((adapter == null) || adapter.isEmpty()); 66379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes updateEmptyStatus(empty); 66479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 66579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 66679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 66779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * When the current adapter is empty, the AdapterView can display a special view 66879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * call the empty view. The empty view is used to provide feedback to the user 66979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * that no data is available in this AdapterView. 67079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 67179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The view to show if the adapter is empty. 67279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 67379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public View getEmptyView() { 67479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return mEmptyView; 67579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 67679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 67779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 67879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Indicates whether this view is in filter mode. Filter mode can for instance 67979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * be enabled by a user when typing on the keyboard. 68079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 68179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return True if the view is in filter mode, false otherwise. 68279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 68379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean isInFilterMode() { 68479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return false; 68579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 68679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 68779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 68879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setFocusable(boolean focusable) { 68979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final T adapter = getAdapter(); 69079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final boolean empty = adapter == null || adapter.getCount() == 0; 69179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 69279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mDesiredFocusableState = focusable; 69379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (!focusable) { 69479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mDesiredFocusableInTouchModeState = false; 69579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 69679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 69779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super.setFocusable(focusable && (!empty || isInFilterMode())); 69879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 69979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 70079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 70179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setFocusableInTouchMode(boolean focusable) { 70279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final T adapter = getAdapter(); 70379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final boolean empty = adapter == null || adapter.getCount() == 0; 70479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 70579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mDesiredFocusableInTouchModeState = focusable; 70679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (focusable) { 70779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mDesiredFocusableState = true; 70879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 70979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 71079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super.setFocusableInTouchMode(focusable && (!empty || isInFilterMode())); 71179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 71279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 71379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void checkFocus() { 71479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final T adapter = getAdapter(); 71579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final boolean empty = adapter == null || adapter.getCount() == 0; 71679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final boolean focusable = !empty || isInFilterMode(); 71779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // The order in which we set focusable in touch mode/focusable may matter 71879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // for the client, see View.setFocusableInTouchMode() comments for more 71979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // details 72079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super.setFocusableInTouchMode(focusable && mDesiredFocusableInTouchModeState); 72179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super.setFocusable(focusable && mDesiredFocusableState); 72279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mEmptyView != null) { 72379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes updateEmptyStatus((adapter == null) || adapter.isEmpty()); 72479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 72579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 72679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 72779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 72879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Update the status of the list based on the empty parameter. If empty is true and 72979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * we have an empty view, display it. In all the other cases, make sure that the listview 73079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * is VISIBLE and that the empty view is GONE (if it's not null). 73179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 73279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private void updateEmptyStatus(boolean empty) { 73379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (isInFilterMode()) { 73479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes empty = false; 73579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 73679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 73779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (empty) { 73879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mEmptyView != null) { 73979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mEmptyView.setVisibility(View.VISIBLE); 74079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes setVisibility(View.GONE); 74179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 74279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // If the caller just removed our empty view, make sure the list view is visible 74379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes setVisibility(View.VISIBLE); 74479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 74579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 74679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // We are now GONE, so pending layouts will not be dispatched. 74779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Force one here to make sure that the state of the list matches 74879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // the state of the adapter. 74979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mDataChanged) { 75079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes this.onLayout(false, getLeft(), getTop(), getRight(), getBottom()); 75179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 75279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 75379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mEmptyView != null) mEmptyView.setVisibility(View.GONE); 75479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes setVisibility(View.VISIBLE); 75579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 75679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 75779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 75879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 75979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Gets the data associated with the specified position in the list. 76079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 76179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position Which data to get 76279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The data associated with the specified position in the list 76379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 76479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public Object getItemAtPosition(int position) { 76579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes T adapter = getAdapter(); 76679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return (adapter == null || position < 0) ? null : adapter.getItem(position); 76779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 76879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 76979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public long getItemIdAtPosition(int position) { 77079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes T adapter = getAdapter(); 77179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return (adapter == null || position < 0) ? INVALID_ROW_ID : adapter.getItemId(position); 77279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 77379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 77479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 77579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void setOnClickListener(OnClickListener l) { 77679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes throw new RuntimeException("Don't call setOnClickListener for an AdapterView. " 77779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes + "You probably want setOnItemClickListener instead"); 77879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 77979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 78079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 78179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Override to prevent freezing of any views created by the adapter. 78279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 78379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 78479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) { 78579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes dispatchFreezeSelfOnly(container); 78679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 78779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 78879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 78979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Override to prevent thawing of any views created by the adapter. 79079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 79179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 79279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { 79379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes dispatchThawSelfOnly(container); 79479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 79579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 79679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes class AdapterDataSetObserver extends DataSetObserver { 79779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 79879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private Parcelable mInstanceState = null; 79979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 80079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 80179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void onChanged() { 80279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mDataChanged = true; 80379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOldItemCount = mItemCount; 80479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mItemCount = getAdapter().getCount(); 80579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 80679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Detect the case where a cursor that was previously invalidated has 80779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // been repopulated with new data. 80879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (AdapterViewICS.this.getAdapter().hasStableIds() && mInstanceState != null 80979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes && mOldItemCount == 0 && mItemCount > 0) { 81079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes AdapterViewICS.this.onRestoreInstanceState(mInstanceState); 81179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mInstanceState = null; 81279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 81379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes rememberSyncState(); 81479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 81579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes checkFocus(); 81679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes requestLayout(); 81779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 81879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 81979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 82079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void onInvalidated() { 82179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mDataChanged = true; 82279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 82379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (AdapterViewICS.this.getAdapter().hasStableIds()) { 82479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Remember the current state for the case where our hosting activity is being 82579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // stopped and later restarted 82679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mInstanceState = AdapterViewICS.this.onSaveInstanceState(); 82779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 82879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 82979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Data is invalid so we should reset our state 83079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOldItemCount = mItemCount; 83179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mItemCount = 0; 83279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectedPosition = INVALID_POSITION; 83379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectedRowId = INVALID_ROW_ID; 83479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNextSelectedPosition = INVALID_POSITION; 83579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNextSelectedRowId = INVALID_ROW_ID; 83679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNeedSync = false; 83779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 83879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes checkFocus(); 83979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes requestLayout(); 84079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 84179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 84279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void clearSavedState() { 84379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mInstanceState = null; 84479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 84579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 84679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 84779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 84879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes protected void onDetachedFromWindow() { 84979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes super.onDetachedFromWindow(); 85079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes removeCallbacks(mSelectionNotifier); 85179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 85279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 85379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private class SelectionNotifier implements Runnable { 85479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public void run() { 85579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mDataChanged) { 85679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Data has changed between when this SelectionNotifier 85779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // was posted and now. We need to wait until the AdapterView 85879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // has been synched to the new data. 85979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (getAdapter() != null) { 86079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes post(this); 86179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 86279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 86379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes fireOnSelected(); 86479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 86579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 86679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 86779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 86879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void selectionChanged() { 86979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mOnItemSelectedListener != null) { 87079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mInLayout || mBlockLayoutRequests) { 87179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // If we are in a layout traversal, defer notification 87279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // by posting. This ensures that the view tree is 87379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // in a consistent state and is able to accomodate 87479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // new layout or invalidate requests. 87579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mSelectionNotifier == null) { 87679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectionNotifier = new SelectionNotifier(); 87779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 87879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes post(mSelectionNotifier); 87979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 88079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes fireOnSelected(); 88179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 88279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 88379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 88479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // we fire selection events here not in View 88579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mSelectedPosition != ListView.INVALID_POSITION && isShown() && !isInTouchMode()) { 88679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); 88779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 88879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 88979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 89079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes private void fireOnSelected() { 89179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mOnItemSelectedListener == null) 89279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return; 89379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 89479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int selection = this.getSelectedItemPosition(); 89579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (selection >= 0) { 89679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes View v = getSelectedView(); 89779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOnItemSelectedListener.onItemSelected(this, v, selection, 89879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes getAdapter().getItemId(selection)); 89979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 90079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOnItemSelectedListener.onNothingSelected(this); 90179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 90279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 90379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 90479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 90579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 90679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes View selectedView = getSelectedView(); 90779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (selectedView != null && selectedView.getVisibility() == VISIBLE 90879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes && selectedView.dispatchPopulateAccessibilityEvent(event)) { 90979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return true; 91079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 91179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return false; 91279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 91379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 91479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes @Override 91579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes protected boolean canAnimate() { 91679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return super.canAnimate() && mItemCount > 0; 91779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 91879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 91979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void handleDataChanged() { 92079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes final int count = mItemCount; 92179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean found = false; 92279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 92379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (count > 0) { 92479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 92579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int newPos; 92679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 92779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Find the row we are supposed to sync to 92879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mNeedSync) { 92979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Update this first, since setNextSelectedPositionInt inspects 93079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // it 93179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNeedSync = false; 93279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 93379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // See if we can find a position in the new data with the same 93479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // id as the old selection 93579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes newPos = findSyncPosition(); 93679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (newPos >= 0) { 93779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Verify that new selection is selectable 93879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int selectablePos = lookForSelectablePosition(newPos, true); 93979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (selectablePos == newPos) { 94079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Same row id is selected 94179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes setNextSelectedPositionInt(newPos); 94279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes found = true; 94379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 94479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 94579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 94679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (!found) { 94779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Try to use the same position if we can't find matching data 94879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes newPos = getSelectedItemPosition(); 94979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 95079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Pin position to the available range 95179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (newPos >= count) { 95279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes newPos = count - 1; 95379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 95479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (newPos < 0) { 95579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes newPos = 0; 95679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 95779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 95879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Make sure we select something selectable -- first look down 95979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int selectablePos = lookForSelectablePosition(newPos, true); 96079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (selectablePos < 0) { 96179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Looking down didn't work -- try looking up 96279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes selectablePos = lookForSelectablePosition(newPos, false); 96379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 96479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (selectablePos >= 0) { 96579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes setNextSelectedPositionInt(selectablePos); 96679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes checkSelectionChanged(); 96779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes found = true; 96879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 96979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 97079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 97179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (!found) { 97279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Nothing is selected 97379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectedPosition = INVALID_POSITION; 97479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectedRowId = INVALID_ROW_ID; 97579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNextSelectedPosition = INVALID_POSITION; 97679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNextSelectedRowId = INVALID_ROW_ID; 97779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNeedSync = false; 97879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes checkSelectionChanged(); 97979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 98079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 98179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 98279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void checkSelectionChanged() { 98379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) { 98479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes selectionChanged(); 98579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOldSelectedPosition = mSelectedPosition; 98679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mOldSelectedRowId = mSelectedRowId; 98779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 98879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 98979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 99079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 99179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Searches the adapter for a position matching mSyncRowId. The search starts at mSyncPosition 99279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * and then alternates between moving up and moving down until 1) we find the right position, or 99379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 2) we run out of time, or 3) we have looked at every position 99479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 99579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return Position of the row that matches mSyncRowId, or {@link #INVALID_POSITION} if it can't 99679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * be found 99779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 99879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int findSyncPosition() { 99979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int count = mItemCount; 100079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 100179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (count == 0) { 100279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return INVALID_POSITION; 100379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 100479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 100579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long idToMatch = mSyncRowId; 100679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int seed = mSyncPosition; 100779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 100879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // If there isn't a selection don't hunt for it 100979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (idToMatch == INVALID_ROW_ID) { 101079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return INVALID_POSITION; 101179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 101279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 101379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Pin seed to reasonable values 101479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes seed = Math.max(0, seed); 101579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes seed = Math.min(count - 1, seed); 101679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 101779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long endTime = SystemClock.uptimeMillis() + SYNC_MAX_DURATION_MILLIS; 101879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 101979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes long rowId; 102079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 102179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // first position scanned so far 102279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int first = seed; 102379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 102479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // last position scanned so far 102579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int last = seed; 102679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 102779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // True if we should move down on the next iteration 102879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean next = false; 102979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 103079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // True when we have looked at the first item in the data 103179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean hitFirst; 103279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 103379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // True when we have looked at the last item in the data 103479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes boolean hitLast; 103579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 103679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Get the item ID locally (instead of getItemIdAtPosition), so 103779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // we need the adapter 103879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes T adapter = getAdapter(); 103979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (adapter == null) { 104079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return INVALID_POSITION; 104179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 104279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 104379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes while (SystemClock.uptimeMillis() <= endTime) { 104479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes rowId = adapter.getItemId(seed); 104579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (rowId == idToMatch) { 104679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Found it! 104779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return seed; 104879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 104979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 105079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes hitLast = last == count - 1; 105179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes hitFirst = first == 0; 105279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 105379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (hitLast && hitFirst) { 105479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Looked at everything 105579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes break; 105679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 105779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 105879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (hitFirst || (next && !hitLast)) { 105979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Either we hit the top, or we are trying to move down 106079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes last++; 106179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes seed = last; 106279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Try going up next time 106379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes next = false; 106479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else if (hitLast || (!next && !hitFirst)) { 106579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Either we hit the bottom, or we are trying to move up 106679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes first--; 106779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes seed = first; 106879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Try going down next time 106979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes next = true; 107079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 107179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 107279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 107379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 107479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return INVALID_POSITION; 107579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 107679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 107779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 107879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Find a position that can be selected (i.e., is not a separator). 107979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 108079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position The starting position to look at. 108179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param lookDown Whether to look down for other positions. 108279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @return The next selectable position starting at position and then searching either up or 108379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * down. Returns {@link #INVALID_POSITION} if nothing can be found. 108479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 108579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes int lookForSelectablePosition(int position, boolean lookDown) { 108679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes return position; 108779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 108879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 108979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 109079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Utility to keep mSelectedPosition and mSelectedRowId in sync 109179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position Our current position 109279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 109379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void setSelectedPositionInt(int position) { 109479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectedPosition = position; 109579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSelectedRowId = getItemIdAtPosition(position); 109679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 109779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 109879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 109979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Utility to keep mNextSelectedPosition and mNextSelectedRowId in sync 110079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * @param position Intended value for mSelectedPosition the next time we go 110179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * through layout 110279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 110379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void setNextSelectedPositionInt(int position) { 110479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNextSelectedPosition = position; 110579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNextSelectedRowId = getItemIdAtPosition(position); 110679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // If we are trying to sync to the selection, update that too 110779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mNeedSync && mSyncMode == SYNC_SELECTED_POSITION && position >= 0) { 110879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncPosition = position; 110979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncRowId = mNextSelectedRowId; 111079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 111179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 111279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes 111379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes /** 111479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * Remember enough information to restore the screen state when the data has 111579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * changed. 111679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes * 111779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes */ 111879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes void rememberSyncState() { 111979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (getChildCount() > 0) { 112079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mNeedSync = true; 112179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncHeight = mLayoutHeight; 112279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mSelectedPosition >= 0) { 112379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Sync the selection state 112479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes View v = getChildAt(mSelectedPosition - mFirstPosition); 112579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncRowId = mNextSelectedRowId; 112679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncPosition = mNextSelectedPosition; 112779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (v != null) { 112879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSpecificTop = v.getTop(); 112979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 113079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncMode = SYNC_SELECTED_POSITION; 113179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 113279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes // Sync the based on the offset of the first view 113379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes View v = getChildAt(0); 113479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes T adapter = getAdapter(); 113579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (mFirstPosition >= 0 && mFirstPosition < adapter.getCount()) { 113679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncRowId = adapter.getItemId(mFirstPosition); 113779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } else { 113879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncRowId = NO_ID; 113979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 114079e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncPosition = mFirstPosition; 114179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes if (v != null) { 114279e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSpecificTop = v.getTop(); 114379e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 114479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes mSyncMode = SYNC_FIRST_POSITION; 114579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 114679e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 114779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes } 114879e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes}