web-dev-qa-db-ja.com

カスタムタブインジケーター(インジケーターのように下向きの矢印付き)

enter image description here

このような指標を作るためのワットはありますか?
選択したアイテムのように下向きの矢印がありますか?

15
Charles Galvez

私が見つけた唯一の解決策は、元のTabLayoutのソースコードを取得し、必要に応じてカスタマイズすることです。

実際、このカスタムの矢印を取得するために必要なのは、SlidingTabStripvoid draw(Canvas canvas)メソッドをオーバーライドすることだけです。残念ながら、SlidingTabStripprivate内の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-drawablebackgroundTabLayoutWithArrowとして設定する必要があります。

<?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 +それを使用している1ページのアプリ)をドロップボックスにアップロードしました- お気軽にチェックしてください

私はそれが役立つことを願っています

20

現在は機能しません。tintmanagerクラスはサポートライブラリ23.2.0から削除され、クリックされた位置を検出するforループ内で実行時に描画可能な背景を変更することで同じ機能を管理しました。PS:この質問と回答を確認してください。 https://github.com/astuetz/PagerSlidingTabStrip/issues/141

1
geniushkg

@KonstantinLoginovコードを使用して上向きの三角形を必要とする人のためのコードは次のとおりです

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