What I'd like to do is change the state (really, the background) of an EditText to reflect validity of its contents. E.g. if the user enters 999 where 999 is contextually invalid, the EditText should have a red border in place of the default orange border, likewise once the text is valid it should have a green border.
Methods I've explored:
Changing the style of the EditText programmatically via something like editor.setStyle(R.styles.SomeID). Seems to be impossible within android.
Adding custom states (state_valid, state_invalid) in R.attr, associating them with red/ green 9-patches, then calling drawable.setState() with one of these states. This worked in the sense that the state could be read back via getState(), but the border did not change colour.
Setting the background resource directly upon detection of (in)validity. This works ok, causing the correct visual effect, but seems a little hokey, and allows only one state (e.g. I have to manually check for whether the EditText is pressed, enabled etc).
Given limited UI real-estate I am hesitant to introduce a separate UI element to visually feedback the text's validity to the user, hence my desire to display it in the EditText itself.
So.. is this something that's even feasible? It seems like a fairly common use case, so has anyone achieved what I'm trying to do in a straightforward and elegant manner?
I would recommend changing the text color to indicate validity, rather than changing the color of the focus ring by any of the techniques you describe (of which only #3 seems practical).
Another possibility is to try setCompoundDrawablesWithIntrinsicBounds() to modify an icon on the left or right side of the EditText contents to indicate validity. I remember discussing this technique with somebody a few months back and forget if they got it working or not.
And, of course, another option is to not allow invalid input, via a custom input filter or listener or something.
Well, I'd just extend the EditText class and build the desired functionality on top ( using the third approach you are suggesting, because it works :-) ). Doing this, you have to walk the way only once, and are open to change your implementation once you know the best way ( I would have personally solved it also using the third approach, seems fine to me ).
i think a call to invalidateDrawable(yourDrawable) would work with approach number 2.
i didn't try .. but it make sense
Related
My Android app contains a custom slider control based on the SeekBar, and I want to attach a custom text phrase to my control to explain its use for Accessibility.
I have done this successfully using View.setContentDescription(text), and TalkBack correctly speaks the phrase when I request focus on my slider control from Activity.onCreate.
So far, so good. However, when I touch the control, which I believe sets the AccessibilityFocus on my Android API 16 test device, extra words are being added to the spoken phrase, i.e. '...seek control. 0 per cent'. I want to remove these additional words.
I have tried to eliminate them using event.getText().clear() in View.onInitializeAccessibilityEvent(event) without success. Echoing the event to LogCat reports the correct phrase in event.contentDescription and no entries in event.text, but the extra words appear both in the audio output from the device hardware and in the on-screen debug text displayed by Menu->Settings->Accessibility->TalkBack->Settings->Developer Settings->Display Speech Output.
Please can anyone suggest where the extra words are being added, and how to eliminate them?
Any constructive suggestions would be welcomed. Thanks.
Update
I can see that some Explore By Touch (initial single-tap) event on my custom control does not pass through either its onInitializeAccessibilityEvent or dispatchPopulateAccessibilityEvent methods as I am deliberately calling event.setContentDescription(null). Despite this, there is an AccessibilityEvent being generated with my custom control's ContentDescription, set in Activity.onCreate in code, plus the extra words I'm trying to eliminate.
I've also set an AccessibilityDelegate on my custom control's parent ViewGroup to give visibility of its onRequestSendAccessibilityEvent calls. This confirms that no event containing my ContentDescription is passing through.
This is very puzzling, and happens on both the emulator and real hardware with API 16. Any ideas?
You also need to override http://developer.android.com/reference/android/view/View.html#onInitializeAccessibilityNodeInfo(android.view.accessibility.AccessibilityNodeInfo)
and set the contentDescription there.
If you want to remove the 0%, I would try to change the class in AccessibilityNodeInfo/AccessibilityEvent:
http://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html#setClassName(java.lang.CharSequence)
I believe that this is a bug in TalkBack, and have raised Google Eyes-Free issue #375, including example code.
Update: Google have now archived this. Link moved to: http://code.google.com/archive/p/eyes-free/issues/375
I have some images that are impossible for visually impaired users to use at all. I want to be consistent in my code so I have content descriptions. Is there a specific string that will make it so Talkback doesn't say anything when the user touches the images.
EDIT: Previous answer was to not add the tag in XML. The correct answer is to add the value "#null". This prevents a string from being spoken (same as an adding the attribute), but #null will also prevent the LINT tool from yelling at you about a missing attribute.
I am looking to create something very similar to what Google has done in the Google+ app.
Its hard to describe but please take a look at this screenshot
Google+ app
I am looking to create something similar, of note is that the tags move to the proper line as they fit.
Is this a completely custom solution that Google wrote or is there a library for this somewhere.
It looks like they are decorating the text in the edit text by using spans. They probably have a listener on the edit text listening for modifications at which point they check to see if the most recently added word matches one of your circles. If it does, the create a span over the text and decorate it with a background drawable, font color change, and by adding an image next to it.
Its probably a pretty significant effort depending on how you want to function, but all that functionality is out there in the sdk.
To get a TextView to display (and act friendly with) Html strings my code looks something like:
// itemHtml is a String of HTML defined above
TextView itemContent = (TextView) findViewById(R.id.itemContent);
itemContent.setText(Html.fromHtml(itemHtml));
itemContent.setMovementMethod(LinkMovementMethod.getInstance());
If the Html string has a link, TextView results in links that are clickable and focusable. When the user focuses on a specific link (e.g. by using the d-pad), the link text changes in some significant way to show that focus was obtained.
The problem is that when I test this same pattern using devices with a d-pad using Honeycomb (e.g. a Google TV) or Ice Cream Sandwich flavors of Android, the link in the text shows no noticeable indication that the link has focus.
I know it is getting focus, because when you then hit enter it does the specified action. You can even move around between various links in the text; you're just left guessing which link you're currently at, which results in a very bad user experience.
Is there something I'm doing wrong? Is there some way to fix this or work around this?
Edit: After going a bit nuts, I finally thought I found a solution. However, this solution only works for Honeycomb. ICS is still not solved!
As of API 11, Android has a new setting on TextViews for defining whether the text is selectable.
You can set it using setTextIsSelectable(true) on a TextView, or define it in the XML layout android:textIsSelectable="true"
It's probably best to define it in XML, so that keeping the app backwards-compatible is trivial. Just make sure you're targeting version >= 11, or you'll probably get an error.
The way HTML.fromHTML operates is by creating "spans" with varying effects throughout the various characters of the string. One workaround for this would be to use ClickableSpan coupled with another of the CharacterStyles to colorize the text as clickable. The previous span will allow you to register a callback, and this callback could be to broadcast an intent to view a url (which would open a browser).
The text colour state lists for Honeycomb+ might not set the focused state to a different colour, or you override the colour to be constant.
Check the colors + styles in your_android_sdk_directory/android-14/data/res/
Setting the text to android:autoLink="web" might also help?
The best way to do that is to add CSS styling to your html. I know Android supports :hover selector. So you might right something like this:
String myLink = "your link"
Html.fromHtml(myLink);
and find a way to include CSS data to it: (I'm not sure how but I think it's possible)
a :hover {
color: red;
}
UPDATE:
I think the answer of your question is there.
I'm implementing an EditText that is used to obtain an rtsp URI from the user. Though it's not a huge issue functionally, I would like to disable the default behavior of the on screen keyboard where the state of the caps key is enabled for the first character of every sentence. From what I've gathered, this cannot be done in the XML via android:inputType flags. Any pointers as to how to do this programatically would be helpful.
I'd like to include the code, but the nature of the project prevents me from doing so. But I can say that nothing fancy is being done here. The EditText itself has no other input flags in use, and the only IME option in place is the flag to disable the Extract UI in landscape. The layout is implemented via XML, not programatically, so there are no custom classes or extensions in the mix either.
EDIT: The android:capitalize constant inherited from TextView isn't working. I'm specifically targetting 2.2 on a Galaxy Tab, so I don't know if this has something to do with Samsung's OS tweaks, or if it has something to do with the capitalize constant being deprecated.
EDIT 2: Swype is the culprit for not allowing the use of the capitalize constant. Does anyone know if there is a way to make Swype play nice without having to inform the end user to disable Swype?
You can use the inherited android:capitalize attribute from TextView. It accepts none (no caps, which is what you want), sentences (capitalizes the first word of each sentence), words (capitalizes the first letter of every word), and character (all caps).
Putting this in the XML for the EditText worked to stop Swype 2.17.59.15552.t100 from forcing capitals:
android:inputType="text|textEmailAddress"
Since EditText is subclass of TextView, you should be able to use the TextView:capitalize configuration to change the capitalization scheme of the view. It looks like you might only be able to set none in xml.