I have four EditText boxes that together make up a value. Each box should contain 1 number. When I enter a number into one box the focus should move to the next box. I have "faked" a link between the boxes by modifying the focus when the text is changed. The following code works but I want to allow for the user to paste in values that will then be split across the EditText boxes. So if I paste "123" in box[0], box[0] should contain "1" and box[1] should contain "2" etc. I attempted to add android:maxLength="1" to the XML but when I attempt to paste content, the maxLength validation removes all but the first character.
What is the best way to split the contents of a paste across the 4 EditText boxes?
EnterNumberLayout.java
public class EnterNumberLayout extends LinearLayout {
EditText[] textBoxes;
public static final int NUMBER_OF_ENTRIES = 4;
public EnterNumberLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOrientation(HORIZONTAL);
textBoxes = new EditText[NUMBER_OF_ENTRIES];
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
for (int i = 0; i < NUMBER_OF_ENTRIES; i++){
EditText et = (EditText) inflater.inflate(R.layout.number_box, null);
//et.setOnKeyListener(new BackspaceKeyListener(et));
et.addTextChangedListener(new MoveFocusWatcher(et));
et.setTag(i);
textBoxes[i] = et;
this.addView(et, i);
}
}
private class MoveFocusWatcher implements TextWatcher {
private View view;
public MoveFocusWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if ((int) this.view.getTag() < NUMBER_OF_ENTRIES - 1) {
(textBoxes[(int) this.view.getTag() + 1]).requestFocus();
}
}
public void afterTextChanged(Editable s) {}
}
}
number_box.xml
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number|none"
android:ellipsize="start"
android:gravity="center_horizontal|center_vertical"
android:imeOptions="actionNext"/>
There are probably a few ways to do this, but I'd probably remove the text limit of 1 on the edit text and manage the length with a text watcher.
Here, if text is pasted into the first edit1 then the text watcher will split the values up into the other edit text fields. You need to be careful when changing text in the afterTextChanged callback since the change will initiate another call to the method. Since the text length in edit1 is only one after our processing, the next callback does nothing.
public class TextGroup extends LinearLayout {
EditText edit0;
EditText edit1;
EditText edit2;
EditText edit3;
public TextGroup(Context context, AttributeSet attrs) {
super(context);
View view = LayoutInflater.from(context).inflate(R.layout.edit_text_special, null);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
edit0 = (EditText) view.findViewById(R.id.edit_text0);
edit1 = (EditText) view.findViewById(R.id.edit_text1);
edit2 = (EditText) view.findViewById(R.id.edit_text2);
edit3 = (EditText) view.findViewById(R.id.edit_text3);
edit1.addTextChangedListener(watcher);
this.addView(view, lp);
}
TextWatcher watcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable editable) {
if ( edit1.getText().length() >= 3) {
edit3.setText(String.valueOf(edit1.getText().toString().charAt(2)));
}
if ( edit1.getText().length() >= 2) {
edit2.setText(String.valueOf(edit1.getText().toString().charAt(1)));
edit1.setText(String.valueOf(edit1.getText().toString().charAt(0)));
}
}
};
}
Related
I want to convert choosen element to Integer. When it's done I want to add a random number between 1-20 to choosen Integer. Than show up that number in Toast.
To convert a value coming from a TextView to an integer, you just need to use the following code:
EditText tViewNum = (EditText) rootView.findViewById(R.id.number);
String strWord = tViewNum.getText().toString();
Random r = new Random();
int i1 = r.nextInt(21 - 1) + 20;
String Randomiser = strWord + " " + il; //the +" "+ is used to add a space between the word and the random number.
Toast.makeText(MainActivity.this, Randomiser + "//any other text you wish to include", Toast.LENGTH_SHORT).show();
Note that the random number given here is between 1 (inclusive) and 20 (inclusive).
use a widget forAutoCompleteTextView.
"CustomAutoCompleteTextView"
public class CustomAutoCompleteTextView extends AutoCompleteTextView {
public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void performFiltering(final CharSequence text, final int keyCode) {
// String filterText = "";
super.performFiltering(text, keyCode);
}
/**
* After a selection, capture the new value and append to the existing
* text
*/
#Override
protected void replaceText(final CharSequence text) {
super.replaceText(text);
}
}
Your Xml will be like this:[Depend where you add your widget ]
<com.example.widget.CustomAutoCompleteTextView
android:id="#+id/sent_message_to"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_margin="10dip"
android:layout_weight="1"
android:imeOptions="actionSend"
android:hint="name"
android:gravity="left|center"
android:padding="10dip"
android:textColor="#color/green"
android:textSize="18dp"
android:visibility="visible"
android:selectAllOnFocus="true"
android:inputType="textPersonName"
android:completionThreshold="3"
/>
Main class
you can set adapter for list value or declare array
private AutoCompleteAdapter mAutoCompleteAdapter;
private ArrayList<String> mArray = new ArrayList<String>();
private CustomAutoCompleteTextView mAutoFillTextView;
.....
mAutoFillTextView = mViewUtils.createAutoFillTextView(view.findViewById(R.id.sent_message_to), false);
mAutoCompleteAdapter = new AutoCompleteAdapter(getActivity(), mArray);
mAutoFillTextView.setAdapter(mAutoCompleteAdapter);
and
mAutoFillTextView.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(final CharSequence s, int start, int before, int count) {
try {
mArray.clear();
String string = s.toString().trim();
if (mAutoFillTextView.getThreshold() <= string.length() && mAllowRequest) {
//GET DATA TO LIST
}
} catch (NullPointerException ignored) {
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
I have a problem with EditText-fields in a listview. After i scroll some settings seem to be reset (selectAllOnFocus) and the selection cursor goes bananas.
I have a listview with a custom ArrayAdapter and a custom dataobject. In this case the object only holds one String (to simplify it).
My Activity
// adapter + content
List<ListviewObject> listViewContent = new ArrayList<ListviewObject>();
for(int i = 0; i < 50; i++) {
listViewContent.add(new ListviewObject("num: " + i));
}
adapter = new CustomListAdapter(AddNewPerson.this, R.layout.list_item, listViewContent);
// list
ListView mListView = (ListView)findViewById(R.id.sample_list);
mListView.setItemsCanFocus(true);
mListView.setAdapter(adapter);
My Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
HolderObject holder = null;
if(convertView == null) {
convertView = mLayoutInflater.inflate(layoutResourceId, parent, false);
holder = new HolderObject();
holder.name = (TextView) convertView.findViewById(R.id.txt);
convertView.setTag(holder);
} else {
holder = (HolderObject) convertView.getTag();
}
holder.lvObject = items.get(position);
setNameTextChangeListener(holder);
// Retrieve the correct value
holder.name.setText(holder.lvObject.getName());
return convertView;
}
public static class HolderObject {
ListviewObject lvObject;
TextView name;
}
private void setNameTextChangeListener(final HolderObject holder) {
holder.name.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Update the value
holder.lvObject.setName(s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) { }
});
}
To fix all the focusproblems I found in other threads I've set:
.setItemsCanFocus(true) on the listview
android:descendantFocusability="beforeDescendants" in the activity XML
android:windowSoftInputMode="adjustPan" in the manifest XML
Focussing and editing text works fine. When I scroll the correct values are held and all this seems to work fine.
Before I scroll and I click on some of the EditTexts this happens. (Last focused blurs, clicked one focuses, content is selected)
http://imgur.com/eeIKhCv
After I scroll down and up again, and do the same clicks as before, this happens.
http://imgur.com/75mjPc3
This is due to listView recycling mechanism. To know more about listview recycling mechanism you can refer this link
in your case you avoid the problem by storing a last focused editText and In getView set focus to only last stored integer and skip other position. hope this help you...
It's quite easy:
Declare a String[] to keep track each EditText's input inside the afterTextChanged() of "addTextChangedListener().
Becareful of the order:
viewHolder.editText.removeTextChangedListener(viewHolder.textWatcher);
viewHolder.textWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
mInputs[position] = editable.toString(); //record input
viewHolder.editText.setSelection(viewHolder.editText.getText().length()); //set cursor to the end
}
};
viewHolder.editText.addTextChangedListener(viewHolder.textWatcher);
viewHolder.editText.setText(mInputs[position]);
Add android:windowSoftInputMode="adjustPan" to your Activity in AndroidManifest file.
Good luck!
I have a custom list with one textView and one
edit text in each row. My question is: whenever user enters
any number inside the edittext,at that time i want to take the
value from the edittext and add it with the previous value and
displayed in the top textview.
For eg. Say inside number of edittext i entered 10 in any
edittext. 10is the first number entered.then it is going to add
with 0.after that if he enter 15 in another edittext,then 10+15 = 25
should be displayed in the top textview.
I got it...
That was as simple as using setOnFocusListener. If the focus gets lost from the edit text.at that the boolean hasFocus parameter gets false. and we can easily collect the value inside the edit text. But thanks for you support guys. Thanks 1ce again.
try this
String content = edtEditText.getText().toString();
tvTextView.setText(content);
You have to Use A TextWatcher on the EditText View like this for That:
EditText editText1 = (EditText) findViewById(R.id.e1);
TextWatcher checker = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (ChecknotNull()) {
TextView1.setText(edittext1.getText().toString().trim());;
Note: You can Also Go on Concating the values with the
previous values Of the TextView(InShort,Perform Logic Here)
}
}
private boolean ChecknotNull() {
return editText1.getText().toString().trim().length() > 0;
}
};
//Set the checker method for the EditText View like this Way
editText1.addTextChangedListener(checker);
I am not sure,this would help...but you can try with this:
Get a setOnFocusListener on your edit text like:
mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View arg0, boolean arg1) {
int s=Integer.parseInt(mEditText.getText().toString());
int ps=Integer.parseInt(mTextView.getText().toString());
mTextView.setText((s+ps)+"");
mEditText.setText("");// clear editText after adding its value to textview
}
});
don't forget to empty the edittext when focus is gone,otherwise when user would click onto edittext even to delete previous one,value would again be added to your textview.
In the Adapter, do this:
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder = new ViewHolder();
p = values.get(position);
if (vi == null) {
vi = inflater.inflate(R.layout.feed_items, null);
holder.text = (TextView) vi.findViewById(R.id.tv);
holder.editText = (EditText) vi.findViewById(R.id.et);
holder.editText.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s) {
i++;
int n = Integer.parseInt(holder.text.getText().toString());
int m = Integer.parseInt(s.getText().toString());
holder.text.setText("" + n + m);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
return vi;
}
i have a structure like this in my ListView
TextView EditText
TextView EditText
TextView EditText
Btton
when i click on ok button. how to retrieve value from each EditText and print Sum of it on dialog box...any idea....?
Assuming your row layout is something like
LinearLayout
- TextView
- Edittext
You can use something like
for(int i =0;i<getListView.getChildCount();i++){
LinearLayout layout = getListView.getChildAt(i);
String text = layout.getChildAt(1).getText();
}
I would do it this way
Inside my ListAdapter, while creating rows, save a reference to list view in an ArrayList
On click of the button, get the array list from the adapter and iterate through all edittexts
Check out TextWatcher. Add it using:
myEditText1.addTextChangedListener(new GenericTextWatcher(myEditText1));
myEditText2.addTextChangedListener(new GenericTextWatcher(myEditText2));
myEditText3.addTextChangedListener(new GenericTextWatcher(myEditText3));
...
private class GenericTextWatcher implements TextWatcher{
private View view;
private GenericTextWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void afterTextChanged(Editable editable) {
String text = editable.toString();
switch(view.getId()){
case R.id.editText1_id:
// do something
break;
case R.id.editText2_id:
// do something
break;
case R.id.editText3_id:
// do something
break;
}
}
}
In my Appliaction I use a CursorAdapter. This displays a list, which is part of a RelativeLayout. This List includes several elements(TextView, Button, EditText). The EditText does not normally appear on the screen.The problem: I import any data to a EditText and scroll the screen. In this moment I see the imported data in another EditText. OR:
Another case. There are 3 EditText. I use the virtual Keyboard (For example use the second editText). I get in the data to the Edit Text. Push the Back Button. And the data goes to the Edit Text below. (So the data go to the third Edit Text)
Here is the CursorAdapter Code:
class OOSListadapter extends CursorAdapter{
OOSListadapter(Cursor c){
super(OOS.this,c);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
OOSRow newRow = (OOSRow)view.getTag();
newRow.populateRow(cursor);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater=getLayoutInflater();
View row=inflater.inflate(R.layout.oos_row, parent, false);
OOSRow newRow = new OOSRow(row);
row.setTag(newRow);
return (row);
}
}
And here is one row from my application list.
class OOSRow {
private TextView row_Action = null;;
private TextView row_Must = null;;
private TextView row_Lack = null;;
private TextView row_itemName = null;;
private EditText row_price = null;;
private Button row_detail = null;
private View row = null;
OOSRow (View row){
this.row = row;
row_Action = (TextView)row.findViewById(R.id.oos_row_SignalA);
row_Must = (TextView)row.findViewById(R.id.oos_row_SignalK);
row_Lack = (TextView)row.findViewById(R.id.oos_row_SignalO);
row_itemName = (TextView)row.findViewById(R.id.oos_row_itemLabel);
row_price = (EditText)row.findViewById(R.id.oos_row_EditText);
row_detail = (Button)row.findViewById(R.id.oos_row_detailButton);
}
void populateRow (Cursor c){
Cursor specCursor = dbLoc.Query("SELECT PRICE, LACK, ORDERED FROM ORDERED WHERE ITEMID='"+ c.getString(1) +"'", null);
specCursor.moveToFirst();
row_itemName.setText(c.getString(2));
row_itemName.setContentDescription(c.getString(1));
if (specCursor.getString(1).toString().equals("Y")){
row_itemName.setBackgroundColor(Color.parseColor("#FF0000"));
row_itemName.setTextColor(Color.parseColor("#FFFFFF"));
}else{
row_itemName.setBackgroundColor(Color.parseColor("#000000"));
row_itemName.setTextColor(Color.parseColor("#FFFFFF"));
}
row_itemName.setOnClickListener(SelectedLackItem);
if (c.getString(5).toString().equals("I")){
row_Action.setTextColor(Color.parseColor("#000000"));
row_Action.setBackgroundColor(Color.parseColor("#FF0000"));
}
else{
row_Action.setTextColor(Color.parseColor("#FFFFFF"));
row_Action.setBackgroundColor(Color.parseColor("#000000"));
}
if (c.getString(4).toString().equals("I")){
row_Must.setTextColor(Color.parseColor("#000000"));
row_Must.setBackgroundColor(Color.parseColor("#00FF00"));
}
else{
row_Must.setTextColor(Color.parseColor("#FFFFFF"));
row_Must.setBackgroundColor(Color.parseColor("#000000"));
}
specCursor = dbLoc.Query("SELECT LACK FROM LASTORDERED WHERE ITEMID='"+c.getString(1)+"' AND COMPANYID ='"+dbLoc.GetCompanyId()+"'", null);
if (specCursor.moveToFirst())
{
if (specCursor.getString(0).toString().equals("I")){
row_Lack.setTextColor(Color.parseColor("#000000"));
row_Lack.setBackgroundColor(Color.parseColor("#0000FF"));
}else{
row_Lack.setTextColor(Color.parseColor("#FFFFFF"));
row_Lack.setBackgroundColor(Color.parseColor("#000000"));
}
}
row_detail.setOnClickListener(OpenDetailScreenButton);
row_detail.setContentDescription(c.getString(1));
row_price.setContentDescription(c.getString(1));
row_price.setInputType(0);
/*row_price.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
row_price.setInputType(InputType.TYPE_CLASS_NUMBER);
}
#Override
public void afterTextChanged(Editable s) {
}
});*/
specCursor.close();
specCursor = null;
}
}
And some pictures:
After Back Button:
Any Idea?
I had a very similar problem. The following solution helped me:
<activity android:name= ".yourActivity" android:windowSoftInputMode="adjustPan"/>