How do I keep track of an edittext field across PagerAdapter slides? - android

I'm using a fairly simple custom pager adapter in Android, and I'd like to keep track of the contents of the edittext fields so that each new slide retains the same text if entered. Anyone have any insight on this? I'm guessing I'll need to set up a listener for text change, but I'm unsure of where to put it. Here is my adapter:
private class CustomPagerAdapter extends PagerAdapter {
public int getCount() {
return 3;
}
public Object instantiateItem(ViewGroup collection, int position) {
LayoutInflater inflater = (LayoutInflater) collection.getContext()
.getSystemService(LAYOUT_INFLATER_SERVICE);
View view;
switch(position) {
case 0:
view = inflater.inflate(R.layout.slide0, null, false);
break;
case 1:
view = inflater.inflate(R.layout.slide1, null, false);
break;
case 2:
view = inflater.inflate(R.layout.slide2, null, false);
break;
default:
view = inflater.inflate(R.layout.slide0, null, false);
}
collection.addView(view,0);
return view;
}
#Override
public void destroyItem(ViewGroup arg0, int arg1, Object arg2) {
arg0.removeView((View) arg2);
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
mCurrentSlide = (View) object;
}
}

Ok, here is how I did it:
Set a member variable in your main class:
mText = "";
Set up a textWatcher in instantiateItem() in your adapter class:
EditText edtSlide = (EditText)view.findViewById(R.id.edtSlide);
//Set a listener for the editText that updates the member variable on keystroke.
TextWatcher tw = new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mText = s.toString();
}
};
edtSlide.addTextChangedListener(tw);
Then in the setPrimaryItem() method in your adapter class:
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
EditText text = (EditText)((View) object).findViewById(R.id.edtSlide);
text.setText(mText);
}

Create a TextWatcher and then add it to each of your EditText:
TextWatcher tw = 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) {
}
#Override
public void afterTextChanged(Editable s) {
// Save the text to some global variable
}
};
EditText et = (EditText) findViewById(R.id.editText1);
EditText et2 = (EditText) findViewById(R.id.editText2);
et.addTextChangedListener(tw);
et2.addTextChangedListener(tw);
EDIT:
In the code above there is no easy way to know which of the EditText invoked the event.
In that case you need to provide each EditText with its own TextWatcher:
et1.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) {
}
#Override
public void afterTextChanged(Editable s) {
global_string_variable_for_et1 = s.toString();
}
});
Edit2:
TextWatcher[] tw = new TextWatcher[12];
for (int i = 0; i < tw.length; i++) {
tw[i] = 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) {}
#Override
public void afterTextChanged(Editable s) {
// Save the text to some global variable array
txt_array[i] = s.toString();
}
};
}
for (int i = 0; i < et.length; i++) {7
et[i].addTextChangedListener(tw[i]);
}

I was able to get it by placing a TextWatcher as shown below.
notes = (EditText) itemView.findViewById(R.id.notesText);
TextWatcher 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) {
notedEnteredByUser = charSequence.toString();
Log.i("TEXTWATCHER", notedEnteredByUser);
}
#Override
public void afterTextChanged(Editable editable) {
}
};
notes.addTextChangedListener(textWatcher);
And inside the instantiateItem, I am using the String notedEnteredByUser.

Related

How to update TextView of custom ArrayAdapter on the basis of EditText?

