FileDocCategorySizeDatePackage
AbsSpinner.javaAPI DocAndroid 5.1 API15593Thu Mar 12 22:22:10 GMT 2015android.widget

AbsSpinner

public abstract class AbsSpinner extends AdapterView
An abstract base class for spinner widgets. SDK users will probably not need to use this class.
attr
ref android.R.styleable#AbsSpinner_entries

Fields Summary
SpinnerAdapter
mAdapter
int
mHeightMeasureSpec
int
mWidthMeasureSpec
int
mSelectionLeftPadding
int
mSelectionTopPadding
int
mSelectionRightPadding
int
mSelectionBottomPadding
final android.graphics.Rect
mSpinnerPadding
final RecycleBin
mRecycler
private android.database.DataSetObserver
mDataSetObserver
private android.graphics.Rect
mTouchFrame
Temporary frame to hold a child View's frame rectangle
Constructors Summary
public AbsSpinner(android.content.Context context)


       
        super(context);
        initAbsSpinner();
    
public AbsSpinner(android.content.Context context, android.util.AttributeSet attrs)

        this(context, attrs, 0);
    
public AbsSpinner(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)

        this(context, attrs, defStyleAttr, 0);
    
public AbsSpinner(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes)

        super(context, attrs, defStyleAttr, defStyleRes);
        initAbsSpinner();

        final TypedArray a = context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.AbsSpinner, defStyleAttr, defStyleRes);

        CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries);
        if (entries != null) {
            ArrayAdapter<CharSequence> adapter =
                    new ArrayAdapter<CharSequence>(context,
                            R.layout.simple_spinner_item, entries);
            adapter.setDropDownViewResource(R.layout.simple_spinner_dropdown_item);
            setAdapter(adapter);
        }

        a.recycle();
    
Methods Summary
protected ViewGroup.LayoutParamsgenerateDefaultLayoutParams()

        return new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
    
public SpinnerAdaptergetAdapter()

        return mAdapter;
    
intgetChildHeight(android.view.View child)

        return child.getMeasuredHeight();
    
intgetChildWidth(android.view.View child)

        return child.getMeasuredWidth();
    
public intgetCount()

        return mItemCount;
    
public android.view.ViewgetSelectedView()

        if (mItemCount > 0 && mSelectedPosition >= 0) {
            return getChildAt(mSelectedPosition - mFirstPosition);
        } else {
            return null;
        }
    
private voidinitAbsSpinner()
Common code for different constructor flavors

        setFocusable(true);
        setWillNotDraw(false);
    
abstract voidlayout(int delta, boolean animate)

public voidonInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent event)

        super.onInitializeAccessibilityEvent(event);
        event.setClassName(AbsSpinner.class.getName());
    
public voidonInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo info)

        super.onInitializeAccessibilityNodeInfo(info);
        info.setClassName(AbsSpinner.class.getName());
    
protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

see
android.view.View#measure(int, int) Figure out the dimensions of this Spinner. The width comes from the widthMeasureSpec as Spinnners can't have their width set to UNSPECIFIED. The height is based on the height of the selected item plus padding.

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize;
        int heightSize;

        mSpinnerPadding.left = mPaddingLeft > mSelectionLeftPadding ? mPaddingLeft
                : mSelectionLeftPadding;
        mSpinnerPadding.top = mPaddingTop > mSelectionTopPadding ? mPaddingTop
                : mSelectionTopPadding;
        mSpinnerPadding.right = mPaddingRight > mSelectionRightPadding ? mPaddingRight
                : mSelectionRightPadding;
        mSpinnerPadding.bottom = mPaddingBottom > mSelectionBottomPadding ? mPaddingBottom
                : mSelectionBottomPadding;

        if (mDataChanged) {
            handleDataChanged();
        }
        
        int preferredHeight = 0;
        int preferredWidth = 0;
        boolean needsMeasuring = true;
        
        int selectedPosition = getSelectedItemPosition();
        if (selectedPosition >= 0 && mAdapter != null && selectedPosition < mAdapter.getCount()) {
            // Try looking in the recycler. (Maybe we were measured once already)
            View view = mRecycler.get(selectedPosition);
            if (view == null) {
                // Make a new one
                view = mAdapter.getView(selectedPosition, null, this);

                if (view.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
                    view.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
                }
            }

            if (view != null) {
                // Put in recycler for re-measuring and/or layout
                mRecycler.put(selectedPosition, view);

                if (view.getLayoutParams() == null) {
                    mBlockLayoutRequests = true;
                    view.setLayoutParams(generateDefaultLayoutParams());
                    mBlockLayoutRequests = false;
                }
                measureChild(view, widthMeasureSpec, heightMeasureSpec);
                
                preferredHeight = getChildHeight(view) + mSpinnerPadding.top + mSpinnerPadding.bottom;
                preferredWidth = getChildWidth(view) + mSpinnerPadding.left + mSpinnerPadding.right;
                
                needsMeasuring = false;
            }
        }
        
        if (needsMeasuring) {
            // No views -- just use padding
            preferredHeight = mSpinnerPadding.top + mSpinnerPadding.bottom;
            if (widthMode == MeasureSpec.UNSPECIFIED) {
                preferredWidth = mSpinnerPadding.left + mSpinnerPadding.right;
            }
        }

        preferredHeight = Math.max(preferredHeight, getSuggestedMinimumHeight());
        preferredWidth = Math.max(preferredWidth, getSuggestedMinimumWidth());

        heightSize = resolveSizeAndState(preferredHeight, heightMeasureSpec, 0);
        widthSize = resolveSizeAndState(preferredWidth, widthMeasureSpec, 0);

        setMeasuredDimension(widthSize, heightSize);
        mHeightMeasureSpec = heightMeasureSpec;
        mWidthMeasureSpec = widthMeasureSpec;
    
