Android: why is CardView not updating with new user input?
Asked Answered
B

2

0

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;
}
}
Berkelium answered 18/2, 2016 at 4:39 Comment(8)
Show your adapter that creates the views?Teamster
Ok, I am posting now.Berkelium
I don't understand. You're putting a Contact into the adapter, but then it looks like you're pulling out a ContactItem from the collection. Also I don't see where you are updating these input fields that are supposed to be changing.Teamster
The user enters data on the CardViewActivity UI in each of the two EditText fields and then clicks a Save button that puts the data back to the previous activity via an intent and putExtra. The onActivityResult method in the RecyclerView Activity receives the data. The data is put onto a CardView layout within the RecyclerView list.Berkelium
There's just not enough code here to know what's going on.Teamster
ok what else would you need to see?Berkelium
@Berkelium I see you use notifyItemInserted(0) in addItem. It means like if you are always adding the first item at UI level, but with mItems.add(...) you are adding item on bottom of the list. Try with notifyItemInserted(mItems.size()-1)Build
I always want the new CardView to be added to the top of the RecyclerView list. So should I be changing mItems?Berkelium
B
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);
Build answered 20/2, 2016 at 19:38 Comment(1)
glad I could help :)Build
L
0

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.

Lapham answered 18/2, 2016 at 8:30 Comment(5)
Nice, somehow I forgot to include resultCode. Regarding your PS note: do you recommend I somehow handle that MESSAGE2 can return null? If so, what would you recommend as best practice?Berkelium
Just be carefull when you call contact.getSurname(), because it can return a null object. It depends on your needs, if you want to avoid completely the null value, maybe you can change your getters method to return an empty String ("") if the value is null. Eg: return ( (surname != null) ? surname: "") ;Lapham
Ok. Any idea why Android Studio gives a warning that getSurname is never used when it is included in the Adapter's onBindViewHolder method with "holder.TextViewid.setText(contact.getSurname())"?Berkelium
Updated code but same result unfortunately. Any thoughts? PS notifyItemInserted(0) is included in the addItem method in the Adapter.Berkelium
1) While you're using this method, it shouldn't show this warning. Try to close and open your A.S. -- 2) You're adding the item at the end of mItems, so it must be notifyItemInserted(mItems.size() -1); -- 3) Why you're using two data set in your adapter? (mContacts and mItems) --- 4) What's the difference between ContactItem and Contact? , I think there is something wrong in your adapter logic.Lapham

© 2022 - 2024 — McMap. All rights reserved.