Режим контекстного действия во фрагменте не отображается

хочу сделать такое приложение

пакетные контекстные действия в AbsListView

Я следовал руководству Google по включению пакетных контекстных действий в AbsListView. В моем случае я реализовал AbsListView в Fragment, потому что я хочу, чтобы пользователи могли изменять макет. У меня есть несколько макетов для Activity (подкласс ListView, GridView и еще один подкласс AbsListView). Я также реализую AbsListView.MultiChoiceModeListener в отдельном классе, потому что хочу повторно использовать его в нескольких фрагментах и ​​действиях.

Моя проблема: когда я долго нажимаю на элемент списка, контекстная панель действий не отображается. Однако он ответил на щелчок (показывает, что селектор работает).

Я снова и снова проверял и пробовал свои коды, чтобы убедиться, что правильно следую всему руководству, просмотрел множество способов устранения неполадок по этой теме, но до сих пор не могу понять, почему контекстная панель действий не работает. не подходи.

Вот один из Фрагментов:

public class List extends Bookshelf {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_list, container, false);
        ListView list = (ListView) rootView.findViewById(R.id.book_list);
        list.setAdapter(new BookListAdapter(getActivity()));

        list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        list.setMultiChoiceModeListener(new MultiChoiceCallback(list));

        return rootView;
    }

    private static class BookListAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

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

        public int getCount() {
            return 100;
        }

        public Object getItem(int position) {
            return position;
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;

            if (convertView == null) {
                convertView = mInflater.inflate(R.layout.view_item_book_1text, null);
                holder = new ViewHolder();
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            return convertView;
        }

        static class ViewHolder {
            TextView title;
            ImageView cover;
        }
    }
}

Вот MultiChoiceModeListener (MultiChoiceCallback.java):

public class MultiChoiceCallback implements MultiChoiceModeListener {
    AbsListView usingView;

    public MultiChoiceCallback(AbsListView view) {
        usingView = view;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch (item.getItemId()) {
        case R.id.bookDetails:
            break;
        case R.id.category:
            break;
        case R.id.delete:
            break;
        }
        return false;
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        mode.getMenuInflater().inflate(R.menu.select_book, menu);
        return false;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
        final int checkedCount = usingView.getCheckedItemCount();
        switch (checkedCount) {
            case 0:
                mode.setTitle(null);
                break;
            case 1:
                mode.setTitle("1 item selected");
                break;
            default:
                mode.setTitle("" + checkedCount + " items selected");
                break;
        }
    }
}

Макет Фрагмента (layout/fragment_list.xml):

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/book_list"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>

Раздутый элемент списка просмотра (layout/view_item_book_1text.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="51dp"
    android:background="@color/blue_when_clicked"
    android:clickable="true"
    android:focusable="true"
    android:layout_marginLeft="3dp"
    android:layout_marginRight="3dp"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/cover"
        android:contentDescription="@string/cover"
        android:layout_width="75dp"
        android:layout_height="45dp"
        android:layout_marginTop="3dp"
        android:layout_marginBottom="3dp"
        android:scaleType="fitCenter"
        android:src="@drawable/cover_02" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="3dp"
        android:text="A Book Title"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</LinearLayout>

Селектор цвета для каждого элемента списка (color/blue_when_clicked.xml):

<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/color_light_blue" android:state_pressed="true"/>  <!-- pressed -->
    <item android:drawable="@drawable/color_light_gray" android:state_focused="true"/>  <!-- focused -->
    <item android:drawable="@drawable/color_light_gray" android:state_activated="true"/> <!-- selected -->
</selector>

Любая помощь будет очень признательна!


person Mohamad Sani    schedule 21.07.2014    source источник
comment
Почему бы вам не использовать режим действия, при длительном нажатии элемента списка все, что вам нужно сделать, это вызвать недействительность в режиме действия, вы получите тот же результат, что и изображения, которые вы разместили выше.   -  person Techfist    schedule 21.07.2014


Ответы (2)


Я не проверял это, но на первый взгляд я думаю, что проблема в вашем методе onCreateActionMode (ActionMode mode, Menu menu).

Согласно документация — вы должны вернуть true, чтобы создать ActionMode

true, если режим действия должен быть создан, false, если вход в этот режим должен быть прерван.


Механизм тот же, что и в методе onCreateOptionsMenu (Menu menu) из Activity. Об этом говорится в документации. более понятный способ здесь:

Вы должны вернуть true для отображения меню; если вы вернете false, это не будет показано.


РЕДАКТИРОВАТЬ:

Пробовали ли вы просто запускать код из упомянутого вами туторила? Я сделал минимальную реализацию ActionMode на ListView. Там даже ресурс меню не завышен, просто верните туда true и после долгого нажатия появится ActionMode.

final ListView listView = new ListView(getActivity());
listView.setAdapter(new BookListAdapter(getActivity()));
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        return false;
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // not even need to inflate anything in order to ActionMode to appear
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }
});

Код от адаптера (модифицировал ваш адаптер):

private static class BookListAdapter extends BaseAdapter {
    private LayoutInflater mInflater;

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

    public int getCount() {
        return 100;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(android.R.layout.simple_list_item_1, null);
        }

        ((TextView)convertView).setText("TEST");
        return convertView;
    }
}


Скриншот результата - как вы можете видеть, ActionMode присутствует.

enter

person Maciej Ciemięga    schedule 21.07.2014
comment
Пробовал, все равно не работает... все равно спасибо за ответ, все равно изменю - person Mohamad Sani; 21.07.2014
comment
Я только что сам запустил этот код, и он отлично работает. Пожалуйста, смотрите мой обновленный ответ. Если это не работает для вас - проблема в других частях вашего кода. - person Maciej Ciemięga; 21.07.2014
comment
Я снова боролся со своими кодами и, наконец, нашел ошибку (см. Мой ответ ниже)! Спасибо Maciej за вашу пробную помощь, и вы фактически указали на другую ошибку, связанную с возвратом true - person Mohamad Sani; 22.07.2014

Ага! Ошибка найдена! Это из-за

android:clickable="true"
android:focusable="true"

в layout/view_item_book_1text.xml

Извините, что беспокою всех! Надеюсь, это станет заметкой по устранению неполадок для кого-то еще

person Mohamad Sani    schedule 21.07.2014
comment
Значит, вам пришлось установить их ложными? Оба? - person Vituel; 09.04.2015