【问题标题】:Custom Tab Indicator(With Arrow down like Indicator)自定义选项卡指示器(像指示器一样向下箭头)
【发布时间】:2019-01-25 19:05:05
【问题描述】:

有没有办法制作这样的指标?
它有一些向下的箭头,就像在选定的项目中一样?

【问题讨论】:

    标签: android android-studio tabs indicator pagerslidingtabstrip


    【解决方案1】:

    我能找到的唯一解决方案是获取原始TabLayout 的源代码并根据您的需要对其进行自定义。

    事实上,要获得这个自定义的指向箭头,你需要做的就是重写SlidingTabStripvoid draw(Canvas canvas) 方法。不幸的是,SlidingTabStripprivateTabLayout 中的内部类。

    幸运的是,所有支持库代码都是开放的,所以我们可以创建自己的TabLayoutWithArrow 类。我用这个替换了标准的void draw(Canvas canvas)来绘制箭头:

            @Override
            public void draw(Canvas canvas) {
                super.draw(canvas);
                // i used <dimen name="pointing_arrow_size">3dp</dimen>
                int arrowSize = getResources().getDimensionPixelSize(R.dimen.pointing_arrow_size);
    
                if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) {
                    canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight - arrowSize,
                            mIndicatorRight, getHeight() - arrowSize, mSelectedIndicatorPaint);
                    canvas.drawPath(getTrianglePath(arrowSize), mSelectedIndicatorPaint);
                }
            }
    
            private Path getTrianglePath(int arrowSize) {
                mSelectedIndicatorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
                mSelectedIndicatorPaint.setAntiAlias(true);
    
                int leftPointX = mIndicatorLeft + (mIndicatorRight - mIndicatorLeft) / 2 - arrowSize*2;
                int rightPointX = leftPointX + arrowSize*2;
                int bottomPointX = leftPointX + arrowSize;
                int leftPointY = getHeight() - arrowSize;
                int bottomPointY = getHeight();
    
                Point left = new Point(leftPointX, leftPointY);
                Point right = new Point(rightPointX, leftPointY);
                Point bottom = new Point(bottomPointX, bottomPointY);
    
                Path path = new Path();
                path.setFillType(Path.FillType.EVEN_ODD);
                path.setLastPoint(left.x, left.y);
                path.lineTo(right.x, right.y);
                path.lineTo(bottom.x, bottom.y);
                path.lineTo(left.x, left.y);
                path.close();
    
                return path;
            }
    

    当然,背景,指标的特殊设计可以根据您的需要进行改进/调整。

    要制作我的自定义 TabLayoutWithArrow,我必须将这些文件复制到我的项目中:

    • AnimationUtils
    • 标签布局
    • ThemeUtils
    • ValueAnimatorCompat
    • ValueAnimatorCompatImplEclairMr1
    • ValueAnimatorCompatImplHoneycombMr1
    • ViewUtils
    • ViewUtilsLollipop

    要在箭头后面显示透明度,您只需将此Shape-drawable 设置为backgroundTabLayoutWithArrow

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item android:bottom="@dimen/pointing_arrow_size">
            <shape android:shape="rectangle" >
                <solid android:color="#FFFF00" />
            </shape>
        </item>
        <item android:height="@dimen/pointing_arrow_size"
            android:gravity="bottom">
            <shape android:shape="rectangle" >
                <solid android:color="#00000000" />
            </shape>
        </item>
    </layer-list>
    

    而实际用法是:

    <klogi.com.viewpagerwithdifferentmenu.CustomTabLayout.TabLayoutWithArrow
        android:id="@+id/tabLayout"
        android:background="@drawable/tab_layout_background"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    

    我已将整个项目(TabLayoutWithArrow + 正在使用它的单页应用程序)上传到我的保管箱 - feel free to check it out

    希望对你有帮助

    【讨论】:

    • 它工作正常,我们如何增加指示器的高度?
    • 你有办法恢复三角形吗?
    【解决方案2】:

    现在它不起作用,从支持库 23.2.0 中删除了 tintmanager 类,我通过在运行时更改背景可绘制来管理相同的功能,以便循环检测点击位置,PS:检查这个问题并回答我正在使用相同的库:https://github.com/astuetz/PagerSlidingTabStrip/issues/141

    【讨论】:

      【解决方案3】:

      这是任何需要使用@Konstantin Loginov 代码的向上三角形的代码

      private Path getTrianglePath(int arrowSize) {
      
              mSelectedIndicatorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
              mSelectedIndicatorPaint.setAntiAlias(true);
              mSelectedIndicatorPaint.setColor(Color.WHITE);
      
              int leftPointX = mIndicatorLeft + (mIndicatorRight - mIndicatorLeft) / 2 - arrowSize * 1 / 2;
              int mTopX = leftPointX + arrowSize;
              int mTopY = getHeight() - arrowSize;
              int rightPointX = leftPointX + arrowSize * 2;
      
              int leftPointY = getHeight();
      
              Point left = new Point(leftPointX, leftPointY);
              Point right = new Point(rightPointX, leftPointY);
              Point bottom = new Point(mTopX, mTopY);
      
              Path path = new Path();
              path.setFillType(Path.FillType.EVEN_ODD);
              path.setLastPoint(left.x, left.y);
              path.lineTo(right.x, right.y);
              path.lineTo(bottom.x, bottom.y);
              path.lineTo(left.x, left.y);
              path.close();
      
              return path;
          }
      

      【讨论】:

        猜你喜欢
        • 2012-05-19
        • 1970-01-01
        • 2015-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        相关资源
        最近更新 更多