I was wondering if there was any way that I could get a hint at the bottom of an Edit Text view -- and then the user to start entering text at the top of the box.
As a bonus question, is there any way I can make the hint NOT disappear once the user starts entering text.
You can set the position of the text using the "gravity" attribute (as noted at http://developer.android.com/reference/android/widget/TextView.html#setGravity(int)). So to put the text at the bottom you would have;
android:gravity="bottom"
And to answer your bonus question; No, you can't display the hint when text is entered into the edit text view. Displaying the hint only when the box is empty is the defined behaviour as noted at http://developer.android.com/reference/android/widget/TextView.html#setHint(int)
(and yes, I know the links are for TextView, but EditText derives all of its' text positioning and hint handling functionality from TextView).
Actually THERE IS a way to prevent hint from hiding, and it's a cool one :-)
It gives you the Floating Label look with smooth animation very easily and it's from android itself. No extra libraries and stuff.
Try this:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Touch me and I'll fly!"/>
</android.support.design.widget.TextInputLayout>
You can change the behaviour using other xml tags like android:gravity="start|center|end" and others.
As a BONUS, you can use error messages with it :-) Here's the link to that question: https://stackoverflow.com/a/30953551/6474744
And sorry I do not have enough reputatuion to post images, so help yourself:
http://i0.wp.com/androidlift.info/wp-content/uploads/2015/09/Screenshot_2015-09-28-17-03-561.png
Enjoy :-)
The problem with using both android:gravity and android:hint is that they are inter-linked with regard to cursor position.When you position the hint using gravity and you start entering text, it is entered in the same position as the your hint which is a problem if you want it to start traditionally on the top-left corner.
Related
Say I have a list of items, and one of the views in each item is a message, in a simple TextView, that is populated in code (dynamic data from a backend service).
<TextView
android:id="#+id/message"
style="#style/DefaultText"
/>
Visually it doesn't need a label; the list item layout is pretty clear. But listening to how TalkBack reads the screen, I think it would be beneficial to have a "label" or description for it. So that TalkBack would read something like:
Message: [the actual dynamic message content]
My question is: is it possible to add a label/description for a TextView that, firstly, does not replace the TextView content, but is read along with it, and secondly, only affects TalkBack (not the visual presentation)?
What I tried:
contentDescription for the TextView. Doesn't work: if set, the actual content is not announced, only the contentDescription. Hmm, maybe if I'd set this in code with the description prepended to the actual content... but is there no easier way?
Separate TextView with labelFor pointing to #+id/message. The problem is that it's also shown visually and screws up the design. If I make it not visible, one way or other, it seems TalkBack won't read it either.
Alright, I found two solutions! As mentioned in the question, I'd rather have avoided doing it in code, but it seems for optimal results that's the way to go.
Use android:hint in XML
The most simple way is to set android:hint="Message" for the TextView. TalkBack reads it after the actual text:
[the actual dynamic message content] Message
For my needs, with the message being optional, this has some drawbacks: the hint is announced even if the TextView has no actual content (I'd prefer to omit it then), and in that case it's also shown visually (not what I want). Also, I'd prefer TalkBack to read the hint before the actual text.
Set contentDescription programmatically
Not as simple, but not complicated either, and you have complete control over what TalkBack says.
In my case, preferring to omit the description if message is missing and having it read before the message content, I'd do something like this in the code that populates the list items:
textView.setText(message);
if (!TextUtils.isEmpty(message)) {
textView.setContentDescription(
context.getString(R.string.message_desc, message));
}
With resource:
<string name="message_desc">Message: %s</string>
You can use this namespace it not visually show on real screen
xmlns:tools="http://schemas.android.com/tools"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="your text"/>
In your XML file, set the importance to "no". You can also do this at run time using the View.setImportantForAccessibility() API.
android:importantForAccessibility="no"
Programmatically you can say:
view.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
Example click here
click here for more info
I'm using the new TextInputLayout provided by Android.support to do floating label. But it will fail Espresso Accessibility Check because "View is missing speakable text needed for a screen reader".
Looked into it and find out the TextInputLayout will nullify hint when parent does addView(). This is basically how it can float the label up(set the label, nullify the hint). And any EditText with null hint will fail the accessibility check.
Anyone knows how to resolve this issue? It's really driving me crazy..
Thanks a lot!!!!
A great way to make TextInputLayout accessible is to use "LabelFor" as recommanded by ChrisCM, but you don't have to add an invisible label view to do so: Just put the labelFor or your Textinputlayout and make it point to your EditText
Example:
<android.support.design.widget.TextInputLayout
android:labelFor="#+id/username"
android:contentDescription="#string/username_hint"
android:accessibilityLiveRegion="polite">
<edittext
android:id="#+id/username"
android:hint="#string/username_hint"
…/>
</android.support.design.widget.TextInputLayout>
This way you get the exact same visual behaviour and make "Espresso Accessibility Check" and Talkback happy :)
(To make TextInputLayout fully accessible I also added android:accessibilityliveregion on the TextInputLayout element to trigger talkback whenever the error is poping)
A big thanks to this post this blog post which helped a lot
Hints aren't great for accessibility in general. They disappear when text is entered. Try using a "LabelFor" instead. If you don't want a visible label, you can set your label to not be displayed.
This app will give you hints on how to make text boxes accessible.
https://play.google.com/store/apps/details?id=com.dequesystems.accessibility101
Alternatively, if this is a false positive you can ignore checks as described here
val validator: AccessibilityValidator = AccessibilityChecks.enable().apply {
setSuppressingResultMatcher(
allOf(
matchesCheckNames(`is`("TouchTargetSizeViewCheck")),
matchesViews(withId(R.id.my_overflow))
)
)}
The following rules are invoked when we enable tests for accessibility checks:
TouchTargetSizeViewCheck Target height or target width less than 48
dp is flagged, unless there is a touchdelegate detected.
TextContrastViewCheck Checks text color and background and factors in
large text, and calculates the contrast ratio: - 4.5 for regular
text, 3 for large text.
DuplicateSpeakableTextViewHierarchyCheck If
two Views in a hierarchy have the same speakable text, that could be
confusing for users if at least one of them is clickable.
SpeakableTextPresentViewCheck If the view is focusable, this checks
whether valid speakable text exists, and errors if the view is
missing speakable text needed for a screen reader.
EditableContentDescViewCheck Throws an error if Editable TextView has
a contentDescription.
ClickableSpanViewCheck Checks if ClickableSpan
is inaccessible. Individual spans cannot be selected independently in
a single TextView, and accessibility services are unable to call
ClickableSpan#onClick.
RedundantContentDescViewCheck Accessibility
services are aware of the view's type and can use that information as
needed. For example, it throws a warning if the content description
has a redundant word, such as “button.”
DuplicateClickableBoundsViewCheck Throws an error if Clickable view
has the same bounds as another clickable view (likely a descendent).
Sometimes there are containers marked clickable, and they don't
process any click events.
You can make a TextView that has
android:text="My Announcement For Edit Text"
android:labelFor="#id/my_edit_text".
Visibility = gone and visibility = invisible will make it so this label is not announced. Also if you set height and width to 0dp, this will not announce. Instead, constrain the view to be off the screen using something like:
app:layout_constraintEnd_toStartOf="parent"
So your textview will look like this:
<TextView
android:id="#+id/edit_text_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="#+id/my_edit_text"
android:text="Label For My Edit Text"
app:layout_constraintEnd_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
This worked for me using withClassName for a view
AccessibilityChecks.enable().setSuppressingResultMatcher(
AccessibilityCheckResultUtils.matchesViews(
Matchers.anyOf(
ViewMatchers.withResourceName("textview1"),
ViewMatchers.withResourceName("button1"),
ViewMatchers.withClassName(Matchers.endsWith("TextInputLayout"))
)
)
)
I have an app in which the main view is a PopupWindow with a couple of ImageViews and an EditText on top of them. My problem is when I enter a very long text and the text box expands down and pushing the image views out of the view and I can't see them, and in order to see them back I need to delete some text.
What is the proper way of overcoming this?
thanks.
try to add into the XML something like that:
android:maxLines = "5"
android:scrollbars = "vertical"
Perhaps enclosing your LinearLayout of the PopupWindow in a ScrollView could help. LinearLayout does not allow for scrolling, if you are using it.
EDIT: In regards to the other answers, these will also work, but if you are intending to allow the user to enter as much text as they want, it may not be the best solution
See This question for more details
This should limit the height of the EditText, so even if the user types a long book in there, the field will keep its height limited to one line.
android:maxLines="1"
To limit the text to just one line, you can use this instead:
android:singleLine="true"
I have an edittext field. As I type and characters exceed the maxlength of it there appears a new row to continue typing. However, I want to avoid this behavior since there is map below it which is going down relatively.
I don't want to restrict the maxlength as well.
Can someone explain how do I solve this problem?
define following parameters in your xml under the edittext tag:
android:singleLine="true"
Correct me if Im wrong, but is't singleLine="true" depricated?
android:lines="1"
I've got a TextView that I would like to allow the user to select a range of text from within it. The TextView takes up the entire width and height of the device (minus some padding and a title at the top). In an EditText if you long-click you get a selection overlay that allows you to set your selection left and right bounds. I'd like this functionality in a TextView. I've read that in API level 9 (2.3) (http://developer.android.com/sdk/android-2.3.html) there are new text selection controls, but I'm having difficulty implementing this. I'm doing this right now:
eic = new InputConnection( bookTextView );
eic.beginBatchEdit();
But it doesn't do anything noticable. Does anyone know how to use InputConnection correctly? Thanks.
Edit: I don't necessarily need to use what I was attempting above. I ultimately want to use either a TextView or an EditText which looks and feels like a TextView and be able to select text using a dragging cursor. Then I would like to manipulate the selected text with various context menu options (or a menu that pops up above the selected text).
Here is an idea.. Add an EditText with a TextView background, Here is an example
<EditText
android:text=" This is not an editable EditText"
android:id="#+id/EditText01"
android:layout_width="wrap_content"
android:textColor = "#android:color/white"
android:editable = "false"
android:cursorVisible="false"
android:layout_height="wrap_content"
android:background = "#android:drawable/dark_header">
</EditText>
add this to your xml in the place of TextView
You can enable the TextView's Spannable storage. See Highlight Text in TextView or WebView for an example.
See also:
http://developer.android.com/reference/android/text/Spanned.html
You could display the text in a WebView and enable text selection. If you want to only use a textview/edittext, here is an answer that might help you and here is information on the Spannable class that might help you accomplish what you want.
Actually, you do not have to develop this feature by yourself. You just need to use EditText instead TextView, while you set the android:editable of EditText to false. My idea is the same as sandy's.
My code is here, hope it may help you:
https://stackoverflow.com/a/11026292/966405
After long internet surfing to find a solution, i prefered create my own class
https://github.com/orionsource/SelectableTextViewer
Goal features:
Easy to use - only one class
Support for text and Html.fromHtml
Can be in ScrollView with correct touches
Cursors can be redefined
Color of selection can be redefined
All the above solutions either too long or not working for me.
What you need is to add just textView.setTextIsSelectable(true)
in your activity or fragment or adapter.