FileDocCategorySizeDatePackage
InternalSelectionView.javaAPI DocAndroid 5.1 API9119Thu Mar 12 22:22:12 GMT 2015android.util

InternalSelectionView

public class InternalSelectionView extends android.view.View
A view that has a known number of selectable rows, and maintains a notion of which row is selected. The rows take up the entire width of the view. The height of the view is divided evenly among the rows. Note: If the height of the view does not divide exactly to the number of rows, the last row's height is inflated with the remainder. For example, if the view height is 22 and there are two rows, the height of the first row is 10 and the second 22. Notice what this view does to be a good citizen w.r.t its internal selection: 1) calls {@link View#requestRectangleOnScreen} each time the selection changes due to internal navigation. 2) implements {@link View#getFocusedRect} by filling in the rectangle of the currently selected row 3) overrides {@link View#onFocusChanged} and sets selection appropriately according to the previously focused rectangle.

Fields Summary
private android.graphics.Paint
mPainter
private android.graphics.Paint
mTextPaint
private android.graphics.Rect
mTempRect
private int
mNumRows
private int
mSelectedRow
private final int
mEstimatedPixelHeight
private Integer
mDesiredHeight
private String
mLabel
Constructors Summary
public InternalSelectionView(android.content.Context context, int numRows, String label)


           
        super(context);
        mNumRows = numRows;
        mLabel = label;
        init();
    
public InternalSelectionView(android.content.Context context, android.util.AttributeSet attrs)

        super(context, attrs);
        TypedArray a =
                context.obtainStyledAttributes(
                        attrs, R.styleable.SelectableRowView);
        mNumRows = a.getInt(R.styleable.SelectableRowView_numRows, 5);
        init();
    
Methods Summary
voidensureRectVisible()

        getRectForRow(mTempRect, mSelectedRow);
        requestRectangleOnScreen(mTempRect);
    
public voidgetFocusedRect(android.graphics.Rect r)

        getRectForRow(r, mSelectedRow);
    
public java.lang.StringgetLabel()

        return mLabel;
    
public intgetNumRows()

        return mNumRows;
    
public voidgetRectForRow(android.graphics.Rect rect, int row)

        final int rowHeight = getRowHeight(row);
        final int top = mPaddingTop + row * rowHeight;
        rect.set(mPaddingLeft,
                top,
                getWidth() - mPaddingRight,
                top + rowHeight);
    
private intgetRowHeight(int row)

        final int availableHeight = getHeight() - mPaddingTop - mPaddingBottom;
        final int desiredRowHeight = availableHeight / mNumRows;
        if (row < mNumRows - 1) {
            return desiredRowHeight;
        } else {
            final int residualHeight = availableHeight % mNumRows;
            return desiredRowHeight + residualHeight;
        }
    
public intgetSelectedRow()

        return mSelectedRow;
    
private voidinit()

        setFocusable(true);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(10);
        mTextPaint.setColor(Color.WHITE);
    
private intmeasureHeight(int measureSpec)

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        int desiredHeight = mDesiredHeight != null ?
                mDesiredHeight :
                mNumRows * mEstimatedPixelHeight + mPaddingTop + mPaddingBottom;
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            return specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            return desiredHeight < specSize ? desiredHeight : specSize;
        } else {
            return desiredHeight;
        }
    
private intmeasureWidth(int measureSpec)

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        int desiredWidth = 300 + mPaddingLeft + mPaddingRight;
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            return specSize;
        } else if (specMode == MeasureSpec.AT_MOST) {
            return desiredWidth < specSize ? desiredWidth : specSize;
        } else {
            return desiredWidth;
        }
    
protected voidonDraw(android.graphics.Canvas canvas)

        int rectTop = mPaddingTop;
        int rectLeft = mPaddingLeft;
        int rectRight = getWidth() - mPaddingRight;
        for (int i = 0; i < mNumRows; i++) {

            mPainter.setColor(Color.BLACK);
            mPainter.setAlpha(0x20);

            int rowHeight = getRowHeight(i);

            // draw background rect
            mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight);
            canvas.drawRect(mTempRect, mPainter);

            // draw forground rect
            if (i == mSelectedRow && hasFocus()) {
                mPainter.setColor(Color.RED);
                mPainter.setAlpha(0xF0);
                mTextPaint.setAlpha(0xFF);
            } else {
                mPainter.setColor(Color.BLACK);
                mPainter.setAlpha(0x40);
                mTextPaint.setAlpha(0xF0);
            }
            mTempRect.set(rectLeft + 2, rectTop + 2,
                    rectRight - 2, rectTop + rowHeight - 2);
            canvas.drawRect(mTempRect, mPainter);

            // draw text to help when visually inspecting
            canvas.drawText(
                    Integer.toString(i),
                    rectLeft + 2,
                    rectTop + 2 - (int) mTextPaint.ascent(),
                    mTextPaint);

            rectTop += rowHeight;
        }
    
protected voidonFocusChanged(boolean focused, int direction, android.graphics.Rect previouslyFocusedRect)

        super.onFocusChanged(focused, direction, previouslyFocusedRect);

        if (focused) {
            switch (direction) {
                case View.FOCUS_DOWN:
                    mSelectedRow = 0;
                    break;
                case View.FOCUS_UP:
                    mSelectedRow = mNumRows - 1;
                    break;
                case View.FOCUS_LEFT:  // fall through
                case View.FOCUS_RIGHT:
                    // set the row that is closest to the rect
                    if (previouslyFocusedRect != null) {
                        int y = previouslyFocusedRect.top
                                + (previouslyFocusedRect.height() / 2);
                        int yPerRow = getHeight() / mNumRows;
                        mSelectedRow = y / yPerRow;
                    } else {
                        mSelectedRow = 0;
                    }
                    break;
                default:
                    // can't gleam any useful information about what internal
                    // selection should be...
                    return;
            }
            invalidate();
        }
    
public booleanonKeyDown(int keyCode, android.view.KeyEvent event)

        switch(event.getKeyCode()) {
            case KeyEvent.KEYCODE_DPAD_UP:
                if (mSelectedRow > 0) {
                    mSelectedRow--;
                    invalidate();
                    ensureRectVisible();
                    return true;
                }
                break;
            case KeyEvent.KEYCODE_DPAD_DOWN:
                if (mSelectedRow < (mNumRows - 1)) {
                    mSelectedRow++;
                    invalidate();
                    ensureRectVisible();
                    return true;
                }
                break;
        }
        return false;
    
protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

        setMeasuredDimension(
            measureWidth(widthMeasureSpec),
            measureHeight(heightMeasureSpec));
    
public voidsetDesiredHeight(int desiredHeight)

        mDesiredHeight = desiredHeight;
    
public java.lang.StringtoString()

        if (mLabel != null) {
            return mLabel;
        }
        return super.toString();