最近遇到一个问题,想定制actionmode,首先需要去掉actionmode左边的√ 号,其次用setcustomview 自定义布局。安网上的方法:
    <style name="AppTheme" parent="android:Theme.Holo">
           <item name="android:actionModeCloseButtonStyle">@style/NoCloseButton</item>
    </style>    <style name="NoCloseButton" parent="@android:style/Widget.ActionButton.CloseMode">
            <item name="android:visibility">gone</item>
    </style>
去掉了左边的√ 号。
          但接下来setcustomview的时候,布局无法充满整个actionbar。   绿色标出的部分无法填满,xml布局写的是match_parent   

解决方案 »

  1.   

    me too。有能解决的大牛吗
      

  2.   

    你可以打开DDMS,,看看视图结构。
      

  3.   

    先看图,这是hierarchyviewer 看到的结果,相信大家都能在DDMS的tool中看到这样样子最下面的 包含3个TextView的 linearLayout 就是自定义的 mCustomView
    代码内 actionMOde. setCustomView(mCustomView)id = action_mode_close_button 就是所谓的 左边的√ 号
    visible 被设置为 GONE
      

  4.   

    接下来看运行的样子:从2个图中可以看到,CustomView 确实不是充满父容器的,尽管在xml 是写的 match_parent这2楼说明大家遇到的情况,和应该知道的 hierarchyviewer 效果
    下面一楼说明原因
      

  5.   

    【子View的大小,是由父容器决定的】
    因此,要找3个TextView 的linearLayout的大小在哪里确定,就应该去找它的父容器,
    从#8 楼的图看出,应该定位到 ActionBarContextView 去看源码
    下面是 源码 actionBarContextView.java - onMeasure() 的一部分      if (mClose != null) {
     
                availableWidth = measureChildView(mClose, availableWidth, childSpecHeight, 0);
                MarginLayoutParams lp = (MarginLayoutParams) mClose.getLayoutParams();
                availableWidth -= lp.leftMargin + lp.rightMargin;
             
    }meaasureChildView()方法在父类AbsActionbarView中: protected int measureChildView(View child, int availableWidth, int childSpecHeight,
                int spacing) {
            child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
                    childSpecHeight);        availableWidth -= child.getMeasuredWidth();
            availableWidth -= spacing;        return Math.max(0, availableWidth);
        }可以看到 mClose (就是 “√ 号”)只是判断了是否为null,但是却没有判断是否visible == GONE
    一个本该不measure的view(因为是GONE),但是依然计算了。
    这就导致在计算后,availableWidth 变小了在回到ActionBarCOntextView - OnMeasure()if (mCustomView != null) {
     
                ViewGroup.LayoutParams lp = mCustomView.getLayoutParams();
                final int customWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
                        MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
                final int customWidth = lp.width >= 0 ?
                        Math.min(lp.width, availableWidth) : availableWidth;
                final int customHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
                        MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
                final int customHeight = lp.height >= 0 ?
                        Math.min(lp.height, height) : height;
                mCustomView.measure(MeasureSpec.makeMeasureSpec(customWidth, customWidthMode),
                        MeasureSpec.makeMeasureSpec(customHeight, customHeightMode));
             
    }可以看到 customWidth 被赋值的是 availableWidth(这时候这个值已经变小了)
    因此最后拿到的结果就是大家看到的样子。
      

  6.   

    解决方法就是自定义一个Layout(使用 FrameLayout 等布局都可以),
    Layout作为一个container,用来存放我们的customView
    然后重写内面的onMeasure方法,宽度等于屏幕的宽度就好了。这么做的原因:
    1. View的大小,是由父容器传递进来的参数—— measure Spec 决定的(上面我有说到)
    2. 改变View的大小,不让父容器决定,不理会父容器传递的参数,由自己来给自己确定大小,因此需要重写onMeasure这样的副作用是:如果 mClose 按钮重新设置成Visible,customView是不会从屏幕宽度变小,会覆盖 mClose 按钮
      

  7.   

    这位大神的办法可以解决:http://blog.csdn.net/u013139394/article/details/43488221
      

  8.   

    解决了https://www.jianshu.com/p/73472fcee761