简体   繁体   中英

Android: RecyclerView item's onClick() unintentionally activated after call to finish() by another activity (which was started by that RecyclerView)

I have created a "ListItemActivity" with a RecyclerView in which images associated with instances of my Item class are displayed.

These images have an onClick method on them that will open another "ItemDetailActivity" showing more details about that particular item.

In the "ItemListActivity" there is a floating action button which starts an "ItemAddActivity" to add new Items. When the user is in this activity and adds a new Item, they click a button which calls finish() and returns them to the "ListItemActivity".

Everything works as intended, except:

After adding a new Item in the "ItemAddActivity" and finish() is called, thus returning us to the "ItemListActivity", sometimes (more often than not) it appears that the onClick method on a seemingly random image in "ItemListActivity"'s RecyclerView is activated.

I'm not sure if this has something to do with clicking on the "ItemAddActivity" button itself, or some feature of the RecyclerView that I'm unaware of, the use of finish(), or ... ?

Please let me know if you require additional information or code.

"ItemListActivity":

public class ItemListActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ClosetSampleViewModel mViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_item_list);

    Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
    setSupportActionBar(myToolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    mRecyclerView = findViewById(R.id.item_list_rv);
    final ItemListAdapter adapter = new ItemListAdapter(this);
    mRecyclerView.setAdapter(adapter);
    mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL));

    mViewModel = ViewModelProviders.of(this).get(ClosetSampleViewModel.class);
    mViewModel.getAllItems().observe(this, new Observer<List<Item>>() {
        @Override
        public void onChanged(@Nullable List<Item> items) {
            adapter.setItems(items);
        }
    });
}

public void addItem(View view) {
    Intent intent = new Intent(this, ItemAddActivity.class);
    startActivity(intent);
}

public void viewItemDetail(View view) {
    final int itemPosition = mRecyclerView.getChildLayoutPosition(view);
    mViewModel.getAllItems().observe(this, new Observer<List<Item>>() {
        @Override
        public void onChanged(@Nullable List<Item> items) {
            Item item = items.get(itemPosition);
            Intent intent = new Intent(getApplicationContext(), ItemDetailActivity.class);
            intent.putExtra("itemId", item.getId());
            startActivity(intent);
        }
    });
}

}

"ItemListAdapter":

public class ItemListAdapter extends RecyclerView.Adapter<ItemListAdapter.ItemViewHolder> {
private final LayoutInflater mInflater;
private List<Item> mItems;

public ItemListAdapter(Context context) {
    mInflater = LayoutInflater.from(context);
}

@Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = mInflater.inflate(R.layout.item_list_rv_item, parent, false);
    return new ItemViewHolder(itemView);

}

@Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
    if (mItems != null) {
        Item currentItem = mItems.get(position);

        String uriString = "none";
        if (currentItem.getImageUri() != null) {
            uriString = currentItem.getImageUri().toString();

            // TODO
            GlideApp.with(holder.pictureImageView.getContext()).load(uriString).placeholder(R.color.colorPrimaryDark).dontTransform().into(holder.pictureImageView);
        } else {
            holder.pictureImageView.setVisibility(View.INVISIBLE);
        }

    } else {
        // TODO: data not ready yet.
    }
}

public void setItems(List<Item> items) {
    mItems = items;
    notifyDataSetChanged();
}

@Override
public int getItemCount() {
    return mItems == null ? 0 : mItems.size();
}


class ItemViewHolder extends RecyclerView.ViewHolder {
    private final ImageView pictureImageView;

    private ItemViewHolder(View itemView) {
        super(itemView);
        pictureImageView = itemView.findViewById(R.id.item_list_rv_image);
    }
}

}

Layout for RecyclerView item:

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_list_rv_image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryDark"
    android:adjustViewBounds="true"
    android:padding="5dp"
    android:layout_margin="3dp"
    android:onClick="viewItemDetail" />

Layout for "ItemListActivity":

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ItemListActivity">

<!-- Load the toolbar here -->

<android.support.v7.widget.RecyclerView
    android:id="@+id/item_list_rv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:listitem="@layout/item_list_rv_item"/>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/item_list_fab"
    app:fabSize="normal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="end|bottom"
    android:layout_margin="16dp"
    android:layout_marginEnd="16dp"
    android:layout_marginBottom="16dp"
    android:src="@drawable/ic_add_white_24dp"
    android:background="@color/colorAccent"
    android:onClick="addItem" />

</android.support.design.widget.CoordinatorLayout>

Relevant code from "ItemAddActivity":

public void onAddItemClicked(View view) {

    if (currentPhotoPath == null) {
    Toast.makeText(this, "Can't add item without image.", Toast.LENGTH_LONG).show();
    } else {
        final String itemName = itemNameEditText.getText().toString();
        final String itemDescription = itemDescriptionEditText.getText().toString();

        // Image set for this Item.
        final Uri imageUri = Uri.parse(currentPhotoPath);

        // Set the photo path to null in the shared prefs so we don't accidently delete it next time.
        SharedPreferences prefs = getApplicationContext().getSharedPreferences(ITEM_IMAGE_SHARED_PREFS_FILE, MODE_PRIVATE);
        SharedPreferences.Editor prefsEditor = prefs.edit();
        prefsEditor.putString(PREF_PHOTO_PATH, null);
        prefsEditor.apply();


        if (itemCategorySpinner.getSelectedItemPosition() >= 0) {
            mViewModel.getAllCategories().observe(this, new Observer<List<Category>>() {
            @Override
            public void onChanged(@Nullable List<Category> categories) {
                addItem(new Item(itemName, itemDescription, imageUri, categories.get(itemCategorySpinner.getSelectedItemPosition())));
            }
            });

        } else {
            addItem(new Item(itemName, itemDescription, imageUri, null));
            }


    }

}

private void addItem(Item item) {
mViewModel.insertItem(item);
finish();

}

Layout for "ItemAddActivity":

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ItemAddActivity">

<!-- Load the toolbar here -->

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

<EditText
    android:id="@+id/item_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:importantForAutofill="no"
    android:hint="@string/item_name" />

<EditText
    android:id="@+id/item_description"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:importantForAutofill="no"
    android:hint="@string/item_description" />

<android.support.v7.widget.AppCompatSpinner
    android:id="@+id/item_category_spinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

<Button
    android:id="@+id/take_photo_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/take_photo"
    android:onClick="onTakePhotoClicked" />

<Button
    android:id="@+id/add_item_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/add_item"
    android:onClick="onAddItemClicked"/>

<ImageView
    android:id="@+id/item_photo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"/>

</LinearLayout>

</android.support.design.widget.CoordinatorLayout>

Screenshots: ItemListActivity ItemAddActivity

I've been wracking my brain over this, I can't figure out what's going on here. If there's something missing, let me know. I had a lot of trouble getting the formatting to work right.

Many, many thanks.

The viewItemDetail method seems strange. After a first click you have registered an observer so whenever a new item will be available it will start the ItemDetailActivity. Why register an observer to start the activity. You got the index to get the item. Get the adapter from recycler view then get the item using index and just fire an intent with the itemid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM