Android: элемент RecyclerView onClick () непреднамеренно активируется после вызова метода finish () другим действием (которое было запущено этим RecyclerView). - PullRequest
0 голосов
/ 19 мая 2019

Я создал «ListItemActivity» с RecyclerView, в котором отображаются изображения, связанные с экземплярами моего класса Item.

На этих изображениях есть метод onClick, который открывает другую "ItemDetailActivity", показывающую более подробную информацию об этом конкретном элементе.

В «ItemListActivity» есть кнопка с плавающим действием, которая запускает «ItemAddActivity» для добавления новых элементов. Когда пользователь участвует в этом действии и добавляет новый элемент, он нажимает кнопку, которая вызывает метод finish () и возвращает их в «ListItemActivity».

Все работает как задумано, кроме:

После добавления нового Item в ItemAddActivity и вызывается метод finish (), возвращающий нас к «ItemListActivity», иногда (чаще всего) оказывается, что метод onClick для, казалось бы, случайного изображения в «ItemListActivity» "RecyclerView активирован.

Я не уверен, что это как-то связано с нажатием на кнопку «ItemAddActivity» самой, или с какой-то функцией RecyclerView, о которой я не знаю, с использованием метода finish () или ...?

Пожалуйста, дайте мне знать, если вам требуется дополнительная информация или код.

"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);
    }
}

}

Макет для элемента RecyclerView:

<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" />

Макет для "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>

Соответствующий код из "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();

}

Макет для "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>

Скриншоты: ItemListActivity ItemAddActivity

Я ломал голову над этим, я не могу понять, что здесь происходит. Если чего-то не хватает, дайте мне знать. У меня было много проблем с правильным форматированием.

Большое, большое спасибо.

1 Ответ

0 голосов
/ 19 мая 2019

Метод viewItemDetail кажется странным.После первого щелчка вы зарегистрировали наблюдателя, поэтому всякий раз, когда новый элемент будет доступен, он запускает ItemDetailActivity.Зачем регистрировать наблюдателя, чтобы начать деятельность?Вы получили индекс, чтобы получить предмет.Получите адаптер из представления переработчика, затем получите элемент, используя индекс, и просто введите намерение с помощью itemid.

...