How to add dividers to LinearLayoutICS?

后端 未结 1 1341
执笔经年
执笔经年 2020-12-02 01:50

Background

I\'m trying to switch my alternative \"App Manager\" app from ActionBarSherlock library to the support library Google has created, since it gets more u

相关标签:
1条回答
  • 2020-12-02 01:55

    OK, it seems setShowDividers and setDividerDrawable cannot be used because LinearLayoutICS doesn't have them .

    Not only that, but Lint didn't warn me about it being used.

    So, what I ended up with is copying LinearLayoutICS code (from here, hope it's the latest version) and some of the original LinearLayout code, to make something that does work. I hope it doesn't have any bugs.

    Long live open source ... :)

    Sadly setMeasureWithLargestChildEnabled isn't available for old APIs, so I think the ActionBarSherlock way is still better in case that's something you wish to use.

    EDIT: the setMeasureWithLargestChildEnabled method doesn't work on ActionBarSherlock.

    Here's the code, for those who wish to use. I hope next time the library gets updated, I will remember to check this issue again.

    public class LinearLayoutICS extends LinearLayout
      {
      private Drawable mDivider;
      private int      mDividerWidth,mDividerHeight;
      private int      mShowDividers;
      private int      mDividerPadding;
    
      public LinearLayoutICS(final Context context,final AttributeSet attrs)
        {
        super(context,attrs);
        // the R is from "android.support.v7.appcompat.R" .
        final TypedArray a=context.obtainStyledAttributes(attrs,R.styleable.LinearLayoutICS);
        mDivider=a.getDrawable(R.styleable.LinearLayoutICS_divider);
        if(mDivider!=null)
          {
          mDividerWidth=mDivider.getIntrinsicWidth();
          mDividerHeight=mDivider.getIntrinsicHeight();
          }
        else mDividerHeight=mDividerWidth=0;
        mShowDividers=a.getInt(R.styleable.LinearLayoutICS_showDividers,SHOW_DIVIDER_NONE);
        mDividerPadding=a.getDimensionPixelSize(R.styleable.LinearLayoutICS_dividerPadding,0);
        a.recycle();
        setWillNotDraw(mDivider==null);
        }
    
      @Override
      protected void onDraw(final Canvas canvas)
        {
        if(getOrientation()==VERTICAL)
          drawDividersVertical(canvas);
        else drawDividersHorizontal(canvas);
        }
    
      @Override
      protected void measureChildWithMargins(final View child,final int parentWidthMeasureSpec,final int widthUsed,final int parentHeightMeasureSpec,final int heightUsed)
        {
        if(mDivider!=null)
          {
          final int childIndex=indexOfChild(child);
          final int count=getChildCount();
          final LayoutParams params=(LayoutParams)child.getLayoutParams();
          // To display the dividers in-between the child views, we modify their margins
          // to create space.
          if(getOrientation()==VERTICAL)
            {
            if(hasDividerBeforeChildAt(childIndex))
              params.topMargin=mDividerHeight;
            else if(childIndex==count-1&&hasDividerBeforeChildAt(count))
              params.bottomMargin=mDividerHeight;
            }
          else if(hasDividerBeforeChildAt(childIndex))
            params.leftMargin=mDividerWidth;
          else if(childIndex==count-1&&hasDividerBeforeChildAt(count))
            params.rightMargin=mDividerWidth;
          }
        super.measureChildWithMargins(child,parentWidthMeasureSpec,widthUsed,parentHeightMeasureSpec,heightUsed);
        }
    
      void drawDividersVertical(final Canvas canvas)
        {
        final int count=getChildCount();
        for(int i=0;i<count;i++)
          {
          final View child=getChildAt(i);
          if(child!=null&&child.getVisibility()!=GONE&&hasDividerBeforeChildAt(i))
            {
            final LayoutParams lp=(LayoutParams)child.getLayoutParams();
            drawHorizontalDivider(canvas,child.getTop()-lp.topMargin);
            }
          }
        if(hasDividerBeforeChildAt(count))
          {
          final View child=getChildAt(count-1);
          int bottom=0;
          if(child==null)
            bottom=getHeight()-getPaddingBottom()-mDividerHeight;
          else bottom=child.getBottom();
          drawHorizontalDivider(canvas,bottom);
          }
        }
    
      void drawDividersHorizontal(final Canvas canvas)
        {
        final int count=getChildCount();
        for(int i=0;i<count;i++)
          {
          final View child=getChildAt(i);
          if(child!=null&&child.getVisibility()!=GONE&&hasDividerBeforeChildAt(i))
            {
            final LayoutParams lp=(LayoutParams)child.getLayoutParams();
            drawVerticalDivider(canvas,child.getLeft()-lp.leftMargin);
            }
          }
        if(hasDividerBeforeChildAt(count))
          {
          final View child=getChildAt(count-1);
          int right=0;
          if(child==null)
            right=getWidth()-getPaddingRight()-mDividerWidth;
          else right=child.getRight();
          drawVerticalDivider(canvas,right);
          }
        }
    
      void drawHorizontalDivider(final Canvas canvas,final int top)
        {
        mDivider.setBounds(getPaddingLeft()+mDividerPadding,top,getWidth()-getPaddingRight()-mDividerPadding,top+mDividerHeight);
        mDivider.draw(canvas);
        }
    
      void drawVerticalDivider(final Canvas canvas,final int left)
        {
        mDivider.setBounds(left,getPaddingTop()+mDividerPadding,left+mDividerWidth,getHeight()-getPaddingBottom()-mDividerPadding);
        mDivider.draw(canvas);
        }
    
      /**
       * Determines where to position dividers between children.
       *
       * @param childIndex Index of child to check for preceding divider
       * @return true if there should be a divider before the child at childIndex
       * @hide Pending API consideration. Currently only used internally by the system.
       */
      protected boolean hasDividerBeforeChildAt(final int childIndex)
        {
        if(childIndex==0)
          return (mShowDividers&SHOW_DIVIDER_BEGINNING)!=0;
        else if(childIndex==getChildCount())
          return (mShowDividers&SHOW_DIVIDER_END)!=0;
        else if((mShowDividers&SHOW_DIVIDER_MIDDLE)!=0)
          {
          boolean hasVisibleViewBefore=false;
          for(int i=childIndex-1;i>=0;i--)
            if(getChildAt(i).getVisibility()!=GONE)
              {
              hasVisibleViewBefore=true;
              break;
              }
          return hasVisibleViewBefore;
          }
        return false;
        }
    
      @Override
      public int getDividerPadding()
        {
        return mDividerPadding;
        }
    
      @Override
      public void setDividerPadding(final int dividerPadding)
        {
        mDividerPadding=dividerPadding;
        }
    
      @Override
      public void setShowDividers(final int showDividers)
        {
        if(mShowDividers!=showDividers)
          requestLayout();
        mShowDividers=showDividers;
        }
    
      @Override
      public void setDividerDrawable(final Drawable divider)
        {
        if(divider==mDivider)
          return;
        mDivider=divider;
        if(divider!=null)
          {
          mDividerWidth=divider.getIntrinsicWidth();
          mDividerHeight=divider.getIntrinsicHeight();
          }
        else
          {
          mDividerWidth=0;
          mDividerHeight=0;
          }
        setWillNotDraw(divider==null);
        requestLayout();
        }
    
      @Override
      public Drawable getDividerDrawable()
        {
        return mDivider;
        }
      }
    
    0 讨论(0)
提交回复
热议问题