【问题标题】:Toolbar won't disappear in action mode动作模式下工具栏不会消失
【发布时间】:2019-01-14 14:43:59
【问题描述】:

我正在尝试实现这样的功能,即当我长按列表项时,将启动操作模式并且可以删除一个或多个项目。
我从DocumentsActivity 开始搜索,该搜索开始一个片段DocumentsFragment,其中包含一个ListView 及其项目。 ListAdapter 通过 Fragment 的 onCreate 中的方法调用 setListAdapter(this.documentsAdapter) 进行初始化和设置。我在 Fragment 的 onActivityCreated 的 listview 上设置了各种监听器:

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 似乎是动作栏。但问题是,操作栏出现在工具栏上方,工具栏不会消失(见图)。

我尝试调用 getSupportActionBar().hide() 或将其设置为 null 甚至使用其他样式/主题。这一切都没有奏效。有时蓝色工具栏完全是白色的,但仅此而已。

我完全不知道为什么工具栏不会消失。能给点建议吗?

提前致谢!

_____ 更新 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>

这就是在 Activity 中设置操作栏的方式:

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

【问题讨论】:

  • 您能否将您的应用程序主题代码从styles.xmlonCreate 发布到您setSupportActionBar 的位置?
  • @MayurGajra 我添加了来源
  • 你能分享你的 Manifest 文件吗?
  • @AbhinavGupta 在那里

标签: android android-layout android-toolbar


【解决方案1】:

正如 cmets 中提供的链接所指出的,您只需在 AppTheme 样式中添加以下行:

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

它只是表示动作模式应该覆盖窗口内容而不是向下推,它告诉你不需要为动作模式保留任何空间。

【讨论】:

  • @MarcelHofgesang 那你是如何设置动作模式的呢?尝试在工具栏上设置 acion 模式而不是像这样的活动:toolbar.startActionMode(callback);
  • 是的,我也尝试过这种方式,但它还有一些错误......实际上,当MultiChoiceModeListener 被调用时,动作模式就会被激活。查看android开发者网站developer.android.com/reference/android/widget/…的描述
【解决方案2】:

好吧,就我浏览您的代码并理解它而言,您已经完成了您提供工具栏作为 ActionBar 并使用 .NoActionBar 主题的所有操作,除非根据 Android 开发人员,您还应该将 windowActionBar 属性设置为 false风格。 enter link description here 第二段清除了它。

希望对你有帮助!

【讨论】:

    【解决方案3】:

    所有这些答案都很好,您应该尝试它们,但您需要的是 ContextualMenu,因此您应该首先将视图添加到 registerForContextMenu(),以便菜单知道哪些菜单是上下文菜单,然后实现 @987654325 的 onCreateContextMenu @

    @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,然后使用CHOICE_MODE_MULTIPLE_MODAL 参数调用setChoiceMode()。像这样:

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

    我所说的所有内容以及更多内容,您可以在 this android developer documentation 中找到

    【讨论】:

      【解决方案4】:

      添加:

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

      或者:

      //Remove selected selections
      public void removeSelection() {
      
          mSelectedItemsIds = new SparseBooleanArray();
      }
      

      【讨论】:

      • 这并不涉及我所说的问题。删除列表项不是问题,只是第二个工具栏。而且我这些方法不适用于我的场景。
      【解决方案5】:

      实际上问题是由不同的事情引起的。 首先,windowActionBar 被设置为true,也是属性fitsSystemWindows.我删除了styles.xml 中的两行

      然后在活动布局中有属性layout_marginTop="?actionBarSize" 我没有看到,完全混乱。但是这个属性需要在那里,所以当onCreateActionModeonDestroyActionMode 被调用时,我在方法onActivityCreated 中处理它。

      在那之后,我遇到了列表视图项目消失的自动问题。我通过在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);
      }
      

      【讨论】:

        【解决方案6】:

        在 Kotlin 中,假设您的 Activity 扩展自 AppCompatActivity

        • 您应该获取支持操作栏的实例并调用方法

          supportActionBar?.show()supportActionBar?.hide()

        • 如果您使用的是片段,则可以从片段的活动实例访问操作栏

          (activity as AppCompatActivity).supportActionBar?.show()

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-10-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-10
          相关资源
          最近更新 更多