问题
I have a DialogFragment
and in it's layout I have a EditText
and a ListView
. The Listview basically shows the list of contacts (Initially this list has 0 items). When the edittext
's value is updated I populate the list with contacts that have the text
typed in the EditText
.
On the EditText
I have used a addTextChangedListener
to update the list with desired contacts as the user types in a name or email address of the contact.
The weird problem I am facing is that the list (or maybe the layout) gets updated only when I press the back button to hide the keyboard after typing. As long as the soft keyboard is showing the the list does not get updated (Except for the very first time when items are added to the empty list).
Following is some of the code for better understanding.
CustomDialogFragment.java
(in onCreateView):
// Set list adapter for contacts list
contactsList = (ListView) shareView.findViewById(R.id.contactList);
emailContactAdapter = new EmailContactAdapter(getActivity(), emailContacts, shareFragment);
contactsList.setAdapter(emailContactAdapter);
// Implement Phone-book contact share
sendToInput = (EditText) shareView.findViewById(R.id.contact_name);
sendToInput.addTextChangedListener(onContactNameSearch);
in onContactNameSearch (TextWatcher):
public TextWatcher onContactNameSearch = new TextWatcher() {
private generics commonMethods = new generics();
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
emailContacts.clear();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
Log.d("DEBUG::REACH", "After Text Changed called");
String textValue = s.toString();
// Show or hide the share apps list based on user input
// and whether or not the list is already showing or not
if (textValue.equals("")) {
Log.d("DEBUG::REACH", "TEXT value is empty");
showAppList();
emailContacts.clear();
} else {
Log.d("DEBUG::REACH", "TEXT has value");
// Hide app list if visible
if (isAppListShowing()) hideAppList();
// Get the email contacts list based on the user query
emailContacts.addAll(commonMethods.getEmailContacts(appContext, textValue));
}
adapter.notifyDataSetChanged();
}
My assumption is that the list adapter's list is correctly updated but due to some reason the layout does not reflect the new changes until the soft keyboard is hidden.
Questions:
- Has anyone faced a similar issue before (Could not find any resources while googling :/) ?
- Why does this happen ?
- Is there anything related to this in the official docs ?
- What's the best way to resolve this ?
PS: The code in the afterTextChanged
method was previously in the onTextChanged
method and I was facing the same issue.
UPDATE (Added screenshots for better understanding)
The following is when the dialog fragment is shown and no text has been typed in the edittext.
Now when I type in "A" and the list populates.
I add another few letters but the list does not update. I added letters "mit" so now the query becomes "Amit" but no change in the list.
Now when I press the hardware back button on the device to hide the keyboard. The keyboard is hidden and the list is updated.
(Please do not mind the overlapping contact names and emails, still have to fix the layout :P)
UPDATE2 (Adding EmailContactAdapter code)
Following is the EmailContactAdapter class
public class EmailContactAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<EmailContact> contacts;
private ProductShareFragment fragment;
private LayoutInflater inflater;
/**
* Constructor
*/
public EmailContactAdapter(Activity activity, ArrayList<EmailContact> contacts, ProductShareFragment fragment) {
this.activity = activity;
this.contacts = contacts;
this.fragment = fragment;
}
@Override
public int getCount() {
return contacts.size();
}
@Override
public Object getItem(int position) {
return contacts.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null) {
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = inflater.inflate(R.layout.email_contact_list_row, null);
}
EmailContact contact = contacts.get(position);
ImageView contactImage = (ImageView) convertView.findViewById(R.id.email_contact_image);
TextView contactName = (TextView) convertView.findViewById(R.id.email_contact_name);
TextView contactEmail = (TextView) convertView.findViewById(R.id.email_contact_email);
// contactImage.setImageBitmap(contact.getImage());
contactName.setText(contact.getName());
contactEmail.setText(contact.getEmail());
return convertView;
}
}
回答1:
You are trying to change visible list with changing emailContacts
, but adapter still contains old list data.
Solution: after each new text in EditText
create new adapter (is a VERY bad way), or create method in EmailContactAdapter
to replace items - in your case contacts
field.
回答2:
In the below code, you are populating the list with the result of commonMethods.getEmailContacts
// Get the email contacts list based on the user query
emailContacts.addAll(commonMethods.getEmailContacts(appContext, textValue));
Surely you first need to do emailContacts.Clear()
otherwise the list is not going to change?
回答3:
Try delete all emailContacts.clear();. Then add emailContacts.clear(); just before emailContacts.addAll(commonMethods.getEmailContacts(appContext, textValue));. You are appending your list for every letter your typed.
来源:https://stackoverflow.com/questions/30217317/listview-does-not-update-until-keyboard-is-hidden