I have a custom ArrayAdapter which is a horizontal LinearLayout containing 02 EditText fields and 01 TextView.....all are set to take/show numberDecimals.
All I want is that whenever a number is input in any of the EditText fields, the product of the two numbers (EditText 1 & EditText 2) is shown in TextView.
I've tried both OnFocusChangedListener and TextChangedListener but the TextView doesnt get updated during live entries. It doesnt show anything.
I'm new to programming, so cant find any other solution for that.
Thanks in advance!
Below is the Adapter code:
TextView labelView;
EditText ratioView;
EditText rateView;
TextView avgView;
public FibresAdapter(Activity context, ArrayList<Fibres> fibresList) {
super(context, 0, fibresList);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
final Fibres currentFibre = getItem(position);
labelView = (TextView) convertView.findViewById(R.id.label);
labelView.setText(currentFibre.fibreLabel);
ratioView = (EditText) convertView.findViewById(ratio);
rateView = (EditText) convertView.findViewById(R.id.rate);
avgView = (TextView) convertView.findViewById(R.id.avg);
ratioView.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) {
if (s.toString().length() > 0) {
currentFibre.fibreRatio = Double.parseDouble(s.toString());
avgView.setText("Testing");
} else {
currentFibre.fibreRatio = 0;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
rateView.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) {
if (s.toString().length() > 0) {
currentFibre.fibreRate = Double.parseDouble(s.toString());
avgView.setText("Testing");
} else {
currentFibre.fibreRate = 0;
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
return convertView;
}
Below is the code for Activity:
double totalAvg;
double totalRatio;
TextView totalAvgView;
TextView totalRatioView;
static ArrayList<Fibres> fibres;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fibres_list);
fibres = new ArrayList<>();
int x = 0;
while (x < Fibres.fibCatArray.length) {
fibres.add(new Fibres(Fibres.fibCatArray[x]));
x++;
}
ListView listView = (ListView) findViewById(R.id.list);
FibresAdapter adapter = new FibresAdapter(this, fibres);
listView.setAdapter(adapter);
totalRatioView = (TextView) findViewById(R.id.total_ratio);
totalAvgView = (TextView) findViewById(R.id.total_avg);
}
public void displayTotals() {
totalRatio = 0;
totalAvg = 0;
for (Fibres materials : fibres) {
totalRatio += materials.fibreRatio;
totalAvg += (materials.fibreRatio / 100 * materials.fibreRate);
}
totalRatioView.setText(totalRatio + "");
totalAvgView.setText(totalAvg + "");
}
public boolean validateData() {
if (totalRatio != 100) {
Toast.makeText(this, "Total should be 100%!", Toast.LENGTH_SHORT).show();
return false;
}
for (Fibres materials : fibres) {
if (materials.fibreRatio > 1 && materials.fibreRate <= 0) {
Toast.makeText(this, "Enter both Ratio & Rate!", Toast.LENGTH_SHORT).show();
return false;
}
}
return true;
}
In your adapter add addTextChangedListener to both EditText and use textView.setText() inside that. Something like this.
editText1.addTextChangedListener(new TextWatcher() {
#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)
textView.setText("");
}
});

Fundapter list view filtering error

I'm trying to do a search function in the list view and I'm using Fundapter and not normal Adapter. However when I try to type something into the edit text, I get:
Attempt to invoke virtual method 'void android.widget.Filter.filter(java.lang.CharSequence)' on a null object reference
This is my code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view, container, false);
final ArrayList<Participants> participants = new ArrayList<>();
//then i hardcoded the participants data...
//participants.add(p1);
BindDictionary<Participants> dictionary = new BindDictionary<>();
dictionary.addStringField(R.id.tvName, new StringExtractor<Participants>() {
#Override
public String getStringValue(Participants participants, int position) {
return participants.getName();
}
});
dictionary.addStringField(R.id.tvCompany, new StringExtractor<Participants>() {
#Override
public String getStringValue(Participants participants, int position) {
return participants.getCompanyName();
}
});
dictionary.addStringField(R.id.tvNRIC, new StringExtractor<Participants>() {
#Override
public String getStringValue(Participants participants, int position) {
return participants.getNRIC();
}
});
final FunDapter adapter = new FunDapter(ViewFragment.this.getActivity(), participants, R.layout.participants_layout, dictionary);
ListView lvParticipants = (ListView) view.findViewById(R.id.lvParticipants);
lvParticipants.setAdapter(adapter);
etSearch = (EditText) view.findViewById(R.id.etSearch);
etSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
adapter.getFilter().filter(s);
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
}
});
lvParticipants.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Participants selectedParticipants = participants.get(position);
Toast.makeText(ViewFragment.this.getActivity(), selectedParticipants.getName(), Toast.LENGTH_SHORT).show();
}
});
return view;
}
Shouldn't it be onTextChnaged(), you are doing your operation in beforeTextChnaged()... look into it.

how to make the EditText value persistent in a scrollable listview