public voidonRestoreInstanceState(android.os.Parcelable state)

        SavedState ss = (SavedState) state;
  
        super.onRestoreInstanceState(ss.getSuperState());

        if (ss.selectedId >= 0) {
            mDataChanged = true;
            mNeedSync = true;
            mSyncRowId = ss.selectedId;
            mSyncPosition = ss.position;
            mSyncMode = SYNC_SELECTED_POSITION;
            requestLayout();
        }
    
public android.os.ParcelableonSaveInstanceState()

    

    
       
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);
        ss.selectedId = getSelectedItemId();
        if (ss.selectedId >= 0) {
            ss.position = getSelectedItemPosition();
        } else {
            ss.position = INVALID_POSITION;
        }
        return ss;
    
public intpointToPosition(int x, int y)
Maps a point to a position in the list.

param
x X in local coordinate
param
y Y in local coordinate
return
The position of the item which contains the specified point, or {@link #INVALID_POSITION} if the point does not intersect an item.

        Rect frame = mTouchFrame;
        if (frame == null) {
            mTouchFrame = new Rect();
            frame = mTouchFrame;
        }

        final int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            View child = getChildAt(i);
            if (child.getVisibility() == View.VISIBLE) {
                child.getHitRect(frame);
                if (frame.contains(x, y)) {
                    return mFirstPosition + i;
                }
            }
        } 
        return INVALID_POSITION;
    
voidrecycleAllViews()

        final int childCount = getChildCount();
        final AbsSpinner.RecycleBin recycleBin = mRecycler;
        final int position = mFirstPosition;

        // All views go in recycler
        for (int i = 0; i < childCount; i++) {
            View v = getChildAt(i);
            int index = position + i;
            recycleBin.put(index, v);
        }  
    
public voidrequestLayout()
Override to prevent spamming ourselves with layout requests as we place views

see
android.view.View#requestLayout()

        if (!mBlockLayoutRequests) {
            super.requestLayout();
        }
    
voidresetList()
Clear out all children from the list

        mDataChanged = false;
        mNeedSync = false;
        
        removeAllViewsInLayout();
        mOldSelectedPosition = INVALID_POSITION;
        mOldSelectedRowId = INVALID_ROW_ID;
        
        setSelectedPositionInt(INVALID_POSITION);
        setNextSelectedPositionInt(INVALID_POSITION);
        invalidate();
    
public voidsetAdapter(SpinnerAdapter adapter)
The Adapter is used to provide the data which backs this Spinner. It also provides methods to transform spinner items based on their position relative to the selected item.

param
adapter The SpinnerAdapter to use for this Spinner

        if (null != mAdapter) {
            mAdapter.unregisterDataSetObserver(mDataSetObserver);
            resetList();
        }
        
        mAdapter = adapter;
        
        mOldSelectedPosition = INVALID_POSITION;
        mOldSelectedRowId = INVALID_ROW_ID;
        
        if (mAdapter != null) {
            mOldItemCount = mItemCount;
            mItemCount = mAdapter.getCount();
            checkFocus();

            mDataSetObserver = new AdapterDataSetObserver();
            mAdapter.registerDataSetObserver(mDataSetObserver);

            int position = mItemCount > 0 ? 0 : INVALID_POSITION;

            setSelectedPositionInt(position);
            setNextSelectedPositionInt(position);
            
            if (mItemCount == 0) {
                // Nothing selected
                checkSelectionChanged();
            }
            
        } else {
            checkFocus();            
            resetList();
            // Nothing selected
            checkSelectionChanged();
        }

        requestLayout();
    
public voidsetSelection(int position, boolean animate)
Jump directly to a specific item in the adapter data.

        // Animate only if requested position is already on screen somewhere
        boolean shouldAnimate = animate && mFirstPosition <= position &&
                position <= mFirstPosition + getChildCount() - 1;
        setSelectionInt(position, shouldAnimate);
    
public voidsetSelection(int position)

        setNextSelectedPositionInt(position);
        requestLayout();
        invalidate();
    
voidsetSelectionInt(int position, boolean animate)
Makes the item at the supplied position selected.

param
position Position to select
param
animate Should the transition be animated

        if (position != mOldSelectedPosition) {
            mBlockLayoutRequests = true;
            int delta  = position - mSelectedPosition;
            setNextSelectedPositionInt(position);
            layout(delta, animate);
            mBlockLayoutRequests = false;
        }