Android: why is CardView not updating with new use

2019-01-29 08:32发布

问题:

I have a RecyclerView that creates CardViews from user input (via two EditTexts).

I am able to create the new Cards properly. The first CardView shows the two user input fields correctly. When I create the second CardView it shows up correctly on the layout but the two data input fields are not correct. Instead of showing the second set of two user inputs, the second CardView shows the exact same two user inputs from the first CardView.

Somehow after creating the first CardView I need to clear the String objects in the intents that are set to the onActivityResult() in the RecyclerView activity. Then set the next user inputs to the next CardView. Not sure why but Android Studio also says setSurname in Contact class is never used even though it is used in the Adapter's onBindViewHolder method.

Do I need to use onStop() method to complete the onClickSave method and destroy the CardViewActivity once the user is done inputing data in the EditText fields? What am I missing here?

CardViewActivity file where user enters input:

...
public void onClickSave(View v) {
    final int stringToDo = cListenerEditText.getText().toString().replace(" ", "").length();
    // if only the two user input fields have data
    else if (stringToDo > 0 && stringNotes1 > 0 ) {
        InputMethodManager imm = (InputMethodManager)
                getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(cListenerEditText.getWindowToken(), 0);
        String doMessage = cListenerEditText.getText().toString();
        String note1Message = dListenerEditText.getText().toString();
        Intent intent = new Intent();
        intent.putExtra("MESSAGE1", doMessage);
        intent.putExtra("MESSAGE2", note1Message);
        setResult(1, intent);
        finish();
    }    

// If only stringToDo has data and others are empty.
    else if (stringToDo > 0 && stringNotes1 == 0 && stringNotes2 == 0 &&
            stringDueDate == 0 && stringDueTime ==0) {
        InputMethodManager imm = (InputMethodManager)
              getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(cListenerEditText.getWindowToken(), 0);
        String doMessage = cListenerEditText.getText().toString();
        Intent intent = new Intent();
        intent.putExtra("MESSAGE1", doMessage);
        setResult(1, intent);
        finish();
    }

RecyclerView Activity file:

...  
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
    super.onActivityResult(requestCode,resultCode,data);
    if(requestCode==1) {
        String doMessage=data.getStringExtra("MESSAGE1");
        String note1Message=data.getStringExtra("MESSAGE2");
        Contact contact = new Contact(doMessage,note1Message);
        mContactsAdapter.addItem(contact);
        mRecyclerView.scrollToPosition(0);            
    }
}  

Adapter:

...
public class ListContactsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...
private List<ListItem> buildItemsList() {
    List<ListItem> items = new ArrayList<>();
    if (mContacts.size() > 0) {
        for (Contact contact : mContacts) {
            items.add(new ContactItem(contact));
        }
    } else {
            for (int i=0; i<1; i++) {
            items.add(new EmptyItem());
        }
    }
    return items;
}

public void addItem(Contact contact) {
    if (mContacts.size()==0) {
        mItems.clear();
        notifyDataSetChanged();
    }
    mContacts.add(contact);
    mItems.add(new ContactItem(contact));
    notifyItemInserted(0);
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, final int position) {
    int type = getItemViewType(position);
    if (type == ListItem.CONTACT_TYPE) {
        ContactItem item = (ContactItem) mItems.get(position);
        final Contact contact = item.getContact();
        ContactViewHolder holder = (ContactViewHolder) viewHolder;
        holder.cardBlankText2.setText(contact.getName() + " " + contact.getSurname());
    }
}

Data Model file:

public class Contact {

private String name;
private String surname;

public Contact(String name, String surname) {
    this.name = name;
    this.surname = surname;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getSurname() {
    return surname;
}

public void setSurname(String surname) {
    this.surname = surname;
}
}

回答1:

Looking at your code I see a problem with implementation of addItem method here:

mItems.add(new ContactItem(contact));
notifyItemInserted(0);

It seems you are adding item on bottom and notify insertion on top. You should keep insertion and notification aligned in terms of position. In particular, if you want to insert on top you should change your code as follows:

mItems.add(0, new ContactItem(contact));
notifyItemInserted(0);


回答2:

With Activity.setResult(int resultCode, Intent data), the first parameter is the result code not the request code.

You're using setResult(1, intent); its similar to setResult(Activity.RESULT_FIRST_USER, intent);.

Note that:

RESULT_FIRST_USER : Start of user-defined activity results.


Change your code to:

setResult(Activity.RESULT_OK , intent);

And

if( (requestCode==1) && (resultCode==Activity.RESULT_OK) ) {
    String doMessage=data.getStringExtra("MESSAGE1");
    String note1Message=data.getStringExtra("MESSAGE2");
    Contact contact = new Contact(doMessage,note1Message);
    mContactsAdapter.addItem(contact);
    //maybe you should call "mContactsAdapter.notifyItemInserted(...)" to refresh your adapter, if you didn't do that in addItem() method.
    mRecyclerView.scrollToPosition(0);            
}

PS: From your CardViewActivity code, data.getStringExtra("MESSAGE2") can return null object.