Make text bold, italic or underline while writing in edittext - android

I want my editText to able to write text in bold, italic and underline along with normal text.
Eg:
The weather is nice today.
I know I can use html tags but I want to perform these operations while writing in the edittext.
What I have tried:
//here textEdits is my model to store the string. As I have multiple editTexts in the activity.
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if(isBold){
String textsequence = textEdits.get(position).getTextString();
if(i > 0){
String sequence = charSequence.subSequence(0, i).toString() +"<b>"+ charSequence.subSequence(i,i+i3).toString() + "</b>";
textEdits.get(position).setTextString(sequence.toString());
editTextcurrrent.setText(Html.fromHtml(sequence.toString()));
editTextcurrrent.setSelection(i+i3);
}
}
}
else {
textEdits.get(position).setTextString(charSequence.toString());
}
}
}
The problem:
The charSequence returns a string without html tags so, once you have set the value, the next time you will get a string without html tags, and therefore you cannot track your previous html edits.
Other than this I have tried Typeface but even that didn't work out.
Also apologies if the work that I tried is not quite understandable, Its a part of a large code so there are quite a lot linked up and I tried to remove as much dependencies as I could.

You will want to use SpannableString:
String yourString = "The weather is nice today."
SpannableString contentSpan = new SpannableString(yourString);
contentSpan.setSpan(new TextAppearanceSpan(activity, R.style.bold_style), weatherFirstPos, weatherLastPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
contentSpan.setSpan(new TextAppearanceSpan(activity, R.style.italic_style), niceFirstPos, niceLastPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
editTextcurrrent.setText(contentSpan, TextView.BufferType.SPANNABLE);
For R.style.bold_style and italic_style you can have something like:
<style name="bold_style">
<item name="android:textStyle">bold</item>
<item name="android:textColor">#color/black</item>
</style>
weatherFirstPos, weatherLastPos, niceFirstPos and niceLastPos are the positions of where you want to apply the style:
int weatherFirstPos = yourString.indexOf("weather");
int weatherLastPos = weatherFirstPos + "weather".length();

Use OnFocusChange Listener & Change EditText properties as you like when EditText gain focus of user
or
you can also set in Xml bold and italic.
<EditText
android:id="#+id/edittext"
android:layout_margin="#dimen/activity_horizontal_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold|italic"
android:text="enter your name"/>

Related

Setting EditText imeOptions to actionNext has no effect when using digits

Here my edittext:-
<com.os.fastlap.util.customclass.EditTextPlayRegular
android:id="#+id/full_name_et"
style="#style/Edittext_white_13sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_5sdp"
android:background="#00ffffff"
android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
android:imeOptions="actionNext"
android:inputType="text"
android:maxLength="20"
android:maxLines="1"
android:nextFocusDown="#+id/last_name_et"
android:textCursorDrawable="#null" />
When I remove digit in edittext it work fine but with digit imeOptions doesn't work. But one surprising thing if I use singleLine instead of maxLines it work fine. But singleLine now is deprecated. I cannot remove digit in my edittext and I don't want use deprecated method. Any one can solve this problem. Thanks in adavance
Here is a simplified solution with the software keyboard button "Next":
final String NOT_ALLOWED_CHARS = "[^a-zA-Z0-9]+";
final EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void afterTextChanged(Editable s) {
if (!TextUtils.isEmpty(s)) {
// remove the listener to avoid StackoverflowException
editText.removeTextChangedListener(this);
// replace not allowed characters with empty strings
editText.setText(s.toString().replaceAll(NOT_ALLOWED_CHARS, ""));
// setting selection moves the cursor at the end of string
editText.setSelection(editText.getText().length());
// add the listener to keep watching
editText.addTextChangedListener(this);
}
}
});
Here the regular expression [^a-zA-Z0-9]+ corresponds to the allowed values of android:digits of the EditText in question.
you can use
android:lines="1"
in place of
android:maxLines
or
android:singleLine="true".
I know you have tried many solutions, Try with
android:lines="1"
these if you haven't tried earlier.
The problem is you are clicking on Enter key instead of the actionNext you need in order to move cursor to next EditText
Specify the Input Method Action
Most soft input methods provide a user action button in the bottom
corner that's appropriate for the current text field. By default, the
system uses this button for either a Next or Done action unless your
text field allows multi-line text (such as with
android:inputType="textMultiLine"), in which case the action button is
a carriage return. However, you can specify additional actions that
might be more appropriate for your text field, such as Send or Go.
It causes carriage return for your action button. So it means that doesn't fire android:nextFocusDown
First of all, lets see what is difference between singleLine which is deprecated and maxLines
singleLine
When you set android:singleLine="true" one line text is in EditText visible but Enter key isn't visible in keypad
maxLines
when you set android:maxLines attribute with the particular value only same amount of line text is visible in EditText and enter key in keypad also visible for Entering.
So When you click action button it is firing Enter Action according to your code. Also you must change your inputType attribute with android:inputType="textMultiLine" if you use android:maxLines attribute
maxLines
added in API level 1 int maxLines Makes the TextView be at most this
many lines tall. When used on an editable text, the inputType
attribute's value must be combined with the textMultiLine flag for the
maxLines attribute to apply.
May be an integer value, such as "100".
When I customized your code with the correct attributes still it was firing Enter key instead of IME_ACTION_NEXT which you want. I think it didn't solve the problem due to
textMultiLine Can be combined with text and its variations to allow
multiple lines of text in the field. If this flag is not set, the text
field will be constrained to a single line. Corresponds to
TYPE_TEXT_FLAG_MULTI_LINE.
TYPE_TEXT_FLAG_MULTI_LINE
added in API level 3 int TYPE_TEXT_FLAG_MULTI_LINE Flag for
TYPE_CLASS_TEXT: multiple lines of text can be entered into the field.
If this flag is not set, the text field will be constrained to a
single line. The IME may also choose not to display an enter key when
this flag is not set, as there should be no need to create new lines.
Constant Value: 131072 (0x00020000)
SOLUTION:
Subclass EditText and adjust the IME options. After that you don't need android:maxLines or android:singleLine attributes.
#Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection connection = super.onCreateInputConnection(outAttrs);
int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
if ((imeActions&EditorInfo.IME_ACTION_NEXT) != 0) {
// clear the existing action
outAttrs.imeOptions ^= imeActions;
// set the DONE action
outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT;
}
if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
return connection;
}
You could also check another post here. I reconfigured the accepted answer of this post on your purpose
android:digits specifies that the EditText has a numeric input method, as per the docs
You could use android:inputType="personName" to achieve the same as your current digits attr
android:maxLines only Makes the TextView be at most this many lines tall, not prevent user from input more characters.
The same with android:lines that only makes the TextView be exactly this many lines tall.
The workaround code for your solution are as below,
XML File
<EditText
android:id="#+id/full_name_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5sp"
android:background="#00ffffff"
android:imeOptions="actionNext"
android:inputType="text"
android:maxLines="1"
android:maxLength="20"
android:textCursorDrawable="#null" />
Java:
final EditText edtfirstName = (EditText) findViewById(R.id.full_name_et);
edtfirstName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (charSequence.toString().startsWith(" ")) {
String result = charSequence.toString().replace(" ", "").replaceAll("[^a-zA-Z]+", "");
if (!charSequence.toString().equals(result)) {
edtfirstName.setText(result);
edtfirstName.setSelection(result.length());
}
} else {
String result = charSequence.toString().replaceAll("[^a-zA-Z ]+", "");
if (!charSequence.toString().equals(result)) {
edtfirstName.setText(result);
edtfirstName.setSelection(result.length());
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
});

