Панель инструментов не исчезнет в режиме действия - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь реализовать функцию, которая, когда я долго щелкаю по элементу списка, запускается режим действия, и становится возможным удалить один или несколько элементов.
Я запускаю в MainActivity DocumentsActivity поиск, который запускает фрагмент DocumentsFragment с ListView и их элементами. ListAdapter инициализируется и устанавливается с помощью вызова метода setListAdapter(this.documentsAdapter) в onCreate во фрагменте. Я установил различных слушателей в списке в onActivityCreated во фрагменте:

public void onActivityCreated(Bundle savedInstanceState) {

    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            getListView().setItemChecked(position, true);
            return true; 
    }});
    getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            menu.clear();
            ((DocumentsActivity)getActivity()).getMenuInflater().inflate(R.menu.documents_context_menu, menu);
            return true;
        }
    });
    super.onActivityCreated(savedInstanceState);
}

Когда я долго нажимаю на элемент списка, запускается режим действия, и меню documents_context_menu кажется панелью действий. Но проблема в том, что над панелью инструментов появляется панель действий, и панель инструментов не исчезает (см. Рисунок).

image

Я пытался вызвать getSupportActionBar().hide() или установить его на ноль, или даже использовать другой стиль / тему. Все это не сработало. Иногда синяя панель инструментов была полностью белой, но это все.

Я понятия не имею, почему панель инструментов не исчезнет. Можешь дать совет?

Заранее спасибо!

_____ Обновление 1 _____

Это файл styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:fitsSystemWindows">true</item>
    <item name="colorAccent">@color/darkblue100</item>
    <item name="android:actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
    <item name="actionOverflowButtonStyle">@style/ActionButtonOverflow</item>
    <item name="android:actionMenuTextColor">@color/black</item>
</style>

И вот как в действии устанавливается панель действий:

protected void onCreate(Bundle savedInstanceState) {
    handleIntent(getIntent());
    requestWindowFeature(5);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_documents);
    Toolbar mToolbar = (Toolbar) findViewById(R.id.tool_bar);
    setSupportActionBar(mToolbar);
    args = getIntent().getExtras();
    if (findViewById(R.id.container_documents) != null && savedInstanceState == null) {
        showDocumentsFragment();
    }
}

Ответы [ 5 ]

0 голосов
/ 25 января 2019

На самом деле это было вызвано различными настройками. Во-первых, как говорилось несколько раз, windowActionBar был установлен true, также был атрибут fitsSystemWindows. Я удалил обе строки в styles.xml.

Тогда в макете активности был атрибут layout_marginTop="?actionBarSize", которого я не видел, следуя в полной растерянности. Но этот атрибут должен быть там, поэтому я обрабатываю его в методе onActivityCreated, когда вызываются onCreateActionMode и onDestroyActionMode.

После этого у меня возникла автоматическая проблема с тем, что элементы списка исчезли. Я исправил это, передав свой фрагмент снова в onDestroyActionMode.

public void onActivityCreated(Bundle savedInstanceState) {

    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {...}
    });
    getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        LinearLayout ll = ((DocumentsActivity)getActivity()).findViewById(R.id.container_documents);

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
            params.setMargins(0, 0, 0, 0);
            ll.setLayoutParams(params);

            ((DocumentsActivity)getActivity()).getSupportActionBar().hide();
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.documents_context_menu, menu);
            return true;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            DrawerLayout.LayoutParams params = (DrawerLayout.LayoutParams) ll.getLayoutParams();
            params.setMargins(0, R.attr.actionBarSize, 0, 0);
            ll.setLayoutParams(params);
            ((DocumentsActivity)getActivity()).getSupportActionBar().show();

            if (getFragmentManager() != null)
                getFragmentManager()
                .beginTransaction()
                .detach(this)
                .attach(this)
                .commit();
        }
    });

    super.onActivityCreated(savedInstanceState);
}
0 голосов
/ 22 января 2019

все эти ответы хороши, вы должны попробовать их, но вам нужно ContextualMenu, поэтому вы должны сначала добавить представления к registerForContextMenu(), чтобы меню знало, какие меню являются контекстными, а затем реализовать onCreateContextMenu вашего Activity

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
                            ContextMenuInfo menuInfo) {
   super.onCreateContextMenu(menu, v, menuInfo);
   MenuInflater inflater = getMenuInflater();
   inflater.inflate(R.menu.context_menu, menu);
}

затем реализуйте onContextItemSelected() так:

@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
    case R.id.edit:
        editNote(info.id);
        return true;
    case R.id.delete:
        deleteNote(info.id);
        return true;
    default:
        return super.onContextItemSelected(item);
}
}

затем вам нужно выполнить действие с представлениями и реализовать AbsListView.MultiChoiceModeListener, затем вызвать setChoiceMode() с аргументом CHOICE_MODE_MULTIPLE_MODAL. как это:

ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
                                      long id, boolean checked) {
    // Here you can do something when items are selected/de-selected,
    // such as update the title in the CAB
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    // Respond to clicks on the actions in the CAB
    switch (item.getItemId()) {
        case R.id.menu_delete:
            deleteSelectedItems();
            mode.finish(); // Action picked, so close the CAB
            return true;
        default:
            return false;
    }
}

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    // Inflate the menu for the CAB
    MenuInflater inflater = mode.getMenuInflater();
    inflater.inflate(R.menu.context, menu);
    return true;
}

@Override
public void onDestroyActionMode(ActionMode mode) {
    // Here you can make any necessary updates to the activity when
    // the CAB is removed. By default, selected items are deselected/unchecked.
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
    // Here you can perform updates to the CAB due to
    // an <code><a href="/reference/android   /view/ActionMode.html#invalidate()">invalidate()</a></code> request
    return false;
}
});

все, что я сказал, и, в конечном счете, многое другое, вы можете найти в этой документации для разработчиков Android

0 голосов
/ 17 января 2019

Добавить:

 //Set action mode null after use
    public void setNullToActionMode() {
        if (mActionMode != null)
            mActionMode = null;
    }

Или:

//Remove selected selections
public void removeSelection() {

    mSelectedItemsIds = new SparseBooleanArray();
}
0 голосов
/ 22 января 2019

Итак, насколько я прошёл ваш код и понял его, вы сделали все, что предоставили своей Панели инструментов, чтобы действовать как ActionBar, и использовали тему .NoActionBar, за исключением того, что, согласно Android Developer, вы также должны установить для атрибута windowActionBar значение false в вашем стиль. введите описание ссылки здесь Второй пункт очищает его.

Надеюсь, это поможет!

0 голосов
/ 14 января 2019

Как указано в ссылке в комментариях, вам просто нужно добавить следующую строку в ваш стиль AppTheme:

<item name="windowActionModeOverlay">true</item>

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

...