How can I allow user to edit a TextView? Of course, I can use EditText instead, but I don't know how to customize it and also I've read in Android documentation that TextView can be editable. So I tried this:
<TextView android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="80sp"
android:text="MyText"
android:editable="true"
android:singleLine="true"
android:inputType="text"
android:focusable="true"
android:clickable="true"
android:cursorVisible="true"/>
But it still looks like common TextView. Does anyone know what I have missed? Or, may be, how to customize EditText for it look like TextView: without borders and background?
I know you don't want to use an EditText but it's really easy to make it look like a TextView.
<EditText
android:id="#+id/Id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent" >
</EditText>
You can also use android:background="#null".
Edit:
The TextView's editable param does make it editable (with some restrictions).
If you set android:editable="true" you can access the TextView via the D-pad, or you could add android:focusableInTouchMode="true" to be able to gain focus on touch.
The problem is you cannot modify the existing text, and you cannot move the cursor.
The text you write just gets added before the existing text.
You can make your TextView editable by adding these lines
tv.setFocusable(true);
tv.setEnabled(true);
tv.setClickable(true);
tv.setFocusableInTouchMode(true);
You can fake a editable Textview. You just have to hide the textview when you touch it (make it "clickable"), replace it with an EditText, and display it again when the edit is over.
TextView defines all capabilities found on EditText, but doesn't have built-in support to them. Some main differences on EditText:
a) Method getDefaultEditable() returns true. This is only a mark that defines this subclass as editable.
b) A movement method. Is an object that control the cursor behavior (position, backward/forward moves - that may change in some languages, etc). In opposition, TextView just returns null, because is not cursor anyway.
c) Method CharSequence getText(). TextView returns a single String for that. EditText uses a specific char sequence implementation (Editable) that represents a mutable text buffer.
Because that, we can't think about TextView like a restrained EditText. TextView sketch the editoring interface, but not implement itself.
If you need a text component that you can switch off editing sometimes, you are looking for the EditText component.
tv.setCursorVisible(true);
tv.setFocusableInTouchMode(true);
tv.requestFocus();
tv.setEnabled(true);
I finally found the solution to your problem by creating the TextView programmatically
TextView textView = new TextView(context, null, android.R.attr.editTextStyle) {
#Override
public boolean getDefaultEditable() {
return true;
}
};
OR IN XML
<TextView
android:id="#+id/textView_ID"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:style="#android:attr/editTextStyle"
android:editable="true"/>
Enjoy!
Related
A screen in my app will potentially post really long strings into a TextView. For this scenario, I have android:ellipsize="marquee" set so the text will marquee across the TextView.
However, I've decided I also want this text to be selectable (android:textIsSelectable="true"). In most cases, this is no problem. The text is smaller than the TextView and the user can just select it. However, if I have the textIsSelectable attribute and if the text is bigger than the TextView, the text will pick up an ellipse instead of being the full string. It will still marquee, but it no longer displays the full text. It cuts it off and displays an ellipse.
<TextView
android:layout_width="wrap_content"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:ellipsize="marquee"
android:focusable="true"
android:gravity="center_vertical"
android:singleLine="true"
android:textIsSelectable="true">
Is there a way to have the text selectable and still maintain the entire string in the marquee (no ellipse)?
Can't be sure if this is a bug.
<TextView
android:layout_width="wrap_content"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:ellipsize="start"
android:focusable="true"
android:gravity="center_vertical"
android:singleLine="true"
android:textIsSelectable="true"/>
Note that we're setting android:ellipsize="start" in xml - more on this later.
mTextView = (TextView) findViewById(R.id.tv);
mTextView.post(new Runnable() {
#Override
public void run() {
mTextView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
mTextView.setSelected(true);
}
});
setEllipsize(TruncateAt) checks whether the current ellipsize value is the same as the supplied one. To get around this, we supply android:ellipsize="start" in xml. This way, the TextView has no problem accepting TextUtils.TruncateAt.MARQUEE later on.
Now, even though this works, I will suggest you don't do this. You'll be able to see why - once you try this code. It seems textIsSelectable is not supposed to be used with marquee - the selection handles don't move along with the text.
All in all, it looks extremely sketchy.
How can I display a text error with setError in an EditText not focusable? It's important that users don't modify this EditText, it'll be modified for the application. Maybe I have another option different than focusable=false?
Now, I have it:
<EditText
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:ems="10"
android:focusable="false"
android:inputType="text"
android:onClick="onClick" />
Thanks a lot!
Finally I think it's not possible to do... Because the first necessity is to block the text, doing it with focusable=false or with a TextView, and it also blocks the functionality setError.
An editText with focusable = false I can get a right drawable (the default red exclamation mark) but without text. For this reason I finally added the text with a Toast.
It's not completelly that I wanted, but it's the most similar.
Thanks for your help!
Just use TextView and if you have an error somewhere then show image with drawableRight.
Here's the example of doingit programmatically: https://stackoverflow.com/a/7380789/3864698
I'm curious about the difference setText() and append() are creating. I'm writing a very basic editor with line numbers. I have a TextView to hold line numbers on the left, paired with an EditText on the right to hold the data. Here's the XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="top">
<TextView
android:id="#+id/line_numbers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="0dip"
android:gravity="top"
android:textSize="14sp"
android:textColor="#000000"
android:typeface="monospace"
android:paddingLeft="0dp"/>
<EditText
android:id="#+id/editor"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="text|textMultiLine|textNoSuggestions"
android:imeOptions="actionNone"
android:gravity="top"
android:textSize="14sp"
android:textColor="#000000"
android:typeface="monospace"/>
</LinearLayout>
Ignoring some of the other things I'm doing, the most curious thing I came across was the extra spacing that showed up when I used append() (assuming things have been initialized and all that).
This below, in combination with the XML, sets a flush border between the TextView and EditText.
theEditor = (EditText) findViewById(R.id.editor);
lineNumbers = (TextView) findViewById(R.id.line_numbers);
theLineCount = theEditor.getLineCount();
lineNumbers.setText(String.valueOf(theLineCount)+"\n");
Change the last line to this, though, and suddenly each line in the TextView has padding on the right before the EditText.
lineNumbers.append(String.valueOf(theLineCount)+"\n");
It's not the end of the world. but I was curious what was causing this behavior. Since I'm new to the language, the only thing I could think of was maybe, when append throws the Editable on there, it adds the padding. If I can get an answer, I get to replace all of these nasty lines with simpler appends:
lineNumbers.setText(lineNumbers.getText().toString()+String.valueOf(newLineCount)+"\n");
lineNumbers.setText("It is test,");
//Here lineNumbers have It is test
lineNumbers will have "It is test,". After that, if you use setText again, text will completely change
lineNumbers.setText("It is second test,");
//Here you'll lose first text and lineNumbers text will be "It is
second test,"
After that, if you use append, lets see what will happen..
lineNumbers.append("It is third test,");
// Here you will not lose lineNumbers text.. It will be like this
"It is second test,It is third test"
setText(): Destroys the buffer content by filling the text to be set.
append(): Adds a text to a buffer and then prints the result.
Example: example.setText("Hello"); would print Hello on the output screen. If you then execute example.append("World"); you would get HelloWorld as the output.
setText will replace the existing text with new text.
From Android doc:
Sets the text that this TextView is to display (see setText(CharSequence)) and also sets whether it
is stored in a styleable/spannable buffer and whether it is editable.
append will keep the old text and add the new one more like concatenating.
From Android Doc
Convenience method: Append the specified text to the TextView's display buffer, upgrading it to
BufferType.EDITABLE if it was not already editable.
I think changing BufferType to EDITABLE by append method caused the unexpected padding.
If you want to use append method instead of setText method and remove that padding,
you can try to remove it by using
textView.setincludeFontPadding(false)
or adding this line to your textview in your xml file
android:includeFontPadding="false"
Hope this helps.
The basic difference is that setText() replaces all the text from the existing one and append() adds your new value to existing one. Hope i helped.
I'm trying to create a custom TextView which should have a cursor.I don't want to use EditText since the input should not be provided via the android keyboard, moreover it should look like a TextView.
I've found that the TextView Interface has a support for a cursor, but I was unable to make it show. here is what I've tried:
added
android:textCursorDrawable="#null"
called
textView.setCursorVisible(true);
textView.setSelected(true);
textView.forceLayout();
textView.moveCursorToVisibleOffset();
when I added android:editable="true" and called textView.moveCursorToVisibleOffset(); NullPointerException was thrown within the textView.
any suggestions?
you can use Edit Text like this it shows like Text view:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#null"/>
<EditText
android:id="#+id/drawer_search"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:background="#color/white"
android:drawableLeft="#android:drawable/ic_menu_search"
android:hint="#string/drawer_search_hint"
android:imeOptions="actionSearch"
android:maxLines="1"
android:textColor="#color/dark_blue"
android:textColorHint="#color/dark_blue"
/>
So... all of the attributes work except imeOptions and maxlines. I want the text view to be only one line and the keyboard to not have a return key to go to the next line. It needs to submit/search what ever is in the text view.
So this is the text view. cropped for space.
If you press enter/return it goes to the next line(which there should only be one line).
Why isn't the textview using all of the attributes?
Is there a better way to make it so the keyboard's return button is a submit button rather than next line?
The layout file is declared like this.
View headerRoot = inflater.inflate(R.layout.drawer_header, null);
Attribute android:maxLines corresponds to the maximum height of the EditText or TextView. Use android:singleLine=true for one line input.