I have a listview consists of TextView, EditText and Checkbox. I am want to make the state of the edittext to be persistent so that, when i change the text
inside the edittext and then scroll the listview up or down that text that was added/written into the edittext should not be changed and must remain as it is
I managed to make the checkbox persistent, I do not know how to make the edittext state persistent.
please have a look at the getView() methos it is posted below
and please let me know how to solve this issue
getView
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = null;
if (convertView == null) {
LayoutInflater layoutinflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
view = layoutinflater.inflate(R.layout.model, null);
final ViewHolder holder = new ViewHolder();
holder.tv = (TextView) view.findViewById(R.id.tv);
holder.cb = (CheckBox) view.findViewById(R.id.cb);
holder.et = (EditText) view.findViewById(R.id.et);
holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
ItemDesign element = (ItemDesign) holder.cb.getTag();
element.setChecked(buttonView.isChecked());
}
});
view.setTag(holder);
holder.cb.setTag(designList.get(position));//checkbox
//edittext
ItemDesign element = (ItemDesign) holder.et.getTag();
if (element != null) {
element.setEtTxt(holder.et.getText().toString());
}
holder.et.setTag(designList.get(position));
holder.tv.setTag(designList.get(position));//textview
} else {
view = convertView;
((ViewHolder)view.getTag()).et.setTag(designList.get(position));//edittext
((ViewHolder)view.getTag()).tv.setTag(designList.get(position));//textview
((ViewHolder)view.getTag()).cb.setTag(designList.get(position));//checkbox
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.tv.setText(designList.get(position).getTxt()); //textview
holder.cb.setChecked(designList.get(position).isChecked());//checkbox
//edittext
String etTxt = holder.et.getText().toString();
designList.get(position).setEtTxt(etTxt);
holder.et.setText(designList.get(position).getEtTxt());
return view;
}
private class ViewHolder {
TextView tv;
CheckBox cb;
EditText et;
}
You should add a TextWatcher to your edit text and use that to track the text inputted to the textview.
holder.et.setTag(designList.get(position));//edittext
holder.et.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) {
ItemDesign element = (ItemDesign) holder.cb.getTag();
element.setEditTextValue(s.toString())
}
if I understood you correctly, you need to register TextWatcher in your EditText and save string value every time, when you change text in it. So you will need to update you part of code from:
String etTxt = holder.et.getText().toString();
designList.get(position).setEtTxt(etTxt);
holder.et.setText(designList.get(position).getEtTxt());
to (sorry, I don't know what time of element do you have in designList, but let it be, for example, type Item, you can past your type instead of it):
final Item designItem = designList.get(position);
holder.et.setText(designItem.getEtTxt());
holder.et.addTextChangedListener(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) {
designItem.setEtTxt(editable.toString);
}
});
But be careful. This solution is not working yet, since you have register new and new watchers but don't clear old. There is no perfect solution in this situation for me, since EditText doesn't have something like clearTextChangedListeners(). But you can solve it with introducing your own EditText (copied from here):
public class ExtendedEditText extends EditText {
private ArrayList<TextWatcher> mListeners = null;
public ExtendedEditText(Context ctx) {
super(ctx);
}
public ExtendedEditText(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
public ExtendedEditText(Context ctx, AttributeSet attrs, int defStyle) {
super(ctx, attrs, defStyle);
}
#Override
public void addTextChangedListener(TextWatcher watcher) {
if (mListeners == null) {
mListeners = new ArrayList<TextWatcher>();
}
mListeners.add(watcher);
super.addTextChangedListener(watcher);
}
#Override
public void removeTextChangedListener(TextWatcher watcher) {
if (mListeners != null) {
int i = mListeners.indexOf(watcher);
if (i >= 0) {
mListeners.remove(i);
}
}
super.removeTextChangedListener(watcher);
}
public void clearTextChangedListeners() {
if (mListeners != null) {
for (TextWatcher watcher : mListeners) {
super.removeTextChangedListener(watcher);
}
mListeners.clear();
mListeners = null;
}
}
}
After that final solution will look like this:
final Item designItem = designList.get(position);
holder.et.clearTextChangedListeners();
holder.et.setText(designItem.getEtTxt());
holder.et.addTextChangedListener(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) {
designItem.setEtTxt(editable.toString);
}
});
Where et will be of type ExtendedEditText instead of EditText.

Getting item position in AutoCompleteTextView addTextChangeListener method

