I need help understanding how to accomplish math between different EditText views. I am not asking someone to write me the code but maybe explain what is involved to get this done.
I wanted to post a picture of this but as a new user I can not. Basicly I have a EditText for the following: Width, Length, Eave Height, Pitch.
I have ID's for all the TextViews I just dont know how to program the behind the scenes math involved to make them work. I do have the equations needed to perform the math just not sure where and how to put them in java.
Basicly I need the user to enter a number in each of the top 4 boxes. I need to use an equation to generate the answer that will be displayed in the "SQFT" box. The user will also input a number in a cost box which will generat a "Total" that needs to be displayed in a separate TextView.
Any help would be appreciated, even if it is to point me in a direction of a tutorial to get me started. Thanks for your help.
Just to show what type of math I need to use, below is the equation I use for excel to calulate.
(length+width)*(Eave+1)*2 + (((width/2)/12*Pitch)*(width/2)*2)
I'm not sure if you don't know how to extract the numbers entered in the EditTexts, how to actually do the math calculation, how to let the user initiate the calculate or how to present it.
I created a small demo that has 2 EditTexts, and a TextView that displays the sum of the numbers entered. The user does not need to press any buttons to perform the calculation, it is performed automatically every time the user updates the text (I assumed this is what you wanted).
Please note this code is not good code, it uses lots of internal anonymous classes etc but it supposed to demonstrate the mechanics of how to do this.
This is the main.xml layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<EditText
android:id="#+id/a"
android:hint="input a"
android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:minWidth="60dp"/>
<EditText
android:id="#+id/b"
android:hint="input b"
android:inputType="number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:minWidth="60dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="a+b = " />
<TextView
android:id="#+id/total"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
</LinearLayout>
And this is the sample Activity:
package com.example;
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
public class SumActivity extends Activity
{
private int a;
private int b;
private TextView totalOutput;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
EditText inputA = (EditText) findViewById(R.id.a);
EditText inputB = (EditText) findViewById(R.id.b);
totalOutput = (TextView) findViewById(R.id.total);
inputA.addTextChangedListener(new TextChangedListener()
{
#Override
public void numberEntered(int number)
{
a = number;
updateTotal();
}
});
inputB.addTextChangedListener(new TextChangedListener()
{
#Override
public void numberEntered(int number)
{
b = number;
updateTotal();
}
});
}
private void updateTotal()
{
int total = a + b; // This is where you apply your function
totalOutput.setText("" + total); // need to do that otherwise int will
// be treated as res id.
}
private abstract class TextChangedListener implements TextWatcher
{
public abstract void numberEntered(int number);
#Override
public void afterTextChanged(Editable s)
{
String text = s.toString();
try
{
int parsedInt = Integer.parseInt(text);
numberEntered(parsedInt);
} catch (NumberFormatException e)
{
Log.w(getPackageName(), "Could not parse '" + text + "' as a number", e);
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
}
}
Related
Edit: I have been able to track the problem down to the use of EditText rather than TextView. The repeated calls only happen when a field is an EditText and the system behaves itself when the field is a TextView. I can find nothing in the documentation or online that indicates that LineBackgroundSpan will not work with EditText.
I have updated the MCVE to show how things work with TextView (it does) and with EditText (it doesn't - at least not well). My updated question is how to get LineBackgroundSpan working with EditText.
I have implemented a simple class to add a rounded background to text in an EditText using LineBackgroundSpan. Everything works OK but while debugging I noticed that the drawBackground method of my class is called repeatedly and, seemingly, without end for each span in the string even though no changes are being made. It is not apparent on the display, but is readily apparent if a breakpoint is set in the drawBackground method.
In trying to track down the issue, I was able to reduce the code down to an MCVE.The following code will simply highlight an entire line of text. The top line is an EditText and the bottom line is a TextView. (This is not what I am really trying to do, but it serves the purpose.)
This MCVE exhibits the problem for me on emulators running API 17 and API 24 as well as an actual phone running API 24. Setting the disableDraw argument to true for the constructor of RoundedBackgroudSpan() will disable background drawing action in drawBackground(). I am seeing the problem on the EditText even with background drawing disabled.
What is going on here? Am I misunderstanding how to work with spans? Will spans not work with EditText? Any help will be greatly appreciated.
MainActivity.java
package com.example.bgspanmcve;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.SpannableString;
import android.text.style.LineBackgroundSpan;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import static android.text.Spanned.SPAN_INCLUSIVE_INCLUSIVE;
public class MainActivity extends AppCompatActivity {
final String dispString = "XAB CD EF";
private static int count = 0; // times drawBackground is called
#Override
protected void onCreate(Bundle savedInstanceState) {
EditText editText;
TextView textView;
RoundedBackgroundSpan bg;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the EditText field with a span.
// RoundedBackgroundSpan#drawBackground will be called forever for this EditText.
editText = ((EditText) findViewById(R.id.editText));
SpannableString ssEditText = new SpannableString(dispString);
bg = new RoundedBackgroundSpan(INHIBIT_DRAWING, false);
ssEditText.setSpan(bg, 0, ssEditText.length(), SPAN_INCLUSIVE_INCLUSIVE);
editText.setText(ssEditText);
// Set up the TextView field with a span.
// RoundedBackgroundSpan#drawBackground will be called once for this TextView.
textView = ((TextView) findViewById(R.id.textView));
SpannableString ssTextView = new SpannableString(dispString);
bg = new RoundedBackgroundSpan(INHIBIT_DRAWING, true);
ssTextView.setSpan(bg, 0, ssTextView.length(), SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(ssTextView, TextView.BufferType.EDITABLE);
}
private static class RoundedBackgroundSpan implements LineBackgroundSpan {
private boolean mDisableDraw;
private boolean mIsTextView;
RoundedBackgroundSpan(boolean disableDraw, boolean isTextView) {
super();
mDisableDraw = disableDraw;
mIsTextView = isTextView;
}
#Override
public void drawBackground(
Canvas canvas, Paint paint, int left, int right, int top,
int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
count++;
if (mIsTextView) {
Log.d(TAG, "<<<<drawBackground (TextView) #" + count);
} else {
Log.d(TAG, "<<<<drawBackground (EditText) #" + count);
}
if (mDisableDraw) return;
Paint localPaint = new Paint();
RectF rect = new RectF(left, top, right, bottom);
localPaint.setColor(BG_COLOR);
canvas.drawRoundRect(rect, RADIUS_X, RADIUS_Y, localPaint);
}
private final String TAG = RoundedBackgroundSpan.class.getSimpleName();
private final int BG_COLOR = 0xfF00FF00;
private final int RADIUS_X = 20;
private final int RADIUS_Y = 20;
}
private final static String TAG = MainActivity.class.getSimpleName();
private final boolean INHIBIT_DRAWING = true;
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.example.bgspanmcve.MainActivity">
<EditText
android:id="#+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="0dp"
android:inputType="text"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:text="EditText"
android:textSize="20sp" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#id/editText"
android:layout_below="#id/editText"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:text="TextView"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
The call to drawBackground() is timed to the rate of the flashing cursor which is about 500 ms as suggested by #Suragch. I am now convinced that the call to drawBackground() is made as part of the cursor implementation.
As a quick, but not definitive test, I have set the EditText field to not show the cursor but to still be editable (android:cursorVisible="false"). When this attribute set to false, the repeated calls to drawBackground() cease.
I am implementing a epub reading app where I am using textview for showing text of epub. I want to select text from textview when user long presses on textview and then do multiple operations on selected text of textview like highlight etc..
So, How can I show those cursors to user to select text whatever user wants.
*I dont want to use EditText and make it look like textview. May be overriding textview is prefered.
*I have attached screenshot to explain what I am looking for-
This is asked long time ago, when I had this problem myself as well. I made a Selectable TextView myself for my own app Jade Reader. I've hosted the solution to GitHub. (The code at BitBucket ties to the application, but it's more complete and polished.)
Selectable TextView (on GitHub)
Jade Reader (on BitBucket)
Using the following code will make your TextView selectable.
package com.zyz.mobile.example;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends Activity {
private SelectableTextView mTextView;
private int mTouchX;
private int mTouchY;
private final static int DEFAULT_SELECTION_LEN = 5;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// make sure the TextView's BufferType is Spannable, see the main.xml
mTextView = (SelectableTextView) findViewById(R.id.main_text);
mTextView.setDefaultSelectionColor(0x40FF00FF);
mTextView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
showSelectionCursors(mTouchX, mTouchY);
return true;
}
});
mTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTextView.hideCursor();
}
});
mTextView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
mTouchX = (int) event.getX();
mTouchY = (int) event.getY();
return false;
}
});
}
private void showSelectionCursors(int x, int y) {
int start = mTextView.getPreciseOffset(x, y);
if (start > -1) {
int end = start + DEFAULT_SELECTION_LEN;
if (end >= mTextView.getText().length()) {
end = mTextView.getText().length() - 1;
}
mTextView.showSelectionControls(start, end);
}
}
}
It depends on the minimum Android version that you'd like to support.
On 3.0+, you have the textIsSelectable attribute on the TextView, which enables this behavior. E.g.:
<TextView android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="#dimen/padding_medium"
android:text="#string/hello_world"
android:bufferType="spannable"
android:textIsSelectable="true"
android:textSize="28dip"
tools:context=".MainActivity" />
Below that, you best bet is to use an EditText that looks and behaves like a TextView (apart from the slection thing). Or you can implement this feature yourself using spans.
I wonder in case there is a ready implantation for textarea view that expand as user type more text. like the android built in SMS message text area.
I got a partial answer :) - i needed an SMS Style Textfield as well, so I made one myself, including a textwatcher that tracks how many characters are left.
This is what it will look like:
The Textwatcher implementation
public class SMSTextWatcher implements TextWatcher {
private final int maxLength;
private final int stringId;
private final TextView textView;
/**
* #param maxLength maximum number of characters that are allowed
* #param stringId must have at least one %s in it, for the updated character count.
* #param targetView target text view that displays the number of characters left.
*/
public SMSTextWatcher(int maxLength, int stringId, TextView targetView) {
this.maxLength = maxLength;
this.textView = targetView;
this.stringId = stringId;
updateTextView(maxLength);
}
#Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable editable) {
//Update textview (the limit is handled by the maxLength attribute)
updateTextView(maxLength - editable.length());
}
public void updateTextView(int charactersLeft) {
textView.setText(String.format(textView.getContext().getString(stringId), charactersLeft));
}
}
The Layout XML - let's call it widget_sms_field.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/sms_field_text"
style="#style/TextAppearance.AppCompat.Large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:hint="#string/short_text"
android:imeOptions="actionSend|flagNoEnterAction"
android:inputType="textShortMessage|textAutoCorrect|textCapSentences|textMultiLine"
android:maxLength="#integer/sms_text_max_length"
android:paddingRight="10dp"
android:singleLine="false" />
<TextView
android:id="#+id/sms_field_remaining_characters"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="#string/remaining_characters"
android:textColor="#color/secondary_text" />
</LinearLayout>
The Max Length
In above layout file we used android:maxLength="#integer/sms_text_max_length"
to resolve it, we'll have to create a file called "integer.xml" in the values folder of your project. The content of the file should be as follows:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="sms_text_max_length" type="integer">160</item>
</resources>
If you name the file something other than "integer" - make sure to also change the #integer/sms_text... accordingly.
The "x characters left" Text
The little grey-colored text field(#color/secondary_text - you need to create this color yourself!) with the id sms_field_remaining_characters is the field which will display how many characters are left. For this purpose create a new string resource:
<string name="remaining_characters">%s remaining Characters</string>
Include the widget layout xml in your own layout and in your Fragment's onViewCreated method link the SMSTextWatcher to our sms-style field:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
EditText textField = (EditText) view.findViewById(R.id.sms_field_text);
textField.addTextChangedListener(new SMSTextWatcher(
getResources().getInteger(R.integer.sms_text_max_length),
R.string.remaining_characters,
(TextView) view.findViewById(R.id.sms_field_remaining_characters)));
}
Done :) ! Let me know, if you have questions or suggestions!
I'm trying to create an Android app to help to calculate split the bill if let's say you're eating out in a party of 2 people or more.
You're supposed to enter the subtotal of the bill, enter the number of people in the party, enter applicable discount if any, there are 2 checkboxes for 7% tax, and 10% service charges if it hasn't been included in the bill yet. Finally you just need to click on the "calculate button" for the app to calculate how much each person has to pay.
My Questions are:
for subtotal, it's supposed to be double instead of int, but I'm not sure how to parse String into a double. Is there a way to do this?
I'm not sure if that is the best way to activate the Checkboxes for the tax and 10% tips
When I click on the calculate button, it is supposed to display the Toast message with the result of the calculation, but nothing appears. I'm not sure if the problem is with parseInteger, checkBoxes, or if the onClick method is wrong, or all of them.
Here's the code that I wrote:
package com.kevinw.BillSplitter;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class BillSplitter extends Activity implements OnClickListener {
/** Declares XML Widgets */
private EditText numberDiners;
private EditText enterAmount;
private EditText enterDiscount;
private CheckBox gst;
private CheckBox tips;
private CheckBox cess;
double result;
private Button calculate;
private TextView resultAmount;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Initialize Widgets
numberDiners = (EditText) findViewById(R.id.numberDiners);
enterAmount = (EditText) findViewById(R.id.EnterAmount);
enterDiscount = (EditText) findViewById(R.id.EnterDiscount);
calculate = (Button) findViewById(R.id.calculate);
//Initialize CheckBoxes
gst = (CheckBox) findViewById(R.id.cbCheck1);
gst.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (gst.isChecked()) {
result = result + (0.07 * result);
}
else {
result = result;
}
}
});
tips = (CheckBox) findViewById(R.id.cbCheck2);
tips.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (tips.isChecked()) {
result = result + (0.1 * result);
}
else {
result = result;
}
}
});
}
#Override
public void onClick(View v) {
//Initialize EditTexts
String amount = enterAmount.getText().toString();
int subtotal = Integer.parseInt(amount);
String diners = numberDiners.getText().toString();
int people = Integer.parseInt(diners);
String disc = enterDiscount.getText().toString();
int discount = Integer.parseInt(disc);
double discounted = discount / 100;
result = (1 - discounted) * (subtotal / people);
switch (v.getId()) {
case(R.id.calculate):
Toast.makeText(this, "The Amount a Person has to pay: $" + result, Toast.LENGTH_LONG).show();
break;
}
}
}
and if it helps, this is the XML code for the layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/dinersView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello"/>
<TextView
android:id="#+id/Enter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/dinersView"
android:layout_alignLeft="#+id/EnterAmount"
android:text="#string/enter"/>
<EditText
android:id="#+id/numberDiners"
android:layout_height="wrap_content"
android:layout_below="#+id/dinersView"
android:layout_width="100dip"/>
<EditText
android:id="#+id/EnterAmount"
android:layout_height="wrap_content"
android:layout_below="#+id/Enter"
android:layout_toRightOf="#+id/numberDiners"
android:layout_width="220dip"/>
<TextView
android:id="#+id/Discount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/EnterAmount"
android:layout_alignLeft="#+id/EnterAmount"
android:text="#string/discount"/>
<EditText
android:id="#+id/EnterDiscount"
android:layout_height="wrap_content"
android:layout_below="#+id/Discount"
android:layout_alignLeft="#+id/Discount"
android:layout_width="220dip"/>
<CheckBox
android:id="#+id/cbCheck1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/EnterDiscount" />
<CheckBox
android:id="#+id/cbCheck2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/cbCheck1" />
<TextView
android:id="#+id/gst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/cbCheck1"
android:layout_alignTop="#+id/cbCheck1"
android:layout_alignLeft="#+id/enterDiscount"
android:layout_marginTop="10dip"
android:text="#string/GST"/>
<TextView
android:id="#+id/tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/cbCheck2"
android:layout_alignTop="#+id/cbCheck2"
android:layout_marginTop="10dip"
android:text="#string/tips"/>
<Button
android:id="#+id/calculate"
android:layout_below="#+id/cbCheck2"
android:layout_width="wrap_content"
android:text="#string/calculate"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"/>
</RelativeLayout>
Thank you for all of the help. Really appreciate it.
For string to double conversion you can use Double.valueOf("").
you need to add clicklistener to your calculator button, either add calculate.setOnClickListener(this);
or move your onClick code without switch case inside this block.
calculate.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
for subtotal, it's supposed to be double instead of int, but I'm not sure how to parse String into a double. Is there a way to do this?
Yes there is.
I'm not sure if that is the best way to activate the Checkboxes for the tax and 10% tips
That is not a question but, moving on, no, that is not the right way to write checkbox code.
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (gst.isChecked()) {
result = result + (0.07 * result);
} else {
result = result;
}
}
This code will not work as you expect it to. The price will just keep going up and up on each second tick of the checkbox. You may want to step through what will actually happen in your head or on paper and then try and rethink it.
When I click on the calculate button, it is supposed to display the Toast message with the result of the calculation, but nothing appears. I'm not sure if the problem is with parseInteger, checkBoxes, or if the onClick method is wrong, or all of them.
I think that you will find that the onClick function is never called because you have not called the setOnClickListener function. I think that might be the problem but I'm not sure.
I want to show all my validation error's of EdiText fields in a popup as shown in below image:
As far as I know Android has drawables:
1) popup_inline_error.9.png
2) popup_inline_error_above.9.png
3) indicator_input_error.png
I am able to display the red error indicator inside the right side of the EditText by using:
Drawable err_indiactor = getResources().getDrawable(R.drawable.indicator_input_error);
mEdiText.setCompoundDrawablesWithIntrinsicBounds(null, null, err_indiactor, null);
Now also i want to display the error message as shown is the first image but it seems I am not getting any idea about this, though I think it should be a Custom Toast.
As the earlier answer is solution for my problem but I have tried a different approach to use a custom Drawable image instead of default indicator_input_error image.
Default Drawable
Custom Drawable
So, I have just created two EditText in my layout xml file and then implemented some Listener in Java code on that EditText.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:padding="20dip"
android:background="#222222">
<EditText android:layout_width="match_parent"
android:layout_height="wrap_content" android:hint="Username"
android:id="#+id/etUsername" android:singleLine="true"
android:imeActionLabel="Next"></EditText>
<EditText android:layout_width="match_parent"
android:inputType="textPassword"
android:layout_height="wrap_content" android:hint="Password"
android:id="#+id/etPassword" android:singleLine="true"
android:imeActionLabel="Next"></EditText>
</LinearLayout>
EditTextValidator.java
import java.util.regex.Pattern;
import android.app.Activity;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class EditTextValidator extends Activity {
private EditText mUsername, mPassword;
private Drawable error_indicator;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setting custom drawable instead of red error indicator,
error_indicator = getResources().getDrawable(R.drawable.emo_im_yelling);
int left = 0;
int top = 0;
int right = error_indicator.getIntrinsicHeight();
int bottom = error_indicator.getIntrinsicWidth();
error_indicator.setBounds(new Rect(left, top, right, bottom));
mUsername = (EditText) findViewById(R.id.etUsername);
mPassword = (EditText) findViewById(R.id.etPassword);
// Called when user type in EditText
mUsername.addTextChangedListener(new InputValidator(mUsername));
mPassword.addTextChangedListener(new InputValidator(mPassword));
// Called when an action is performed on the EditText
mUsername.setOnEditorActionListener(new EmptyTextListener(mUsername));
mPassword.setOnEditorActionListener(new EmptyTextListener(mPassword));
}
private class InputValidator implements TextWatcher {
private EditText et;
private InputValidator(EditText editText) {
this.et = editText;
}
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (s.length() != 0) {
switch (et.getId()) {
case R.id.etUsername: {
if (!Pattern.matches("^[a-z]{1,16}$", s)) {
et.setError("Oops! Username must have only a-z");
}
}
break;
case R.id.etPassword: {
if (!Pattern.matches("^[a-zA-Z]{1,16}$", s)) {
et.setError("Oops! Password must have only a-z and A-Z");
}
}
break;
}
}
}
}
private class EmptyTextListener implements OnEditorActionListener {
private EditText et;
public EmptyTextListener(EditText editText) {
this.et = editText;
}
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_NEXT) {
// Called when user press Next button on the soft keyboard
if (et.getText().toString().equals(""))
et.setError("Oops! empty.", error_indicator);
}
return false;
}
}
}
Now I have tested it like:
For empty EditText validations :
Suppose user click on the Username field then Softkeybord opens and if user press Next key then the user will be focused to the Password field and Username field remains empty then the error will be shown like as given in below images:
For wrong input validations :
1) I type the text vikaS in Username field then error will be like as given in below image :
2) I type the text Password1 in password field then error will be like as given in below image :
Note:
Here I have used custom drawable only in case of when user left the EditText field blank and press Next key on key board but you can use it in any case. Only you need to supply Drawable object in setError() method.
try this..
final EditText editText=(EditText) findViewById(R.id.edit);
editText.setImeActionLabel("",EditorInfo.IME_ACTION_NEXT);
editText.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if(actionId==EditorInfo.IME_ACTION_NEXT){
if( editText.getText().toString().trim().equalsIgnoreCase(""))
editText.setError("Please enter some thing!!!");
else
Toast.makeText(getApplicationContext(),"Notnull",Toast.LENGTH_SHORT).show();
}
return false;
}
});
I know answer has been accepted by the asker, but none of the above worked for me.
I was able to reproduce this on my Nexus S running Android 4.0.3.
Here's how I made it work.
Create a theme with:
<style name="MyApp.Theme.Light.NoTitleBar" parent="#android:style/Theme.Light.NoTitleBar">
<item name="android:textColorPrimaryInverse">#android:color/primary_text_light
</item>
</style>
Apply MyApp.Theme.Light.NoTitleBar theme to my application / activity from manifest.
<application
android:name=".MyApp"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/MyApp.Theme.Light.NoTitleBar"
>