zoukankan      html  css  js  c++  java
  • 【Android】AdapterView源码部分解析(二)

    注:AdapterView继承于ViewGroup,所以这里标记为(二)。

    同样官方解释:

    1 An AdapterView is a view whose children are determined by an {@link Adapter}.

    很容易就想到ListView和GridView两个View。类定义如下:

    1 public abstract class AdapterView<T extends Adapter> extends ViewGroup 

    贴一下源码的部分属性,看上去有好多之前不知道的信息:

     1 /**
     2      * The position of the first child displayed
     3      */
     4     @ViewDebug.ExportedProperty
     5     int mFirstPosition = 0;
     6 
     7     /**
     8      * The offset in pixels from the top of the AdapterView to the top
     9      * of the view to select during the next layout.
    10      */
    11     int mSpecificTop;
    12 
    13     /**
    14      * Position from which to start looking for mSyncRowId
    15      */
    16     int mSyncPosition;
    17 
    18     /**
    19      * Row id to look for when data has changed
    20      */
    21     long mSyncRowId = INVALID_ROW_ID;
    22 
    23     /**
    24      * Height of the view when mSyncPosition and mSyncRowId where set
    25      */
    26     long mSyncHeight;
    27 
    28     /**
    29      * True if we need to sync to mSyncRowId
    30      */
    31     boolean mNeedSync = false;
    32 
    33     /**
    34      * Indicates whether to sync based on the selection or position. Possible
    35      * values are {@link #SYNC_SELECTED_POSITION} or
    36      * {@link #SYNC_FIRST_POSITION}.
    37      */
    38     int mSyncMode;
    39 
    40     /**
    41      * Our height after the last layout
    42      */
    43     private int mLayoutHeight;
    44 
    45     /**
    46      * Sync based on the selected child
    47      */
    48     static final int SYNC_SELECTED_POSITION = 0;
    49 
    50     /**
    51      * Sync based on the first child displayed
    52      */
    53     static final int SYNC_FIRST_POSITION = 1;
    54 
    55     /**
    56      * Maximum amount of time to spend in {@link #findSyncPosition()}
    57      */
    58     static final int SYNC_MAX_DURATION_MILLIS = 100;
    59 
    60     /**
    61      * Indicates that this view is currently being laid out.
    62      */
    63     boolean mInLayout = false;
    64 
    65     /**
    66      * The listener that receives notifications when an item is selected.
    67      */
    68     OnItemSelectedListener mOnItemSelectedListener;
    69 
    70     /**
    71      * The listener that receives notifications when an item is clicked.
    72      */
    73     OnItemClickListener mOnItemClickListener;
    74 
    75     /**
    76      * The listener that receives notifications when an item is long clicked.
    77      */
    78     OnItemLongClickListener mOnItemLongClickListener;
    79 
    80     /**
    81      * True if the data has changed since the last layout
    82      */
    83     boolean mDataChanged;

    比如这个:

     1 /**
     2      * The offset in pixels from the top of the AdapterView to the top
     3      * of the view to select during the next layout.
     4      */
     5     int mSpecificTop;
     6 
     7     /**
     8      * Position from which to start looking for mSyncRowId
     9      */
    10     int mSyncPosition;

    还有这个:

    1 /**
    2      * The listener that receives notifications when an item is selected.
    3      */
    4     OnItemSelectedListener mOnItemSelectedListener;

    接口定义如下:

     1     /**
     2      * Interface definition for a callback to be invoked when
     3      * an item in this view has been selected.
     4      */
     5     public interface OnItemSelectedListener {
     6         /**
     7          * Callback method to be invoked when an item in this view has been
     8          * selected.
     9          *
    10          * Impelmenters can call getItemAtPosition(position) if they need to access the
    11          * data associated with the selected item.
    12          *
    13          * @param parent The AdapterView where the selection happened
    14          * @param view The view within the AdapterView that was clicked
    15          * @param position The position of the view in the adapter
    16          * @param id The row id of the item that is selected
    17          */
    18         void onItemSelected(AdapterView<?> parent, View view, int position, long id);
    19 
    20         /**
    21          * Callback method to be invoked when the selection disappears from this
    22          * view. The selection can disappear for instance when touch is activated
    23          * or when the adapter becomes empty.
    24          *
    25          * @param parent The AdapterView that now contains no selected item.
    26          */
    27         void onNothingSelected(AdapterView<?> parent);
    28     }

    重载的时候,当方法不支持的时候,可以选择以下方案:直接抛出异常

     1 /**
     2      * This method is not supported and throws an UnsupportedOperationException when called.
     3      *
     4      * @param child Ignored.
     5      *
     6      * @throws UnsupportedOperationException Every time this method is invoked.
     7      */
     8     @Override
     9     public void addView(View child) {
    10         throw new UnsupportedOperationException("addView(View) is not supported in AdapterView");
    11     }

    看一个方法:

     1 /**
     2      * @return The data corresponding to the currently selected item, or
     3      * null if there is nothing selected.
     4      */
     5     public Object getSelectedItem() {
     6         T adapter = getAdapter();
     7         int selection = getSelectedItemPosition();
     8         if (adapter != null && adapter.getCount() > 0 && selection >= 0) {
     9             return adapter.getItem(selection);
    10         } else {
    11             return null;
    12         }
    13     }

    重载Adapter的时候,经常疑惑getItem这个方法是用来干嘛的,这里有解。

    还有下面这个有意思的方法:

     1 /**
     2      * Sets the view to show if the adapter is empty
     3      */
     4     public void setEmptyView(View emptyView) {
     5         mEmptyView = emptyView;
     6 
     7         final T adapter = getAdapter();
     8         final boolean empty = ((adapter == null) || adapter.isEmpty());
     9         updateEmptyStatus(empty);
    10     }

    当adapter为空的时候显示什么,而不用自己去判断~

    下面这个类乃是数据集监听者,在Adapter里面有一个方法叫做notifyDataSetChanged(),是用来刷新AdapterView的显示数据的,有关么?

    class AdapterDataSetObserver extends DataSetObserver {
    
            private Parcelable mInstanceState = null;
    
            @Override
            public void onChanged() {
                mDataChanged = true;
                mOldItemCount = mItemCount;
                mItemCount = getAdapter().getCount();
    
                // Detect the case where a cursor that was previously invalidated has
                // been repopulated with new data.
                if (AdapterView.this.getAdapter().hasStableIds() && mInstanceState != null
                        && mOldItemCount == 0 && mItemCount > 0) {
                    AdapterView.this.onRestoreInstanceState(mInstanceState);
                    mInstanceState = null;
                } else {
                    rememberSyncState();
                }
                checkFocus();
                requestLayout();
            }
    
            @Override
            public void onInvalidated() {
                mDataChanged = true;
    
                if (AdapterView.this.getAdapter().hasStableIds()) {
                    // Remember the current state for the case where our hosting activity is being
                    // stopped and later restarted
                    mInstanceState = AdapterView.this.onSaveInstanceState();
                }
    
                // Data is invalid so we should reset our state
                mOldItemCount = mItemCount;
                mItemCount = 0;
                mSelectedPosition = INVALID_POSITION;
                mSelectedRowId = INVALID_ROW_ID;
                mNextSelectedPosition = INVALID_POSITION;
                mNextSelectedRowId = INVALID_ROW_ID;
                mNeedSync = false;
                checkSelectionChanged();
    
                checkFocus();
                requestLayout();
            }
    
            public void clearSavedState() {
                mInstanceState = null;
            }
        }

    源码中有一大段是用来控制数据集变化,这里就不具体贴出来的,检几个:

    1  /**
    2      * Remember enough information to restore the screen state when the data has
    3      * changed.
    4      *
    5      */
    6     void rememberSyncState() {}
    1 /**
    2      * Searches the adapter for a position matching mSyncRowId. The search starts at mSyncPosition
    3      * and then alternates between moving up and moving down until 1) we find the right position, or
    4      * 2) we run out of time, or 3) we have looked at every position
    5      *
    6      * @return Position of the row that matches mSyncRowId, or {@link #INVALID_POSITION} if it can't
    7      *         be found
    8      */
    9     int findSyncPosition() {}

    具体用法有时间探讨。我要继续往下走。

  • 相关阅读:
    [NC13331]城市网络
    Codeforces Round #638 (Div. 2)
    牛客练习赛62
    “科大讯飞杯”第18届上海大学程序设计联赛春季赛暨高校网络友谊赛
    Codeforces Round #635 (Div. 2)
    Codeforces Round #631 (Div. 2)
    牛客每日一题
    Codeforces Round #627 (Div. 3)
    MySQL查看建表语句
    Oracle的number数据类型
  • 原文地址:https://www.cnblogs.com/lqminn/p/2874819.html
Copyright © 2011-2022 走看看