Add support for automatic focusability determination
New android:focusable attribute value "auto" and corresponding constant
FOCUSABLE_AUTO specifies that the framework can determine a view's
focusability. For now, the only "auto" logic is that focusable = clickable.
This has the effect of making clickable views focusable by default
unless the developer has explicitly set them focusable=false.
Bug: 31963283
Change-Id: Icce768fa701966970ea6b3469b33a4ef97ebc3ea
Test: Added CTS test, related CTS passes, made a test-app which
enumerates all clickable/focusable combinations to verify
This commit is contained in:
@@ -43376,6 +43376,7 @@ package android.view {
|
||||
method public float getElevation();
|
||||
method public boolean getFilterTouchesWhenObscured();
|
||||
method public boolean getFitsSystemWindows();
|
||||
method public int getFocusable();
|
||||
method public java.util.ArrayList<android.view.View> getFocusables(int);
|
||||
method public void getFocusedRect(android.graphics.Rect);
|
||||
method public android.graphics.drawable.Drawable getForeground();
|
||||
@@ -43680,6 +43681,7 @@ package android.view {
|
||||
method public void setFilterTouchesWhenObscured(boolean);
|
||||
method public void setFitsSystemWindows(boolean);
|
||||
method public void setFocusable(boolean);
|
||||
method public void setFocusable(int);
|
||||
method public void setFocusableInTouchMode(boolean);
|
||||
method public void setForeground(android.graphics.drawable.Drawable);
|
||||
method public void setForegroundGravity(int);
|
||||
@@ -43818,8 +43820,10 @@ package android.view {
|
||||
field protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
|
||||
field public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 2; // 0x2
|
||||
field public static final int FIND_VIEWS_WITH_TEXT = 1; // 0x1
|
||||
field public static final int FOCUSABLE = 1; // 0x1
|
||||
field public static final int FOCUSABLES_ALL = 0; // 0x0
|
||||
field public static final int FOCUSABLES_TOUCH_MODE = 1; // 0x1
|
||||
field public static final int FOCUSABLE_AUTO = 16; // 0x10
|
||||
field protected static final int[] FOCUSED_SELECTED_STATE_SET;
|
||||
field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
|
||||
field protected static final int[] FOCUSED_STATE_SET;
|
||||
@@ -43851,6 +43855,7 @@ package android.view {
|
||||
field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
|
||||
field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
|
||||
field public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
|
||||
field public static final int NOT_FOCUSABLE = 0; // 0x0
|
||||
field public static final int NO_ID = -1; // 0xffffffff
|
||||
field public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
|
||||
field public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
|
||||
|
||||
@@ -46600,6 +46600,7 @@ package android.view {
|
||||
method public float getElevation();
|
||||
method public boolean getFilterTouchesWhenObscured();
|
||||
method public boolean getFitsSystemWindows();
|
||||
method public int getFocusable();
|
||||
method public java.util.ArrayList<android.view.View> getFocusables(int);
|
||||
method public void getFocusedRect(android.graphics.Rect);
|
||||
method public android.graphics.drawable.Drawable getForeground();
|
||||
@@ -46904,6 +46905,7 @@ package android.view {
|
||||
method public void setFilterTouchesWhenObscured(boolean);
|
||||
method public void setFitsSystemWindows(boolean);
|
||||
method public void setFocusable(boolean);
|
||||
method public void setFocusable(int);
|
||||
method public void setFocusableInTouchMode(boolean);
|
||||
method public void setForeground(android.graphics.drawable.Drawable);
|
||||
method public void setForegroundGravity(int);
|
||||
@@ -47042,8 +47044,10 @@ package android.view {
|
||||
field protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
|
||||
field public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 2; // 0x2
|
||||
field public static final int FIND_VIEWS_WITH_TEXT = 1; // 0x1
|
||||
field public static final int FOCUSABLE = 1; // 0x1
|
||||
field public static final int FOCUSABLES_ALL = 0; // 0x0
|
||||
field public static final int FOCUSABLES_TOUCH_MODE = 1; // 0x1
|
||||
field public static final int FOCUSABLE_AUTO = 16; // 0x10
|
||||
field protected static final int[] FOCUSED_SELECTED_STATE_SET;
|
||||
field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
|
||||
field protected static final int[] FOCUSED_STATE_SET;
|
||||
@@ -47075,6 +47079,7 @@ package android.view {
|
||||
field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
|
||||
field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
|
||||
field public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
|
||||
field public static final int NOT_FOCUSABLE = 0; // 0x0
|
||||
field public static final int NO_ID = -1; // 0xffffffff
|
||||
field public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
|
||||
field public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
|
||||
|
||||
@@ -43665,6 +43665,7 @@ package android.view {
|
||||
method public float getElevation();
|
||||
method public boolean getFilterTouchesWhenObscured();
|
||||
method public boolean getFitsSystemWindows();
|
||||
method public int getFocusable();
|
||||
method public java.util.ArrayList<android.view.View> getFocusables(int);
|
||||
method public void getFocusedRect(android.graphics.Rect);
|
||||
method public android.graphics.drawable.Drawable getForeground();
|
||||
@@ -43970,6 +43971,7 @@ package android.view {
|
||||
method public void setFilterTouchesWhenObscured(boolean);
|
||||
method public void setFitsSystemWindows(boolean);
|
||||
method public void setFocusable(boolean);
|
||||
method public void setFocusable(int);
|
||||
method public void setFocusableInTouchMode(boolean);
|
||||
method public void setForeground(android.graphics.drawable.Drawable);
|
||||
method public void setForegroundGravity(int);
|
||||
@@ -44108,8 +44110,10 @@ package android.view {
|
||||
field protected static final int[] ENABLED_WINDOW_FOCUSED_STATE_SET;
|
||||
field public static final int FIND_VIEWS_WITH_CONTENT_DESCRIPTION = 2; // 0x2
|
||||
field public static final int FIND_VIEWS_WITH_TEXT = 1; // 0x1
|
||||
field public static final int FOCUSABLE = 1; // 0x1
|
||||
field public static final int FOCUSABLES_ALL = 0; // 0x0
|
||||
field public static final int FOCUSABLES_TOUCH_MODE = 1; // 0x1
|
||||
field public static final int FOCUSABLE_AUTO = 16; // 0x10
|
||||
field protected static final int[] FOCUSED_SELECTED_STATE_SET;
|
||||
field protected static final int[] FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
|
||||
field protected static final int[] FOCUSED_STATE_SET;
|
||||
@@ -44141,6 +44145,7 @@ package android.view {
|
||||
field public static final int MEASURED_SIZE_MASK = 16777215; // 0xffffff
|
||||
field public static final int MEASURED_STATE_MASK = -16777216; // 0xff000000
|
||||
field public static final int MEASURED_STATE_TOO_SMALL = 16777216; // 0x1000000
|
||||
field public static final int NOT_FOCUSABLE = 0; // 0x0
|
||||
field public static final int NO_ID = -1; // 0xffffffff
|
||||
field public static final int OVER_SCROLL_ALWAYS = 0; // 0x0
|
||||
field public static final int OVER_SCROLL_IF_CONTENT_SCROLLS = 1; // 0x1
|
||||
|
||||
@@ -857,22 +857,39 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
*/
|
||||
static boolean sCascadedDragDrop;
|
||||
|
||||
/**
|
||||
* This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
|
||||
* calling setFlags.
|
||||
*/
|
||||
private static final int NOT_FOCUSABLE = 0x00000000;
|
||||
/** @hide */
|
||||
@IntDef({NOT_FOCUSABLE, FOCUSABLE, FOCUSABLE_AUTO})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Focusable {}
|
||||
|
||||
/**
|
||||
* This view wants keystrokes. Use with TAKES_FOCUS_MASK when calling
|
||||
* setFlags.
|
||||
* This view does not want keystrokes.
|
||||
* <p>
|
||||
* Use with {@link #setFocusable(int)} and <a href="#attr_android:focusable">{@code
|
||||
* android:focusable}.
|
||||
*/
|
||||
private static final int FOCUSABLE = 0x00000001;
|
||||
public static final int NOT_FOCUSABLE = 0x00000000;
|
||||
|
||||
/**
|
||||
* This view wants keystrokes.
|
||||
* <p>
|
||||
* Use with {@link #setFocusable(int)} and <a href="#attr_android:focusable">{@code
|
||||
* android:focusable}.
|
||||
*/
|
||||
public static final int FOCUSABLE = 0x00000001;
|
||||
|
||||
/**
|
||||
* This view determines focusability automatically. This is the default.
|
||||
* <p>
|
||||
* Use with {@link #setFocusable(int)} and <a href="#attr_android:focusable">{@code
|
||||
* android:focusable}.
|
||||
*/
|
||||
public static final int FOCUSABLE_AUTO = 0x00000010;
|
||||
|
||||
/**
|
||||
* Mask for use with setFlags indicating bits used for focus.
|
||||
*/
|
||||
private static final int FOCUSABLE_MASK = 0x00000001;
|
||||
private static final int FOCUSABLE_MASK = 0x00000011;
|
||||
|
||||
/**
|
||||
* This view will adjust its padding to fit sytem windows (e.g. status bar)
|
||||
@@ -4160,7 +4177,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
public View(Context context) {
|
||||
mContext = context;
|
||||
mResources = context != null ? context.getResources() : null;
|
||||
mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
|
||||
mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED | FOCUSABLE_AUTO;
|
||||
// Set some flags defaults
|
||||
mPrivateFlags2 =
|
||||
(LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
|
||||
@@ -4346,6 +4363,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
|
||||
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
|
||||
|
||||
// Set default values.
|
||||
viewFlagValues |= FOCUSABLE_AUTO;
|
||||
viewFlagMasks |= FOCUSABLE_AUTO;
|
||||
|
||||
final int N = a.getIndexCount();
|
||||
for (int i = 0; i < N; i++) {
|
||||
int attr = a.getIndex(i);
|
||||
@@ -4458,8 +4479,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
}
|
||||
break;
|
||||
case com.android.internal.R.styleable.View_focusable:
|
||||
if (a.getBoolean(attr, false)) {
|
||||
viewFlagValues |= FOCUSABLE;
|
||||
viewFlagValues = (viewFlagValues & ~FOCUSABLE_MASK) | getFocusableAttribute(a);
|
||||
if ((viewFlagValues & FOCUSABLE_AUTO) == 0) {
|
||||
viewFlagMasks |= FOCUSABLE_MASK;
|
||||
}
|
||||
break;
|
||||
@@ -5033,7 +5054,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
case GONE: out.append('G'); break;
|
||||
default: out.append('.'); break;
|
||||
}
|
||||
out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
|
||||
out.append((mViewFlags & FOCUSABLE) == FOCUSABLE ? 'F' : '.');
|
||||
out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
|
||||
out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
|
||||
out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
|
||||
@@ -8503,20 +8524,39 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
|
||||
/**
|
||||
* Set whether this view can receive the focus.
|
||||
*
|
||||
* <p>
|
||||
* Setting this to false will also ensure that this view is not focusable
|
||||
* in touch mode.
|
||||
*
|
||||
* @param focusable If true, this view can receive the focus.
|
||||
*
|
||||
* @see #setFocusableInTouchMode(boolean)
|
||||
* @see #setFocusable(int)
|
||||
* @attr ref android.R.styleable#View_focusable
|
||||
*/
|
||||
public void setFocusable(boolean focusable) {
|
||||
if (!focusable) {
|
||||
setFocusable(focusable ? FOCUSABLE : NOT_FOCUSABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this view can receive focus.
|
||||
* <p>
|
||||
* Setting this to {@link #FOCUSABLE_AUTO} tells the framework to determine focusability
|
||||
* automatically based on the view's interactivity. This is the default.
|
||||
* <p>
|
||||
* Setting this to NOT_FOCUSABLE will ensure that this view is also not focusable
|
||||
* in touch mode.
|
||||
*
|
||||
* @param focusable One of {@link #NOT_FOCUSABLE}, {@link #FOCUSABLE},
|
||||
* or {@link #FOCUSABLE_AUTO}.
|
||||
* @see #setFocusableInTouchMode(boolean)
|
||||
* @attr ref android.R.styleable#View_focusable
|
||||
*/
|
||||
public void setFocusable(@Focusable int focusable) {
|
||||
if ((focusable & (FOCUSABLE_AUTO | FOCUSABLE)) == 0) {
|
||||
setFlags(0, FOCUSABLE_IN_TOUCH_MODE);
|
||||
}
|
||||
setFlags(focusable ? FOCUSABLE : NOT_FOCUSABLE, FOCUSABLE_MASK);
|
||||
setFlags(focusable, FOCUSABLE_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -9106,14 +9146,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this View is able to take focus.
|
||||
* Returns whether this View is currently able to take focus.
|
||||
*
|
||||
* @return True if this view can take focus, or false otherwise.
|
||||
* @attr ref android.R.styleable#View_focusable
|
||||
*/
|
||||
@ViewDebug.ExportedProperty(category = "focus")
|
||||
public final boolean isFocusable() {
|
||||
return FOCUSABLE == (mViewFlags & FOCUSABLE_MASK);
|
||||
return FOCUSABLE == (mViewFlags & FOCUSABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the focusable setting for this view.
|
||||
*
|
||||
* @return One of {@link #NOT_FOCUSABLE}, {@link #FOCUSABLE}, or {@link #FOCUSABLE_AUTO}.
|
||||
* @attr ref android.R.styleable#View_focusable
|
||||
*/
|
||||
@ViewDebug.ExportedProperty(mapping = {
|
||||
@ViewDebug.IntToString(from = NOT_FOCUSABLE, to = "NOT_FOCUSABLE"),
|
||||
@ViewDebug.IntToString(from = FOCUSABLE, to = "FOCUSABLE"),
|
||||
@ViewDebug.IntToString(from = FOCUSABLE_AUTO, to = "FOCUSABLE_AUTO")
|
||||
})
|
||||
@Focusable
|
||||
public int getFocusable() {
|
||||
return (mViewFlags & FOCUSABLE_AUTO) > 0 ? FOCUSABLE_AUTO : mViewFlags & FOCUSABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -9653,8 +9708,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
|
||||
private boolean requestFocusNoSearch(int direction, Rect previouslyFocusedRect) {
|
||||
// need to be focusable
|
||||
if ((mViewFlags & FOCUSABLE_MASK) != FOCUSABLE ||
|
||||
(mViewFlags & VISIBILITY_MASK) != VISIBLE) {
|
||||
if ((mViewFlags & FOCUSABLE) != FOCUSABLE
|
||||
|| (mViewFlags & VISIBILITY_MASK) != VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12008,14 +12063,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
}
|
||||
int privateFlags = mPrivateFlags;
|
||||
|
||||
// If focusable is auto, update the FOCUSABLE bit.
|
||||
if (((mViewFlags & FOCUSABLE_AUTO) != 0)
|
||||
&& (changed & (FOCUSABLE_MASK | CLICKABLE | FOCUSABLE_IN_TOUCH_MODE)) != 0) {
|
||||
int newFocus = NOT_FOCUSABLE;
|
||||
if ((mViewFlags & (CLICKABLE | FOCUSABLE_IN_TOUCH_MODE)) != 0) {
|
||||
newFocus = FOCUSABLE;
|
||||
} else {
|
||||
mViewFlags = (mViewFlags & ~FOCUSABLE_IN_TOUCH_MODE);
|
||||
}
|
||||
mViewFlags = (mViewFlags & ~FOCUSABLE) | newFocus;
|
||||
int focusChanged = (old & FOCUSABLE) ^ (newFocus & FOCUSABLE);
|
||||
changed = (changed & ~FOCUSABLE) | focusChanged;
|
||||
}
|
||||
|
||||
/* Check if the FOCUSABLE bit has changed */
|
||||
if (((changed & FOCUSABLE_MASK) != 0) &&
|
||||
((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
|
||||
if (((old & FOCUSABLE_MASK) == FOCUSABLE)
|
||||
if (((changed & FOCUSABLE) != 0) && ((privateFlags & PFLAG_HAS_BOUNDS) != 0)) {
|
||||
if (((old & FOCUSABLE) == FOCUSABLE)
|
||||
&& ((privateFlags & PFLAG_FOCUSED) != 0)) {
|
||||
/* Give up focus if we are no longer focusable */
|
||||
clearFocus();
|
||||
} else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
|
||||
} else if (((old & FOCUSABLE) == NOT_FOCUSABLE)
|
||||
&& ((privateFlags & PFLAG_FOCUSED) == 0)) {
|
||||
/*
|
||||
* Tell the view system that we are now available to take focus
|
||||
@@ -12158,7 +12226,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
}
|
||||
|
||||
if (accessibilityEnabled) {
|
||||
if ((changed & FOCUSABLE_MASK) != 0 || (changed & VISIBILITY_MASK) != 0
|
||||
if ((changed & FOCUSABLE) != 0 || (changed & VISIBILITY_MASK) != 0
|
||||
|| (changed & CLICKABLE) != 0 || (changed & LONG_CLICKABLE) != 0
|
||||
|| (changed & CONTEXT_CLICKABLE) != 0) {
|
||||
if (oldIncludeForAccessibility != includeForAccessibility()) {
|
||||
@@ -18083,7 +18151,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
private static String printFlags(int flags) {
|
||||
String output = "";
|
||||
int numFlags = 0;
|
||||
if ((flags & FOCUSABLE_MASK) == FOCUSABLE) {
|
||||
if ((flags & FOCUSABLE) == FOCUSABLE) {
|
||||
output += "TAKES_FOCUS";
|
||||
numFlags++;
|
||||
}
|
||||
@@ -24704,6 +24772,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
ViewConfiguration.getLongPressTooltipHideTimeout());
|
||||
}
|
||||
|
||||
private int getFocusableAttribute(TypedArray attributes) {
|
||||
TypedValue val = new TypedValue();
|
||||
if (attributes.getValue(com.android.internal.R.styleable.View_focusable, val)) {
|
||||
if (val.type == TypedValue.TYPE_INT_BOOLEAN) {
|
||||
return (val.data == 0 ? NOT_FOCUSABLE : FOCUSABLE);
|
||||
} else {
|
||||
return val.data;
|
||||
}
|
||||
} else {
|
||||
return FOCUSABLE_AUTO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The content view of the tooltip popup currently being shown, or null if the tooltip
|
||||
* is not showing.
|
||||
|
||||
@@ -150,7 +150,11 @@ public class RatingBar extends AbsSeekBar {
|
||||
*/
|
||||
public void setIsIndicator(boolean isIndicator) {
|
||||
mIsUserSeekable = !isIndicator;
|
||||
setFocusable(!isIndicator);
|
||||
if (isIndicator) {
|
||||
setFocusable(FOCUSABLE_AUTO);
|
||||
} else {
|
||||
setFocusable(FOCUSABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -357,9 +357,9 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
|
||||
setInputType(inputType);
|
||||
}
|
||||
|
||||
boolean focusable = true;
|
||||
focusable = a.getBoolean(R.styleable.SearchView_focusable, focusable);
|
||||
setFocusable(focusable);
|
||||
if (getFocusable() == FOCUSABLE_AUTO) {
|
||||
setFocusable(FOCUSABLE);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
|
||||
|
||||
@@ -1492,26 +1492,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
if (hint != null) setHint(hint);
|
||||
|
||||
/*
|
||||
* Views are not normally focusable unless specified to be.
|
||||
* Views are not normally clickable unless specified to be.
|
||||
* However, TextViews that have input or movement methods *are*
|
||||
* focusable by default.
|
||||
* clickable by default. By setting clickable here, we implicitly set focusable as well
|
||||
* if not overridden by the developer.
|
||||
*/
|
||||
a = context.obtainStyledAttributes(
|
||||
attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
|
||||
|
||||
boolean focusable = mMovement != null || getKeyListener() != null;
|
||||
boolean clickable = focusable || isClickable();
|
||||
boolean longClickable = focusable || isLongClickable();
|
||||
boolean canInputOrMove = (mMovement != null || getKeyListener() != null);
|
||||
boolean clickable = canInputOrMove || isClickable();
|
||||
boolean longClickable = canInputOrMove || isLongClickable();
|
||||
|
||||
n = a.getIndexCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
int attr = a.getIndex(i);
|
||||
|
||||
switch (attr) {
|
||||
case com.android.internal.R.styleable.View_focusable:
|
||||
focusable = a.getBoolean(attr, focusable);
|
||||
break;
|
||||
|
||||
case com.android.internal.R.styleable.View_clickable:
|
||||
clickable = a.getBoolean(attr, clickable);
|
||||
break;
|
||||
@@ -1523,7 +1519,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
}
|
||||
a.recycle();
|
||||
|
||||
setFocusable(focusable);
|
||||
setClickable(clickable);
|
||||
setLongClickable(longClickable);
|
||||
|
||||
@@ -1968,11 +1963,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
|
||||
private void fixFocusableAndClickableSettings() {
|
||||
if (mMovement != null || (mEditor != null && mEditor.mKeyListener != null)) {
|
||||
setFocusable(true);
|
||||
setFocusable(FOCUSABLE);
|
||||
setClickable(true);
|
||||
setLongClickable(true);
|
||||
} else {
|
||||
setFocusable(false);
|
||||
setFocusable(FOCUSABLE_AUTO);
|
||||
setClickable(false);
|
||||
setLongClickable(false);
|
||||
}
|
||||
@@ -5936,7 +5931,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
|
||||
mEditor.mTextIsSelectable = selectable;
|
||||
setFocusableInTouchMode(selectable);
|
||||
setFocusable(selectable);
|
||||
setFocusable(FOCUSABLE_AUTO);
|
||||
setClickable(selectable);
|
||||
setLongClickable(selectable);
|
||||
|
||||
|
||||
@@ -2272,13 +2272,16 @@
|
||||
<!-- Sets the padding, in pixels, of the end edge; see {@link android.R.attr#padding}. -->
|
||||
<attr name="paddingEnd" format="dimension" />
|
||||
|
||||
<!-- Boolean that controls whether a view can take focus. By default the user can not
|
||||
move focus to a view; by setting this attribute to true the view is
|
||||
allowed to take focus. This value does not impact the behavior of
|
||||
<!-- Controls whether a view can take focus. By default, this is "auto" which lets the
|
||||
framework determine whether a user can move focus to a view. By setting this attribute
|
||||
to true the view is allowed to take focus. By setting it to "false" the view will not
|
||||
take focus. This value does not impact the behavior of
|
||||
directly calling {@link android.view.View#requestFocus}, which will
|
||||
always request focus regardless of this view. It only impacts where
|
||||
focus navigation will try to move focus. -->
|
||||
<attr name="focusable" format="boolean" />
|
||||
<attr name="focusable" format="boolean|enum">
|
||||
<enum name="auto" value="0x00000010" />
|
||||
</attr>
|
||||
|
||||
<!-- Boolean that controls whether a view can take focus while in touch mode.
|
||||
If this is true for a view, that view can gain focus when clicked on, and can keep
|
||||
@@ -7889,7 +7892,6 @@
|
||||
<attr name="queryBackground" format="reference" />
|
||||
<!-- Background for the section containing the action (e.g. voice search) -->
|
||||
<attr name="submitBackground" format="reference" />
|
||||
<attr name="focusable" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="Switch">
|
||||
|
||||
Reference in New Issue
Block a user