Щелчок PopupMenu вызывает прокрутку RecyclerView

У меня есть кнопка переполнения внутри CardView в Recyclerview. Всякий раз, когда я нажимаю кнопку, я показываю всплывающее меню, но также RecyclerView прокручивает один элемент вниз. Может ли кто-нибудь помочь мне остановить эту нежелательную прокрутку?

По сути, я пытаюсь воспроизвести то же поведение кнопки переполнения, что и в Playstore.

Макет:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">

<android.support.v7.widget.CardView
    android:id="@+id/cv_tracks"
    android:layout_width="match_parent"
    android:layout_height="65dp"
    >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <ImageView
            android:id="@+id/ivTracks"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:background="@drawable/unknown"
           />
        <Button
            android:id="@+id/imgbtn_overflow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent"
            android:drawableTop="@drawable/ic_overflow"
            android:paddingLeft="25dp"
            android:paddingRight="20dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true" /> 
 </RelativeLayout>
 </android.support.v7.widget.CardView>
 </RelativeLayout>

Адаптер:

@Override
public void onBindViewHolder(final TracksViewHolder tracksViewHolder, int i) {

    tracksViewHolder.imgBtnOverflow.setTag(i);
    tracksViewHolder.imgBtnOverflow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Creating the instance of PopupMenu
            final int position = (Integer) v.getTag();

            PopupMenu popup = new PopupMenu(mContext,tracksViewHolder.imgBtnOverflow);

            //Inflating the Popup using xml file
            popup.getMenuInflater()
                    .inflate(R.menu.popup_menu_overflow, popup.getMenu());


            //registering popup with OnMenuItemClickListener
            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {

                public boolean onMenuItemClick(MenuItem item) {

                 if(mPopUpClick!=null)
                     mPopUpClick.actionOnPopUpItemClick(position,item,songs.get(position));
                    return true;
                }
            });

            popup.show(); //showing popup menu
        }
    });

}

ОБНОВЛЕНИЕ: возникла проблема. Когда отображается всплывающее меню, оно сдвигает список вниз, чтобы отобразить весь раскрывающийся список. Как настроить всплывающее окно для отображения вверх/вниз в зависимости от доступного места?


person Siju    schedule 06.04.2015    source источник


Ответы (4)


Пробовал использовать android.widget.PopupMenu вместо android.support.v7.widget.PopupMenu и вуаля, все работает. Так это ошибка в библиотеке поддержки. Могут ли великие разработчики подтвердить то же самое?

person Siju    schedule 07.04.2015
comment
То же самое для меня, использование android.widget.PopupMenu работает до сих пор. - person Chris; 09.10.2016
comment
Огромное спасибо! Я потратил час, борясь с этим! Для всех, кто прибудет после меня: это верно даже в 2019 году. Используйте: android.widget.PopupMenu Не: androidx.appcompat.widget.PopupMenu - person Adi B; 19.03.2019

Вы можете переопределить AnchorView requestRectangleOnScreen() и вернуть false. Это предотвратит прокрутку любого родителя ScrollView.

Итак, в вашем случае imgBtnOverflow будет пользовательским ImageButton, например:

/**
 * A custom {@link ImageButton} which prevents parent ScrollView scrolling when used as the
 * anchor for a {@link android.support.v7.widget.PopupMenu}
 */
public class NonScrollImageButton extends ImageButton {

    public NonScrollImageButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
        return false;
    }
}

Реквизиты для jankovd (https://gist.github.com/jankovd/19ef35efd1f00e9213fa)

Сообщение о проблеме было отправлено во всплывающее меню поддержки здесь: https://code.google.com/p/android/issues/detail?id=135439

person Tim Malseed    schedule 06.05.2016
comment
Ссылка на трекер ошибок не работает - person android developer; 05.08.2019

У меня такая же проблема, и я использую этот способ:

mLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false) {
            @Override
            public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate) {
                return false;
            }
        };
mRecyclerView.setLayoutManager(mLayoutManager);

Пользователь RecyclerView layoutmanager для управления макетом, поэтому я думаю, что изменение поведения layoutmanger — это решение для ставок.

person weigan    schedule 11.12.2017

requestRectangleOnScreenу меня не работает, в моем случае requestRectangleOnScreenне вызывается при показе popupMenu. мое решение переопределить requestChildRectangleOnScreen и вернуть false, работает хорошо.

public class PopupAncorRecyclerViewPager extends RecyclerView {
        @Override
    public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
        return false;
    }
}
person weigan    schedule 27.05.2017