RecyclerView: how to refresh Details Activity?

2019-03-07 02:37发布

问题:

In MainActivity I have a RecyclerView list of CardView Items.

A click on any CardView launches a DetailsActivity CardView that show more data from the database, for that specific CardView.

A click on the DetailsActivity CardView launches EditActivity to edit that CardView's data. Clicking the "Save" button returns the user to the DetailsActivity so the user can see any edited changes to that CardView. The model for the CardView Item implements Parcelable so I use getParcelable() to pass the item and it's database data in the Activity Intents.

My problem is that after clicking "Save" the user returns to the DetailsActivity CardView and the old View for the CardView is shown (the View prior to the updated data the user just entered and saved to the database). I tried to use "adapter.notifyDataSetChanged()" to update the View, but no luck.

Somehow from the EditActivity, I need to re-load the MainActivity so the RecyclerView updates the Adapter and then return the user to the updated DetailsActivity CardView. Can I somehow use startActivityForResult()? What am I missing here?

Here is the UI progression:

MainActivity RecyclerView and Adapter:

--the Adapter uses a recyclerItemClickListener to send the clicked CardView Item back to the MainActivity so I can use onItemClick() to launch DetailsActivity.

--onItemClick() launches DetailsActivity via an Intent

DetailsActvity:

--uses an onClickListener and an Intent to launch EditActivity

EditActivity:

--I would like a click on the "Save" button to save the new/updated CardView data to the database and return the user back to the Details Activity so the user can see the changes to the CardView.

Adapter
...
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false);
    final ItemHolder itemHolder = new ItemHolder(view);

        // Attach a Click listener to the items's (row) view.
        // itemView is from the ItemHolder().
        // onItemClick is the click method in MainActivity.
        itemHolder.itemView.setOnClickListener(new View.OnClickListener() {
            // Handles the row being clicked.
            @Override
            public void onClick(View view) {

                ListItem adapterItem = MyRecylerAdapter.this.getItem(itemHolder.getAdapterPosition()); 
                if (recyclerItemClickListener != null) {
                    // pass the item to the Main Activity
                    // through the RecyclerItemClickListener file and its
                    // public interface.
                    recyclerItemClickListener.onItemClick(itemHolder.itemView, adapterItem);
                }
            }
        });            
    return itemHolder;
}

MainActivity (the RecyclerView Activity)
...
@Override
public void onItemClick(View view, ListItem listItem) {

    Intent intent = new Intent(this, DetailsActivity.class);        
    intent.putExtra("item",listItem);
    startActivity(intent);
}

DetailsActivity
...
public class DetailsActivity extends AppCompatActivity {

    onCreate(...) {

        Bundle extras = getIntent().getExtras();
        if (extras != null) {            
            listItem = extras.getParcelable("item"); 
    }

    helper = new SQLiteDB(this);
    listItems = new ArrayList<>();
    listItems = helper.getAllDBItems();

    cvdcardType1 = (TextView) findViewById(R.id.cvdcardType1);
    if (listItems !=null && listItems.size() !=0) {
        cvdcardType1.setText(listItem.getType());
    }

    cardView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent i = new Intent(DetailsActivity.this,EditActivity.class);
            i.putExtra("cvdItem",listItem);                
            startActivityForResult(i,REQUEST_CODE);

        }
    });
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == REQUEST_CODE) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            listItem = null;
            Bundle returnExtras = getIntent().getExtras();
            if (returnExtras != null) {
                listItem = returnExtras.getParcelable("returnItem");
                if (listItems !=null && listItems.size() !=0) {

                    cvdcardType1.setText(listItem.getType()); 
                    ...  
}
            }
        }
        else if (resultCode == Activity.RESULT_CANCELED) {
            // Finish the startActivityForResult().
            finish();
        }
    }
}

}

EditActivity

public class EditActivity extends AppCompatActivity {
onCreate(...) {
Bundle extras = getIntent().getExtras();
    if (extras != null) {            
        item = extras.getParcelable("cvdItem");
    }
}

// "Save Button"
public void onClickSaveEdits(View v) {
    // update database
    // update RecyclerView adapter and CardView Items
    // update DetailsActivity CardView
    // return the user to DetailsActivity to see updated CardView
    Intent returnIntent = new Intent(EditActivity.this, DetailsActivity.class);
    returnIntent.putExtra("returnItem", item);
    setResult(Activity.RESULT_OK,returnIntent);
    finish();
}

回答1:

You have to finish DetailActivity while moving towards EditActivity and then start DetailActivity again in onBackPressed() method like below:

Intent intent = new Intent(EditActivity.this, DetailsActivity.class);        
intent.putExtra("item",item);
startActivity(intent);


回答2:

Simply you can read database items in onResume() in MainActivity again after editing detail.

allList = sqLiteDB.getAllDBItems();
adapter.notifyDatasetChanged();

In simple words read list again from database and re draw it. And make sure you saved the change in database in EditActivity

and call your EditActivity with startActivityForResult() whatever you change pass it back in setResult();

and in onActivityResult method of DetailActivity populate data with new values.