* file. An item with no state spec is considered to match any set of states and is generally
* useful as a final item to be used as a default.
* <p>
- * If an item with no state spec if placed before other items, those items
+ * If an item with no state spec is placed before other items, those items
* will be ignored.
*
* <a name="ItemAttributes"></a>
}
/**
+ * Return whether the state spec list has at least one item explicitly specifying
+ * {@link android.R.attr#state_focused}.
+ * @hide
+ */
+ public boolean hasFocusStateSpecified() {
+ return StateSet.containsAttribute(mStateSpecs, R.attr.state_focused);
+ }
+
+ /**
* Indicates whether this color state list is opaque, which means that every
* color returned from {@link #getColorForState(int[], int)} has an alpha
* value of 255.
return true;
}
+ /**
+ * Check whether a list of state specs has an attribute specified.
+ * @param stateSpecs a list of state specs we're checking.
+ * @param attr an attribute we're looking for.
+ * @return {@code true} if the attribute is contained in the state specs.
+ * @hide
+ */
+ public static boolean containsAttribute(int[][] stateSpecs, int attr) {
+ if (stateSpecs != null) {
+ for (int[] spec : stateSpecs) {
+ if (spec == null) {
+ break;
+ }
+ for (int specAttr : spec) {
+ if (specAttr == attr || -specAttr == attr) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
public static int[] trimStateSet(int[] states, int newSize) {
if (states.length == newSize) {
return states;
return mLayerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mLayerState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
boolean changed = false;
return isStateful;
}
+ public final boolean hasFocusStateSpecified() {
+ final ChildDrawable[] array = mChildren;
+ for (int i = 0; i < N_CHILDREN; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.hasFocusStateSpecified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public final boolean canConstantState() {
final ChildDrawable[] array = mChildren;
for (int i = 0; i < N_CHILDREN; i++) {
|| super.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mBitmapState.mTint != null && mBitmapState.mTint.hasFocusStateSpecified();
+ }
+
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
return mColorState.mTint != null && mColorState.mTint.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mColorState.mTint != null && mColorState.mTint.hasFocusStateSpecified();
+ }
+
@Override
public int getOpacity() {
if (mTintFilter != null || mPaint.getColorFilter() != null) {
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
}
/**
+ * Indicates whether this drawable has at least one state spec explicitly
+ * specifying {@link android.R.attr#state_focused}.
+ *
+ * <p>Note: A View uses a {@link Drawable} instance as its background and it
+ * changes its appearance based on a state. On keyboard devices, it should
+ * specify its {@link android.R.attr#state_focused} to make sure the user
+ * knows which view is holding the focus.</p>
+ *
+ * @return {@code true} if {@link android.R.attr#state_focused} is specified
+ * for this drawable.
+ *
+ * @hide
+ */
+ @TestApi
+ public boolean hasFocusStateSpecified() {
+ return false;
+ }
+
+ /**
* Specify a set of states for the drawable. These are use-case specific,
* so see the relevant documentation. As an example, the background for
* widgets like Button understand the following states:
return mDrawableContainerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ if (mCurrDrawable != null) {
+ return mCurrDrawable.hasFocusStateSpecified();
+ }
+ if (mLastDrawable != null) {
+ return mLastDrawable.hasFocusStateSpecified();
+ }
+ return false;
+ }
+
@Override
public void setAutoMirrored(boolean mirrored) {
if (mDrawableContainerState.mAutoMirrored != mirrored) {
return mDrawable != null && mDrawable.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mDrawable != null && mDrawable.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
if (mDrawable != null && mDrawable.isStateful()) {
|| (s.mTint != null && s.mTint.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ final GradientState s = mGradientState;
+ return (s.mSolidColors != null && s.mSolidColors.hasFocusStateSpecified())
+ || (s.mStrokeColors != null && s.mStrokeColors.hasFocusStateSpecified())
+ || (s.mTint != null && s.mTint.hasFocusStateSpecified());
+ }
+
@Override
public @Config int getChangingConfigurations() {
return super.getChangingConfigurations() | mGradientState.getChangingConfigurations();
return mLayerState.isStateful();
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mLayerState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] state) {
boolean changed = false;
return isStateful;
}
+ public final boolean hasFocusStateSpecified() {
+ final int N = mNumChildren;
+ final ChildDrawable[] array = mChildren;
+ for (int i = 0; i < N; i++) {
+ final Drawable dr = array[i].mDrawable;
+ if (dr != null && dr.hasFocusStateSpecified()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public final boolean canConstantState() {
final ChildDrawable[] array = mChildren;
final int N = mNumChildren;
return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mNinePatchState.mTint != null && mNinePatchState.mTint.hasFocusStateSpecified();
+ }
+
final static class NinePatchState extends ConstantState {
@Config int mChangingConfigurations;
return true;
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return true;
+ }
+
/**
* Sets the ripple color.
*
return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mShapeState.mTint != null && mShapeState.mTint.hasFocusStateSpecified();
+ }
+
/**
* Subclasses override this to parse custom subelements. If you handle it,
* return true, else return <em>super.inflateTag(...)</em>.
return true;
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mStateListState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] stateSet) {
final boolean changed = super.onStateChange(stateSet);
return -1;
}
+ boolean hasFocusStateSpecified() {
+ return StateSet.containsAttribute(mStateSets, R.attr.state_focused);
+ }
+
@Override
public Drawable newDrawable() {
return new StateListDrawable(this, null);
return super.isStateful() || (mVectorState != null && mVectorState.isStateful());
}
+ /** @hide */
+ @Override
+ public boolean hasFocusStateSpecified() {
+ return mVectorState != null && mVectorState.hasFocusStateSpecified();
+ }
+
@Override
protected boolean onStateChange(int[] stateSet) {
boolean changed = false;
|| (mRootGroup != null && mRootGroup.isStateful());
}
+ public boolean hasFocusStateSpecified() {
+ return mTint != null && mTint.hasFocusStateSpecified()
+ || (mRootGroup != null && mRootGroup.hasFocusStateSpecified());
+ }
+
void setViewportSize(float viewportWidth, float viewportHeight) {
mViewportWidth = viewportWidth;
mViewportHeight = viewportHeight;
}
@Override
+ public boolean hasFocusStateSpecified() {
+ boolean result = false;
+
+ final ArrayList<VObject> children = mChildren;
+ for (int i = 0, count = children.size(); i < count; i++) {
+ final VObject child = children.get(i);
+ if (child.isStateful()) {
+ result |= child.hasFocusStateSpecified();
+ }
+ }
+
+ return result;
+ }
+
+ @Override
int getNativeSize() {
// Return the native allocation needed for the subtree.
int size = NATIVE_ALLOCATION_SIZE;
}
@Override
+ public boolean hasFocusStateSpecified() {
+ return false;
+ }
+
+ @Override
int getNativeSize() {
return NATIVE_ALLOCATION_SIZE;
}
}
@Override
+ public boolean hasFocusStateSpecified() {
+ return (mStrokeColors != null && mStrokeColors instanceof ColorStateList &&
+ ((ColorStateList) mStrokeColors).hasFocusStateSpecified()) &&
+ (mFillColors != null && mFillColors instanceof ColorStateList &&
+ ((ColorStateList) mFillColors).hasFocusStateSpecified());
+ }
+
+ @Override
int getNativeSize() {
return NATIVE_ALLOCATION_SIZE;
}
abstract void applyTheme(Theme t);
abstract boolean onStateChange(int[] state);
abstract boolean isStateful();
+ abstract boolean hasFocusStateSpecified();
abstract int getNativeSize();
abstract Property getProperty(String propertyName);
}