I have Autocomplete textviews in my custom adapter. when i write something in onTextChange listener, i want to get item position. I it gives all items positions. Please help me regarding this issue. Thanks!
autoCompleteTextView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long rowId) {
String selection = (String)parent.getItemAtPosition(position);
//TODO Do something with the selected text
}
});
This is how you can get position of Item you typed in AutoCompleteTextView. But you have to add the full name of item like "apple" or "apples" then this code will give you the position of that particular item. But its very expensive process if you have lots of items in your list.
public class Test extends AppCompatActivity {
private AutoCompleteTextView autoCompleteTextView;
private List<String> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chintan_test);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
list = new ArrayList<>();
list.add("Apple");
list.add("Apples");
list.add("Banana");
list.add("Aunt");
list.add("Orange");
autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
autoCompleteTextView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list));
autoCompleteTextView.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) {
for (String string : list)
if (string.toLowerCase().equals(s.toString().toLowerCase())) {
int pos = list.indexOf(string);
Toast.makeText(Test.this, "" + pos, Toast.LENGTH_SHORT).show();
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
Let me know if this code helps you.
Use textwatcher, implement it in activity class.
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
hi can you please check there is some issue
AutoCompleteTextView tv = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);
final ArrayList<Student> list = new ArrayList<MainActivity.Student>();
list.add(new Student("abc"));
list.add(new Student("abc"));
ArrayAdapter<Student> adapter = new ArrayAdapter<MainActivity.Student>(
this, android.R.layout.simple_dropdown_item_1line, list);
tv.setAdapter(adapter);
tv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Student selected = (Student) arg0.getAdapter().getItem(arg2);
Toast.makeText(MainActivity.this,
"Clicked " + arg2 + " name: " + selected.name,
Toast.LENGTH_SHORT).show();
}
});
for more checking you can go from here...
you can use addTextChangedListener for this purpose
yourAutoCompleteTextView.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) {
}
#Override
public void afterTextChanged(Editable s) {
} });

How to add editText to listView with onTextChange?

I'm trying to create a listView with 2 editText on each row, that are using TextWatcher interface for recognizing if we changes the current text on the editText
My problem is that my adapter is very very laggy and slow. how can i handle this issue ?
here is my adapter:
public class AccountListInfoAdapter2 extends BaseAdapter {
private Activity mContext;
private ArrayList<ModelClass> accounts;
private DisplayImageOptions options;
private LayoutInflater inflater;
private prevClass mainActivityFragment;
private ViewHolder holder;
public AccountListInfoAdapter2(Activity activity, ArrayList<ModelClass> mAccountListData, prevClass mainActivityFragment) {
this.mContext = activity;
this.accounts = mAccountListData;
this.mainActivityFragment = mainActivityFragment;
inflater = LayoutInflater.from(mContext);
}
#Override
public int getCount() {
if (accounts == null) {
return 0;
} else
return accounts.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
view = inflater.inflate(R.layout.account_info_row, parent, false);
holder = new ViewHolder();
assert view != null;
setViews(view);
view.setTag(holder);
holder.emailAddress.setText(accounts.get(position).getEmail());
holder.fullName.setText(accounts.get(position).getFullName());
holder.fullName.setId(position);
holder.emailAddress.setId(position);
//Check if full name has been changed
holder.fullName.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) {
if (s.length() != count) {
if (!accounts.get(position).getFullName().equals(s.toString())) {
accounts.get(position).setFullName(s.toString());
}
}
}
#Override
public void afterTextChanged(Editable s) {
if (!accounts.get(position).getFullName().equals(s.toString())) {
accounts.get(position).setFullName(s.toString());
}
}
});
//Check if email name has been changed
holder.emailAddress.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) {
if(s.length() != count) {
if (!accounts.get(position).getEmail().equals(s.toString())){
accounts.get(position).getEmail(s.toString());
}
}
}
#Override
public void afterTextChanged(Editable s) {
if (!accounts.get(position).getEmail().equals(s.toString())) {
accounts.get(position).getEmail(s.toString());
}
}
});
return view;
}
public static class ViewHolder {
TextView emailAddress;
EditText fullName;
}
public void setViews(View view){
holder.emailAddress = (EditText) view.findViewById(R.id.accountInfoProfileEmailAddress);
holder.fullName = (EditText) view.findViewById(R.id.accountInfoFullName);
}
}
holder.fullName.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) {
if (s.length() != count)
{
if (!accounts.get(position).getFullName().equals(s.toString())) {
//accounts.get(position).setFullName(s.toString());
((MainActivity)context).changeListViewItem(position , s.toString);
}
}
}
#Override
public void afterTextChanged(Editable s) {
if (!accounts.get(position).getFullName().equals(s.toString())) {
//accounts.get(position).setFullName(s.toString());
((MainActivity)context).changeListViewItem(position , s.toString);
}
}
});
Add this function on main activity
public void changeListViewItem(int position , String text)
{
Log.e("" , ""+position);
Log.e("" , ""+text);
refreshAdapter();
}
1.addTextChangedListener can be add repeat.
U can try to add a log in onTextChanged.
Watch how many times it logs when u type a char.
When u use addTextChangedListener, add a tag.
2.U should try to use ViewHolder to help u.

Categories

Resources