Skip to content

Commit 8b05bf3

Browse files
committed
feat(segmentedbar): ability to customize style better with android
1 parent 2411b7b commit 8b05bf3

File tree

1 file changed

+75
-16
lines changed

1 file changed

+75
-16
lines changed

packages/core/ui/segmented-bar/index.android.ts

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ export class SegmentedBarItem extends SegmentedBarItemBase {
116116

117117
this.setNativeView(titleTextView);
118118
if (titleTextView) {
119+
// Disable ALL CAPS transformation
120+
titleTextView.setAllCaps(false);
119121
if (this.titleDirty) {
120122
this._update();
121123
}
@@ -250,6 +252,11 @@ export class SegmentedBar extends SegmentedBarBase {
250252
if (tabWidget) {
251253
tabWidget.setEnabled(tabWidget.isEnabled());
252254
}
255+
256+
// Apply initial tab colors and rounded corners
257+
if (this.items?.length) {
258+
this.setTabColor(this.selectedIndex >= 0 ? this.selectedIndex : 0);
259+
}
253260
}
254261

255262
private insertTab(tabItem: SegmentedBarItem, index: number): void {
@@ -294,26 +301,78 @@ export class SegmentedBar extends SegmentedBarBase {
294301
try {
295302
const tabWidget = this.nativeViewProtected?.getTabWidget();
296303
if (tabWidget) {
304+
// Remove dividers between tabs that can cover rounded corners
305+
tabWidget.setDividerDrawable(null);
306+
tabWidget.setShowDividers(android.widget.LinearLayout.SHOW_DIVIDER_NONE);
307+
// Remove strip/underline from TabWidget
308+
tabWidget.setStripEnabled(false);
309+
297310
const unselectedTextColor = this.getColorForAndroid(this.color ?? '#6e6e6e');
298311
const selectedTextColor = this.getColorForAndroid(this?.selectedTextColor ?? '#000000');
299312
const unselectedBackgroundColor = this.getColorForAndroid(this?.backgroundColor ?? '#dbdbdb');
300313
const selectedBackgroundColor = this.getColorForAndroid(this?.selectedBackgroundColor ?? this?.backgroundColor ?? 'blue');
301-
if (tabWidget) {
302-
for (let i = 0; i < tabWidget.getTabCount(); i++) {
303-
const view = tabWidget.getChildTabViewAt(i);
304-
const item = this.items[i];
305-
const textView = item?.nativeViewProtected;
306-
view.setBackgroundColor(unselectedBackgroundColor);
307-
if (textView) {
308-
textView.setTextColor(unselectedTextColor);
309-
}
310-
if (index == i) {
311-
view.setBackgroundColor(selectedBackgroundColor);
312-
if (textView) {
313-
textView.setTextColor(selectedTextColor);
314-
}
315-
continue;
316-
}
314+
const tabCount = tabWidget.getTabCount();
315+
const cornerRadius = layout.toDevicePixels(8); // 8dp corner radius
316+
317+
// Create a rounded background for the entire TabWidget and clip children to it
318+
if (SDK_VERSION >= 21) {
319+
const tabWidgetDrawable = new android.graphics.drawable.GradientDrawable();
320+
tabWidgetDrawable.setColor(unselectedBackgroundColor);
321+
tabWidgetDrawable.setCornerRadius(cornerRadius);
322+
tabWidget.setBackground(tabWidgetDrawable);
323+
tabWidget.setClipToOutline(true);
324+
tabWidget.setClipChildren(true);
325+
tabWidget.setOutlineProvider(android.view.ViewOutlineProvider.BACKGROUND);
326+
}
327+
328+
for (let i = 0; i < tabCount; i++) {
329+
const view = tabWidget.getChildTabViewAt(i);
330+
const item = this.items[i];
331+
const textView = item?.nativeViewProtected;
332+
const isSelected = index == i;
333+
const bgColor = isSelected ? selectedBackgroundColor : unselectedBackgroundColor;
334+
335+
const isFirst = i === 0;
336+
const isLast = i === tabCount - 1;
337+
338+
// Apply rounded corners to first and last tabs so selected state also has rounded corners
339+
const drawable = new android.graphics.drawable.GradientDrawable();
340+
drawable.setColor(bgColor);
341+
342+
if (isFirst && isLast) {
343+
// Only one tab - round all corners
344+
drawable.setCornerRadius(cornerRadius);
345+
} else if (isFirst) {
346+
// Round top-left and bottom-left corners
347+
const radii = Array.create('float', 8);
348+
radii[0] = cornerRadius;
349+
radii[1] = cornerRadius; // top-left
350+
radii[2] = 0;
351+
radii[3] = 0; // top-right
352+
radii[4] = 0;
353+
radii[5] = 0; // bottom-right
354+
radii[6] = cornerRadius;
355+
radii[7] = cornerRadius; // bottom-left
356+
drawable.setCornerRadii(radii);
357+
} else if (isLast) {
358+
// Round top-right and bottom-right corners
359+
const radii = Array.create('float', 8);
360+
radii[0] = 0;
361+
radii[1] = 0; // top-left
362+
radii[2] = cornerRadius;
363+
radii[3] = cornerRadius; // top-right
364+
radii[4] = cornerRadius;
365+
radii[5] = cornerRadius; // bottom-right
366+
radii[6] = 0;
367+
radii[7] = 0; // bottom-left
368+
drawable.setCornerRadii(radii);
369+
}
370+
// Middle tabs have no rounded corners
371+
372+
view.setBackground(drawable);
373+
374+
if (textView) {
375+
textView.setTextColor(isSelected ? selectedTextColor : unselectedTextColor);
317376
}
318377
}
319378
}

0 commit comments

Comments
 (0)