EditText - have default text that cannot be deleted, and cover text with background after leaving EditText

I am creating an email form and would like to have text in an EditText that cannot be deleted. On the screenshot below, the To could not be deleted.
If anyone has suggestions on how to achieve the above, it would be great - Thanks.
My current code for the To EditText box:
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="0dp"
android:hint="#string/email_to" >
</EditText>
The problem is android:hint text dissappears when the user starts to text, and android:text can be deleted by the user.
How do we have text that cannot be deleted? Thanks.
Note:
Also, I would like to note that I have a method that clears text using a clear button - this works fine - but I am hoping that it would not delete the fixed text (If I got that implemented!).. Here`s the code for that:
private void clearForm(ViewGroup group)
{
for (int i = 0, count = group.getChildCount(); i < count; ++i) {
View view = group.getChildAt(i);
if (view instanceof EditText) {
((EditText)view).setText("");
}
if(view instanceof ViewGroup && (((ViewGroup)view).getChildCount() > 0))
clearForm((ViewGroup)view);
}
}
SOLUTION:
Managed a roundabout way of doing this.. I created a TextView and EditText within a nested Linear Layout. I turned off the border in the EditText using android:background="#00000000".
I created an xml file in the drawable folder, and refered to this in the relevant linear layout like this: android:background="#drawable/customxml"
You can do it by using Text Watcher listener.
You can keep text in edittext by checking length of edittext.
For example
editText.setText("To") // it mean have lenght 2
And Than in method afterTextChanged, check if text in editText is has been deleted (with check length of text in editText)
This is for complete example code:
editText.setText("To");
editText.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
if(s.length < 2){
editText.setText("To")//set editext with "To" again like has been initialized
editText.setSelection(editText.getText().length)// to make cursor in end of text
}
}
});
Hope this help!
To get the visual appearance you want, include a horizontal LinearLayout containing a text view and an EditView. Turn off the border around the EditView (there's an attribute that does that (I think it's android:shadowColor) ) Play around with margins and padding to get them to be adjacent to each other. Set the background color on the linear layout to put a border around the combined pair.
I wouldn't worry much about efficiency. You aren't nesting very deeply. The biggest challenge is going to be getting it to look like a single view.
Edit: Another thought. If that doesn't work, you could make the "To" a drawable, and set it using the android:drawableLeft attribute.
Add TextView to the right side of EditText in LinearLayout with horizontal orientation or RelativeLayout with android:layout_toRightOf="#id/YourTextView"

URLSpans in WebView?

I need to push text into WebView. But there are a lot of different HTML tags in this text and I want to parse it before.
Spanned html = Html.fromHtml(texts.get(i));
But I need to change URLs in the text to call one function in my activity. In TextView I may do it like that:
ClickableSpan[] items = spans.getSpans(0, spans.length(), ClickableSpan.class);
for (ClickableSpan s : items) {
final String url = ((URLSpan)s).getURL();
int spanStart = spans.getSpanStart(s);
int spanEnd = spans.getSpanEnd(s);
spans.removeSpan(s);
spans.setSpan(new URLSpan(url) {
#Override
public void onClick(View widget) {
//code for overriding onClick goes here
}
}, spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
Is it possible to use Html.fromHTML() AND to change links in text to call my function when using WebView instead of TextView?
Not really, because WebView understands HTML, not a Spanned. You are welcome to try to convert the Spanned back into HTML via Html.toHtml(), but the round-trip conversion from HTML to Spanned to HTML is likely to make a hash of any complex formatting, because they are not complete HTML parsers or generators.
I would recommend that you find and use some Java library that is designed to parse and help you fix up HTML.

TextView: how to dynamically change the color of certain word in paragraph

How to change the color of a paragraph word by word with timer. like at first second i want to change color of The in the below paragraph, after 5th second change color of text, after 8th second change color of will be and so on....
The text will be wrapped in tags, and displayed in a monospaced font.
just use Timer and change the font color of your edit text accordingly and stop timer in focus lost.
i think you can do something like this :
Split the paragraph to words by using the method :
split(String separator);// it will return an array of Strings
//in your case you will do somthing like this
myWords = paragraph.split(" ");// the separator is the space
And then , you can use the method to colorate what ever you want of those words by using the method :
myNewParagraph.append(HTML.fromHtml("<font color...>... Your HTML Code to colorate your Text"));
and when you finish coloring each word , you update your textView to display the new text colored
Hope it helps
You can use spans to control the appearance of text. Take a look at Spannable and CharacterStyle.
Here is an example. Of course you would need to put this in some sort of timer.
Spannable spannableText = getSpannableText(yourTextView);
spannableText.setSpan(new TextAppearanceSpan(...), wordStart, wordEnd)
yourTextView.setText(spannableText);
private Spannable getSpannableText(TextView tv) {
CharSequence cs = tv.getText();
if (cs instanceof Spannable) {
return (Spannable)cs;
} else {
return SpannableString.valueOf(cs);
}
}

Creating a customised button with 2 lines of text

I'm new to Android (Visual Studio for 20 years). I need to create a clickable control that features 2 lines of text (1 smaller font at the top of the button for a caption and a larger font line for a value - would post an image but I'm not allowed). The size of the larger font scales so that the value will fit on the control.
I'm pretty sure I need to subclass the button control but not sure how to in this case. All samples I have found don't seem to fit the bill.
Have done this easily with VB.Net but I'm stumped when I try with Android. Any help very much appreciated. Might be a handy control for others too.
Thanks
You could try using Spannable in the code like:
public class Test extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button but = (Button) findViewById(R.id.button1);
String butText= "Line 1\nLine 2";
but.setText(formatString(butText));
}
private Spannable formatString(String str) {
int startSpan = str.indexOf("\n");
int endSpan = str.length();
Spannable spanString = null;
spanString = new SpannableString(str);
spanString.setSpan(new TextAppearanceSpan(this,
R.style.custompoint), startSpan, endSpan,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spanString;
}
}
Where you have a style 'custompoint'
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style
name="custompoint">
<item name="android:textSize">24sp</item>
<item name="android:textStyle">bold</item>
</style>
</resources>

Categories

Resources