Есть ли ват, чтобы сделать такой индикатор?
у него есть указательная стрелка вниз, как в выбранном элементе?
Пользовательский индикатор вкладки (со стрелкой вниз, как индикатор)
Ответ 1
Единственное решение, которое я смог найти, это захватить исходный код оригинального TabLayout
и настроить его в соответствии с вашими потребностями.
Фактически, все, что вам нужно сделать, чтобы получить эту настраиваемую стрелку указателя, это переопределить метод SlidingTabStrip
void draw(Canvas canvas)
. К сожалению, SlidingTabStrip
является внутренним классом private
внутри TabLayout
.
К счастью, весь код библиотеки поддержки открыт, поэтому мы можем создать собственный класс 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 - не стесняйтесь проверить его.
Надеюсь, это поможет
Ответ 2
теперь это не сработает, класс tintmanager удален из библиотеки поддержки 23.2.0, мне удалось использовать те же функциональные возможности, изменив фоновый рисунок во время выполнения внутри для обнаружения петли по петле, 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)+getHeight()/4;
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();
path.close();
return path;
}