it-swarm.com.ru

Пользовательский индикатор вкладки (со стрелкой вниз, как индикатор)

 enter image description here

Есть ли ват, чтобы сделать такой индикатор?
у него есть какая-то заостренная стрелка вниз, как в выбранном элементе? 

12
Charles Galvez

Единственное решение, которое я смог найти, - это получить исходный код исходного TabLayout и настроить его в соответствии с вашими потребностями.

Фактически, все, что вам нужно сделать, чтобы получить эту пользовательскую стрелку, это переопределить метод SlidingTabStripvoid draw(Canvas canvas). К сожалению, SlidingTabStrip - это private внутренний класс внутри TabLayout.

 enter image description here

К счастью, весь код поддержки библиотеки открыт, поэтому мы можем создать наш собственный класс 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 
  • TabLayout
  • ThemeUtils 
  • ValueAnimatorCompat
  • ValueAnimatorCompatImplEclairMr1 
  • ValueAnimatorCompatImplHoneycombMr1
  • ViewUtils 
  • ViewUtilsLollipop

Чтобы иметь прозрачность за стрелкой, вам просто нужно установить это Shape-drawable, как background для TabLayoutWithArrow:

<?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 + одностраничное приложение, которое его использует) в свой Dropbox - не стесняйтесь проверить его .

Я надеюсь, что это помогает

17
Konstantin Loginov

теперь это не работает, класс tintmanager удален из библиотеки поддержки 23.2.0, я управлял той же функциональностью, изменяя фон, который можно рисовать во время выполнения внутри для цикла, определяющего нажатую позицию, PS: проверьте этот вопрос и ответьте, я использую ту же библиотеку: https://github.com/astuetz/PagerSlidingTabStrip/issues/141

1
geniushkg

Вот код для тех, кому нужен восходящий треугольник с использованием кода @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;
    }
0
Aditi