List of usage examples for android.content.res ColorStateList getColorForState
public int getColorForState(@Nullable int[] stateSet, int defaultColor)
From source file:com.example.michaelg.myapplication.Item.discreteseekbar.DiscreteSeekBar.java
/** * Sets the color of the seek thumb, as well as the color of the popup indicator. * * @param thumbColorStateList The ColorStateList the seek thumb will be changed to * @param indicatorColor The color the popup indicator will be changed to * The indicator will animate from thumbColorStateList(pressed state) to indicatorColor * when opening *//*from ww w .java 2 s . co m*/ public void setThumbColor(@NonNull ColorStateList thumbColorStateList, int indicatorColor) { mThumb.setColorStateList(thumbColorStateList); //we use the "pressed" color to morph the indicator from it to its own color int thumbColor = thumbColorStateList.getColorForState(new int[] { PRESSED_STATE }, thumbColorStateList.getDefaultColor()); mIndicator.setColors(indicatorColor, thumbColor); }
From source file:android.support.v7ox.widget.AppCompatDrawableManager.java
private ColorStateList createSwitchThumbColorStateList(Context context) { final int[][] states = new int[3][]; final int[] colors = new int[3]; int i = 0;/*from w w w . j a v a 2s. c om*/ final ColorStateList thumbColor = ThemeUtils.getThemeAttrColorStateList(context, R.attr.colorSwitchThumbNormal_ox); if (thumbColor != null && thumbColor.isStateful()) { // If colorSwitchThumbNormal is a valid ColorStateList, extract the default and // disabled colors from it // Disabled state states[i] = ThemeUtils.DISABLED_STATE_SET; colors[i] = thumbColor.getColorForState(states[i], 0); i++; states[i] = ThemeUtils.CHECKED_STATE_SET; colors[i] = ThemeUtils.getThemeAttrColor(context, R.attr.colorControlActivated_ox); i++; // Default enabled state states[i] = ThemeUtils.EMPTY_STATE_SET; colors[i] = thumbColor.getDefaultColor(); i++; } else { // Else we'll use an approximation using the default disabled alpha // Disabled state states[i] = ThemeUtils.DISABLED_STATE_SET; colors[i] = ThemeUtils.getDisabledThemeAttrColor(context, R.attr.colorSwitchThumbNormal_ox); i++; states[i] = ThemeUtils.CHECKED_STATE_SET; colors[i] = ThemeUtils.getThemeAttrColor(context, R.attr.colorControlActivated_ox); i++; // Default enabled state states[i] = ThemeUtils.EMPTY_STATE_SET; colors[i] = ThemeUtils.getThemeAttrColor(context, R.attr.colorSwitchThumbNormal_ox); i++; } return new ColorStateList(states, colors); }
From source file:com.astir_trotter.atcustom.ui.iconics.core.IconicsDrawable.java
/** * Ensures the tint filter is consistent with the current tint color and * mode.//from ww w . j ava 2 s. c o m */ private PorterDuffColorFilter updateTintFilter(ColorStateList tint, PorterDuff.Mode tintMode) { if (tint == null || tintMode == null) { return null; } // setMode, setColor of PorterDuffColorFilter are not public method in SDK v7. (Thanks @Google still not accessible in API v24) // Therefore we create a new one all the time here. Don't expect this is called often. final int color = tint.getColorForState(getState(), Color.TRANSPARENT); return new PorterDuffColorFilter(color, tintMode); }
From source file:org.kde.necessitas.ministro.ExtractStyle.java
JSONObject getColorStateList(ColorStateList colorList) { JSONObject json = new JSONObject(); try {/*from w w w. j a v a2s .c om*/ json.put("EMPTY_STATE_SET", colorList.getColorForState(EMPTY_STATE_SET, 0)); json.put("WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(WINDOW_FOCUSED_STATE_SET, 0)); json.put("SELECTED_STATE_SET", colorList.getColorForState(SELECTED_STATE_SET, 0)); json.put("SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_STATE_SET, 0)); json.put("FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_STATE_SET, 0)); json.put("FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("ENABLED_STATE_SET", colorList.getColorForState(ENABLED_STATE_SET, 0)); json.put("ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("ENABLED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_STATE_SET, 0)); json.put("ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_STATE_SET, 0)); json.put("ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_STATE_SET, 0)); json.put("ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_STATE_SET", colorList.getColorForState(PRESSED_STATE_SET, 0)); json.put("PRESSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_STATE_SET, 0)); json.put("PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_STATE_SET, 0)); json.put("PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_STATE_SET, 0)); json.put("PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_ENABLED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_STATE_SET, 0)); json.put("PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_ENABLED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_STATE_SET, 0)); json.put("PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_ENABLED_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_STATE_SET, 0)); json.put("PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_WINDOW_FOCUSED_STATE_SET, 0)); json.put("PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_STATE_SET, 0)); json.put("PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET", colorList.getColorForState(PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET, 0)); } catch (JSONException e) { e.printStackTrace(); } return json; }
From source file:com.appeaser.sublimepickerlibrary.timepicker.RadialTimePickerView.java
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) { Context context = getContext(); // Pull disabled alpha from theme. final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); mDisabledAlpha = outValue.getFloat(); // process style attributes final Resources res = getResources(); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RadialTimePickerView, defStyleAttr, defStyleRes);//from ww w .j ava 2 s. com mTypeface = Typeface.create("sans-serif", Typeface.NORMAL); // Initialize all alpha values to opaque. for (int i = 0; i < mAlpha.length; i++) { mAlpha[i] = new IntHolder(ALPHA_OPAQUE); } mTextColor[HOURS] = a.getColorStateList(R.styleable.RadialTimePickerView_spNumbersTextColor); mTextColor[HOURS_INNER] = a.getColorStateList(R.styleable.RadialTimePickerView_spNumbersInnerTextColor); mTextColor[MINUTES] = mTextColor[HOURS]; mPaint[HOURS] = new Paint(); mPaint[HOURS].setAntiAlias(true); mPaint[HOURS].setTextAlign(Paint.Align.CENTER); mPaint[MINUTES] = new Paint(); mPaint[MINUTES].setAntiAlias(true); mPaint[MINUTES].setTextAlign(Paint.Align.CENTER); final ColorStateList selectorColors = a .getColorStateList(R.styleable.RadialTimePickerView_spNumbersSelectorColor); int selectorActivatedColor = Color.BLACK; if (selectorColors != null) { selectorActivatedColor = selectorColors .getColorForState(SUtils.resolveStateSet(SUtils.STATE_ENABLED | SUtils.STATE_ACTIVATED), 0); } mPaintCenter.setColor(selectorActivatedColor); mPaintCenter.setAntiAlias(true); final int[] activatedStateSet = SUtils.resolveStateSet(SUtils.STATE_ENABLED | SUtils.STATE_ACTIVATED); mSelectorColor = selectorActivatedColor; mSelectorDotColor = mTextColor[HOURS].getColorForState(activatedStateSet, 0); mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_DOT] = new Paint(); mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_LINE] = new Paint(); mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2); mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint(); mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2); mPaintBackground.setColor(a.getColor(R.styleable.RadialTimePickerView_spNumbersBackgroundColor, ContextCompat.getColor(context, R.color.timepicker_default_numbers_background_color_material))); mPaintBackground.setAntiAlias(true); mSelectorRadius = res.getDimensionPixelSize(R.dimen.sp_timepicker_selector_radius); mSelectorStroke = res.getDimensionPixelSize(R.dimen.sp_timepicker_selector_stroke); mSelectorDotRadius = res.getDimensionPixelSize(R.dimen.sp_timepicker_selector_dot_radius); mCenterDotRadius = res.getDimensionPixelSize(R.dimen.sp_timepicker_center_dot_radius); mTextSize[HOURS] = res.getDimensionPixelSize(R.dimen.sp_timepicker_text_size_normal); mTextSize[MINUTES] = res.getDimensionPixelSize(R.dimen.sp_timepicker_text_size_normal); mTextSize[HOURS_INNER] = res.getDimensionPixelSize(R.dimen.sp_timepicker_text_size_inner); mTextInset[HOURS] = res.getDimensionPixelSize(R.dimen.sp_timepicker_text_inset_normal); mTextInset[MINUTES] = res.getDimensionPixelSize(R.dimen.sp_timepicker_text_inset_normal); mTextInset[HOURS_INNER] = res.getDimensionPixelSize(R.dimen.sp_timepicker_text_inset_inner); mShowHours = true; mIs24HourMode = false; mAmOrPm = AM; // Set up accessibility components. mTouchHelper = new RadialPickerTouchHelper(); ViewCompat.setAccessibilityDelegate(this, mTouchHelper); if (ViewCompat.getImportantForAccessibility(this) == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); } initHoursAndMinutesText(); initData(); a.recycle(); // Initial values final Calendar calendar = Calendar.getInstance(Locale.getDefault()); final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); final int currentMinute = calendar.get(Calendar.MINUTE); setCurrentHourInternal(currentHour, false, false); setCurrentMinuteInternal(currentMinute, false); setHapticFeedbackEnabled(true); }
From source file:com.tr4android.support.extension.picker.time.RadialTimePickerView.java
public RadialTimePickerView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs); // Pull disabled alpha from theme. final TypedValue outValue = new TypedValue(); context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); mDisabledAlpha = outValue.getFloat(); // process style attributes final Resources res = getResources(); final TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TimePickerDialog, defStyleAttr, defStyleRes);//from ww w. j a v a 2 s . c om mTypeface = Typeface.create("sans-serif", Typeface.NORMAL); // Initialize all alpha values to opaque. for (int i = 0; i < mAlpha.length; i++) { mAlpha[i] = new IntHolder(ALPHA_OPAQUE); } mTextColor[HOURS] = a.getColorStateList(R.styleable.TimePickerDialog_numbersTextColor); if (mTextColor[HOURS] == null) { mTextColor[HOURS] = PickerThemeUtils.getTextColorPrimaryActivatedStateList(context); } mTextColor[HOURS_INNER] = a.getColorStateList(R.styleable.TimePickerDialog_numbersInnerTextColor); if (mTextColor[HOURS_INNER] == null) { mTextColor[HOURS_INNER] = PickerThemeUtils.getTextColorSecondaryActivatedStateList(context); } mTextColor[MINUTES] = mTextColor[HOURS]; mPaint[HOURS] = new Paint(); mPaint[HOURS].setAntiAlias(true); mPaint[HOURS].setTextAlign(Paint.Align.CENTER); mPaint[MINUTES] = new Paint(); mPaint[MINUTES].setAntiAlias(true); mPaint[MINUTES].setTextAlign(Paint.Align.CENTER); final int[] selectedStateSet = new int[] { android.R.attr.state_enabled, android.R.attr.state_selected }; // Set up number selected color, if available. final ColorStateList numbersSelectorColor; if (a.hasValue(R.styleable.TimePickerDialog_numbersSelectorColor)) { numbersSelectorColor = a.getColorStateList(R.styleable.TimePickerDialog_numbersSelectorColor); } else { final TypedArray ta = context.obtainStyledAttributes(new int[] { R.attr.colorControlActivated }); numbersSelectorColor = ta.getColorStateList(0); ta.recycle(); } final int selectorActivatedColor = numbersSelectorColor.getColorForState(selectedStateSet, 0); mPaintCenter.setColor(selectorActivatedColor); mPaintCenter.setAntiAlias(true); mSelectorColor = selectorActivatedColor; mSelectorDotColor = mTextColor[HOURS].getColorForState(selectedStateSet, 0); mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_DOT] = new Paint(); mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_LINE] = new Paint(); mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2); mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint(); mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint(); mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true); mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2); mPaintBackground.setColor(a.getColor(R.styleable.TimePickerDialog_numbersBackgroundColor, ContextCompat.getColor(context, android.R.color.transparent))); mPaintBackground.setAntiAlias(true); mSelectorRadius = res.getDimensionPixelSize(R.dimen.timepicker_selector_radius); mSelectorStroke = res.getDimensionPixelSize(R.dimen.timepicker_selector_stroke); mSelectorDotRadius = res.getDimensionPixelSize(R.dimen.timepicker_selector_dot_radius); mCenterDotRadius = res.getDimensionPixelSize(R.dimen.timepicker_center_dot_radius); mTextSize[HOURS] = res.getDimensionPixelSize(R.dimen.timepicker_text_size_normal); mTextSize[MINUTES] = res.getDimensionPixelSize(R.dimen.timepicker_text_size_normal); mTextSize[HOURS_INNER] = res.getDimensionPixelSize(R.dimen.timepicker_text_size_inner); mTextInset[HOURS] = res.getDimensionPixelSize(R.dimen.timepicker_text_inset_normal); mTextInset[MINUTES] = res.getDimensionPixelSize(R.dimen.timepicker_text_inset_normal); mTextInset[HOURS_INNER] = res.getDimensionPixelSize(R.dimen.timepicker_text_inset_inner); mShowHours = true; mIs24HourMode = false; mAmOrPm = AM; // Set up accessibility components. mTouchHelper = new RadialPickerTouchHelper(); ViewCompat.setAccessibilityDelegate(this, mTouchHelper); if (ViewCompat.getImportantForAccessibility(this) == ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_AUTO) { ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); } initHoursAndMinutesText(); initData(); a.recycle(); // Initial values final Calendar calendar = Calendar.getInstance(Locale.getDefault()); final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); final int currentMinute = calendar.get(Calendar.MINUTE); setCurrentHourInternal(currentHour, false, false); setCurrentMinuteInternal(currentMinute, false); setHapticFeedbackEnabled(true); }
From source file:android.support.graphics.drawable.VectorDrawableCompat.java
/** * Ensures the tint filter is consistent with the current tint color and * mode./*from w w w .j a v a 2 s . c o m*/ */ PorterDuffColorFilter updateTintFilter(PorterDuffColorFilter tintFilter, ColorStateList tint, PorterDuff.Mode tintMode) { if (tint == null || tintMode == null) { return null; } // setMode, setColor of PorterDuffColorFilter are not public method in SDK v7. // Therefore we create a new one all the time here. Don't expect this is called often. final int color = tint.getColorForState(getState(), Color.TRANSPARENT); return new PorterDuffColorFilter(color, tintMode); }
From source file:com.appeaser.sublimepickerlibrary.timepicker.RadialTimePickerView.java
/** * Draw the 12 text values at the positions specified by the textGrid parameters. *//* w w w .j a v a2s .c om*/ private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, ColorStateList textColor, String[] texts, float[] textX, float[] textY, Paint paint, int alpha, boolean showActivated, int activatedDegrees, boolean activatedOnly) { paint.setTextSize(textSize); paint.setTypeface(typeface); // The activated index can touch a range of elements. final float activatedIndex = activatedDegrees / (360.0f / NUM_POSITIONS); final int activatedFloor = (int) activatedIndex; final int activatedCeil = ((int) Math.ceil(activatedIndex)) % NUM_POSITIONS; for (int i = 0; i < 12; i++) { final boolean activated = (activatedFloor == i || activatedCeil == i); if (activatedOnly && !activated) { continue; } final int stateMask = SUtils.STATE_ENABLED | (showActivated && activated ? SUtils.STATE_ACTIVATED : 0); final int color = textColor.getColorForState(SUtils.resolveStateSet(stateMask), 0); paint.setColor(color); paint.setAlpha(getMultipliedAlpha(color, alpha)); canvas.drawText(texts[i], textX[i], textY[i], paint); } }
From source file:com.tr4android.support.extension.picker.time.RadialTimePickerView.java
/** * Draw the 12 text values at the positions specified by the textGrid parameters. *//*from w ww .ja va 2 s.com*/ private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, ColorStateList textColor, String[] texts, float[] textX, float[] textY, Paint paint, int alpha, boolean showActivated, int activatedDegrees, boolean activatedOnly) { paint.setTextSize(textSize); paint.setTypeface(typeface); // The activated index can touch a range of elements. final float activatedIndex = activatedDegrees / (360.0f / NUM_POSITIONS); final int activatedFloor = (int) activatedIndex; final int activatedCeil = ((int) Math.ceil(activatedIndex)) % NUM_POSITIONS; for (int i = 0; i < 12; i++) { final boolean activated = (activatedFloor == i || activatedCeil == i); if (activatedOnly && !activated) { continue; } final int[] stateMask = new int[] { android.R.attr.state_enabled, (showActivated && activated ? android.R.attr.state_selected : 0) }; final int color = textColor.getColorForState(stateMask, 0); paint.setColor(color); paint.setAlpha(getMultipliedAlpha(color, alpha)); canvas.drawText(texts[i], textX[i], textY[i], paint); } }
From source file:com.anysoftkeyboard.keyboards.views.AnyKeyboardViewBase.java
@CallSuper protected void onBufferDraw(Canvas canvas, final Paint paint) { if (mKeyboardChanged) { invalidateAllKeys();// w w w . j a v a 2 s . c o m mKeyboardChanged = false; } canvas.getClipBounds(mDirtyRect); if (mKeyboard == null) return; final boolean drawKeyboardNameText = (mKeyboardNameTextSize > 1f) && AnyApplication.getConfig().getShowKeyboardNameText(); final boolean drawHintText = (mHintTextSize > 1) && AnyApplication.getConfig().getShowHintTextOnKeys(); final boolean useCustomKeyTextColor = false; // TODO: final boolean useCustomKeyTextColor = // AnyApplication.getConfig().getUseCustomTextColorOnKeys(); final ColorStateList keyTextColor = useCustomKeyTextColor ? new ColorStateList(new int[][] { { 0 } }, new int[] { 0xFF6666FF }) : mKeyTextColor; final boolean useCustomHintColor = drawHintText && false; // TODO: final boolean useCustomHintColor = drawHintText && final ColorStateList hintColor = useCustomHintColor ? new ColorStateList(new int[][] { { 0 } }, new int[] { 0xFFFF6666 }) : mHintTextColor; // allow preferences to override theme settings for hint text position final boolean useCustomHintAlign = drawHintText && AnyApplication.getConfig().getUseCustomHintAlign(); final int hintAlign = useCustomHintAlign ? AnyApplication.getConfig().getCustomHintAlign() : mHintLabelAlign; final int hintVAlign = useCustomHintAlign ? AnyApplication.getConfig().getCustomHintVAlign() : mHintLabelVAlign; final Drawable keyBackground = mKeyBackground; final Rect clipRegion = mClipRegion; final int kbdPaddingLeft = getPaddingLeft(); final int kbdPaddingTop = getPaddingTop(); final Key[] keys = mKeys; final Key invalidKey = mInvalidatedKey; boolean drawSingleKey = false; if (invalidKey != null && canvas.getClipBounds(clipRegion)) { // TODO we should use Rect.inset and Rect.contains here. // Is clipRegion completely contained within the invalidated key? if (invalidKey.x + kbdPaddingLeft - 1 <= clipRegion.left && invalidKey.y + kbdPaddingTop - 1 <= clipRegion.top && invalidKey.x + invalidKey.width + kbdPaddingLeft + 1 >= clipRegion.right && invalidKey.y + invalidKey.height + kbdPaddingTop + 1 >= clipRegion.bottom) { drawSingleKey = true; } } for (Key keyBase : keys) { final AnyKey key = (AnyKey) keyBase; final boolean keyIsSpace = isSpaceKey(key); if (drawSingleKey && (invalidKey != key)) { continue; } if (!mDirtyRect.intersects(key.x + kbdPaddingLeft, key.y + kbdPaddingTop, key.x + key.width + kbdPaddingLeft, key.y + key.height + kbdPaddingTop)) { continue; } int[] drawableState = key.getCurrentDrawableState(mDrawableStatesProvider); if (keyIsSpace) paint.setColor(mKeyboardNameTextColor); else paint.setColor(keyTextColor.getColorForState(drawableState, 0xFF000000)); keyBackground.setState(drawableState); // Switch the character to uppercase if shift is pressed CharSequence label = key.label == null ? null : adjustLabelToShiftState(key); final Rect bounds = keyBackground.getBounds(); if ((key.width != bounds.right) || (key.height != bounds.bottom)) { keyBackground.setBounds(0, 0, key.width, key.height); } canvas.translate(key.x + kbdPaddingLeft, key.y + kbdPaddingTop); keyBackground.draw(canvas); if (TextUtils.isEmpty(label)) { Drawable iconToDraw = getIconToDrawForKey(key, false); if (iconToDraw != null/* && shouldDrawIcon */) { //http://developer.android.com/reference/android/graphics/drawable/Drawable.html#getCurrent() //http://stackoverflow.com/a/103600/1324235 final boolean is9Patch = iconToDraw.getCurrent() instanceof NinePatchDrawable; // Special handing for the upper-right number hint icons final int drawableWidth; final int drawableHeight; final int drawableX; final int drawableY; drawableWidth = is9Patch ? key.width : iconToDraw.getIntrinsicWidth(); drawableHeight = is9Patch ? key.height : iconToDraw.getIntrinsicHeight(); drawableX = (key.width + mKeyBackgroundPadding.left - mKeyBackgroundPadding.right - drawableWidth) / 2; drawableY = (key.height + mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom - drawableHeight) / 2; canvas.translate(drawableX, drawableY); iconToDraw.setBounds(0, 0, drawableWidth, drawableHeight); iconToDraw.draw(canvas); canvas.translate(-drawableX, -drawableY); if (keyIsSpace && drawKeyboardNameText) { // now a little hack, I'll set the label now, so it get // drawn. label = mKeyboardName; } } else { // ho... no icon. // I'll try to guess the text label = guessLabelForKey(key.getPrimaryCode()); } } if (label != null) { // For characters, use large font. For labels like "Done", use // small font. final FontMetrics fm; if (keyIsSpace) { paint.setTextSize(mKeyboardNameTextSize); paint.setTypeface(Typeface.DEFAULT_BOLD); if (mKeyboardNameFontMetrics == null) mKeyboardNameFontMetrics = paint.getFontMetrics(); fm = mKeyboardNameFontMetrics; } else if (label.length() > 1 && key.getCodesCount() < 2) { setPaintForLabelText(paint); if (mLabelFontMetrics == null) mLabelFontMetrics = paint.getFontMetrics(); fm = mLabelFontMetrics; } else { setPaintToKeyText(paint); if (mTextFontMetrics == null) mTextFontMetrics = paint.getFontMetrics(); fm = mTextFontMetrics; } if (isLabelOfPictographic(label)) { paint.setTextSize(2f * paint.getTextSize()); } final float labelHeight = -fm.top; // Draw a drop shadow for the text paint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mShadowColor); final float textWidth = adjustTextSizeForLabel(paint, label, key.width); // the center of the drawable space, which is value used // previously for vertically // positioning the key label final float centerY = mKeyBackgroundPadding.top + ((key.height - mKeyBackgroundPadding.top - mKeyBackgroundPadding.bottom) / (keyIsSpace ? 3 : 2));// the label on the space is a bit higher // the X coordinate for the center of the main label text is // unaffected by the hints final float textX = mKeyBackgroundPadding.left + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2; final float textY; // Some devices (mostly pre-Honeycomb, have issues with RTL text // drawing. // Of course, there is no issue with a single character :) // so, we'll use the RTL secured drawing (via StaticLayout) for // labels. if (label.length() > 1 && !AnyApplication.getConfig().workaround_alwaysUseDrawText()) { // calculate Y coordinate of top of text based on center // location textY = centerY - ((labelHeight - paint.descent()) / 2); canvas.translate(textX, textY); // RTL fix. But it costs, let do it when in need (more than // 1 character) StaticLayout labelText = new StaticLayout(label, new TextPaint(paint), (int) textWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); labelText.draw(canvas); } else { // to get Y coordinate of baseline from center of text, // first add half the height (to get to // bottom of text), then subtract the part below the // baseline. Note that fm.top is negative. textY = centerY + ((labelHeight - paint.descent()) / 2); canvas.translate(textX, textY); canvas.drawText(label, 0, label.length(), 0, 0, paint); } canvas.translate(-textX, -textY); // (-) // Turn off drop shadow paint.setShadowLayer(0, 0, 0, 0); } if (drawHintText) { if ((key.popupCharacters != null && key.popupCharacters.length() > 0) || (key.popupResId != 0) || (key.longPressCode != 0)) { Align oldAlign = paint.getTextAlign(); String hintText = null; if (key.hintLabel != null && key.hintLabel.length() > 0) { hintText = key.hintLabel.toString(); // it is the responsibility of the keyboard layout // designer to ensure that they do // not put too many characters in the hint label... } else if (key.longPressCode != 0) { if (Character.isLetterOrDigit(key.longPressCode)) hintText = Character.toString((char) key.longPressCode); } else if (key.popupCharacters != null) { final String hintString = key.popupCharacters.toString(); final int hintLength = hintString.length(); if (hintLength <= 3) hintText = hintString; } // if hintText is still null, it means it didn't fit one of // the above // cases, so we should provide the hint using the default if (hintText == null) { if (mHintOverflowLabel != null) hintText = mHintOverflowLabel; else { // theme does not provide a defaultHintLabel // use if hints are above, ... if hints are // below // (to avoid being too close to main label/icon) if (hintVAlign == Gravity.TOP) hintText = ""; else hintText = "..."; } } if (mKeyboard.isShifted()) hintText = hintText.toUpperCase(getKeyboard().getLocale()); // now draw hint paint.setTypeface(Typeface.DEFAULT); paint.setColor(hintColor.getColorForState(drawableState, 0xFF000000)); paint.setTextSize(mHintTextSize); // get the hint text font metrics so that we know the size // of the hint when // we try to position the main label (to try to make sure // they don't overlap) if (mHintTextFontMetrics == null) { mHintTextFontMetrics = paint.getFontMetrics(); } final float hintX; final float hintY; // the (float) 0.5 value is added or subtracted to just give // a little more room // in case the theme designer didn't account for the hint // label location if (hintAlign == Gravity.START) { // left paint.setTextAlign(Align.LEFT); hintX = mKeyBackgroundPadding.left + 0.5f; } else if (hintAlign == Gravity.CENTER) { // center paint.setTextAlign(Align.CENTER); hintX = mKeyBackgroundPadding.left + (key.width - mKeyBackgroundPadding.left - mKeyBackgroundPadding.right) / 2; } else { // right paint.setTextAlign(Align.RIGHT); hintX = key.width - mKeyBackgroundPadding.right - 0.5f; } if (hintVAlign == Gravity.TOP) { // above hintY = mKeyBackgroundPadding.top - mHintTextFontMetrics.top + 0.5f; } else { // below hintY = key.height - mKeyBackgroundPadding.bottom - mHintTextFontMetrics.bottom - 0.5f; } canvas.drawText(hintText, hintX, hintY, paint); paint.setTextAlign(oldAlign); } } canvas.translate(-key.x - kbdPaddingLeft, -key.y - kbdPaddingTop); } mInvalidatedKey = null; mDirtyRect.setEmpty(); }