Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ typealias TitleBottom = Int

fun makeTitleAtMostWidthMeasureSpec(containerWidth: Int, rightBarWidth: Int, leftBarWidth: Int, isCenter: Boolean, isFill: Boolean = false): Int {
return if (isCenter) {
View.MeasureSpec.makeMeasureSpec(containerWidth, View.MeasureSpec.AT_MOST)
val availableWidth = containerWidth - rightBarWidth - leftBarWidth
View.MeasureSpec.makeMeasureSpec(availableWidth, View.MeasureSpec.AT_MOST)
} else {
val availableWidth = containerWidth - rightBarWidth - leftBarWidth - 2 * DEFAULT_LEFT_MARGIN_PX
View.MeasureSpec.makeMeasureSpec(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,22 @@ package com.reactnativenavigation.views.stack.topbar.titlebar
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import com.facebook.react.ReactInstanceManager
import com.reactnativenavigation.react.ReactView

@SuppressLint("ViewConstructor")
class TitleBarReactView(context: Context?, componentId: String?,
componentName: String?) : ReactView(context, componentId, componentName) {
var centered: Boolean = false

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var titleHeightMeasureSpec: Int
var titleWidthMeasureSpec: Int
if (centered) {
titleHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
titleWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
val availableWidth = MeasureSpec.getSize(widthMeasureSpec)
super.onMeasure(
MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
heightMeasureSpec
)
} else {
titleHeightMeasureSpec = heightMeasureSpec
titleWidthMeasureSpec = widthMeasureSpec
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
super.onMeasure(titleWidthMeasureSpec, titleHeightMeasureSpec)
}
}
Binary file modified playground/e2e/assets/buttons_navbar.android.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 74 additions & 1 deletion playground/src/screens/TopBarTitleTestScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { View, Text } from 'react-native';
import { View, Text, StyleSheet } from 'react-native';
import { NavigationComponent, NavigationProps, Navigation as Nav } from 'react-native-navigation';
import Button from '../components/Button';
import Root from '../components/Root';
Expand All @@ -11,6 +11,8 @@ const {
TOPBAR_TITLE_AVATAR,
SET_TOPBAR_WITH_SUBTITLE_BTN,
SET_TOPBAR_WITHOUT_SUBTITLE_BTN,
SET_TOPBAR_CENTER_WITH_BUTTONS_BTN,
SET_TOPBAR_FILL_WITH_BUTTONS_BTN,
} = testIDs;

// TopBar title component WITH subtitle
Expand Down Expand Up @@ -53,8 +55,37 @@ function TopBarWithoutSubtitle() {
);
}

// Mimics an inbox conversation header: avatar + long name + status line.
// With center alignment + right buttons, ellipsizeMode won't fire because
// TitleBarReactView measures with UNSPECIFIED — the text renders at full
// natural width and gets clipped behind the buttons.
function InboxConversationHeader() {
return (
<View style={inboxStyles.row}>
<View style={inboxStyles.avatar} />
<View style={inboxStyles.textContainer}>
<Text numberOfLines={1} ellipsizeMode="tail" style={inboxStyles.name}>
John Jacob Jingleheimer Schmidt-Wolfeschlegelsteinhausen
</Text>
<Text numberOfLines={1} ellipsizeMode="tail" style={inboxStyles.status}>
Online - Last message received 2 minutes ago via mobile
</Text>
</View>
</View>
);
}

const inboxStyles = StyleSheet.create({
row: { flexDirection: 'row', alignItems: 'center', flex: 1 },
avatar: { width: 32, height: 32, borderRadius: 16, backgroundColor: '#4A90D9', marginRight: 8 },
textContainer: { flex: 1, justifyContent: 'center' },
name: { fontSize: 16, fontWeight: '600', color: '#000' },
status: { fontSize: 12, color: '#888' },
});

Nav.registerComponent('TopBarWithSubtitle', () => TopBarWithSubtitle);
Nav.registerComponent('TopBarWithoutSubtitle', () => TopBarWithoutSubtitle);
Nav.registerComponent('InboxConversationHeader', () => InboxConversationHeader);

interface Props extends NavigationProps { }

Expand Down Expand Up @@ -90,6 +121,16 @@ export default class TopBarTitleTestScreen extends NavigationComponent<Props> {
testID={SET_TOPBAR_WITHOUT_SUBTITLE_BTN}
onPress={this.setTopBarWithoutSubtitle}
/>
<Button
label="Center + Right Buttons (Cut-off Bug)"
testID={SET_TOPBAR_CENTER_WITH_BUTTONS_BTN}
onPress={this.setCenterWithRightButtons}
/>
<Button
label="Fill + Right Buttons (Working)"
testID={SET_TOPBAR_FILL_WITH_BUTTONS_BTN}
onPress={this.setFillWithRightButtons}
/>
</Root>
);
}
Expand Down Expand Up @@ -117,5 +158,37 @@ export default class TopBarTitleTestScreen extends NavigationComponent<Props> {
},
},
});

setCenterWithRightButtons = () =>
Navigation.mergeOptions(this, {
topBar: {
rightButtons: [
{ id: 'SEARCH', icon: require('../../img/clear.png') },
{ id: 'MORE', icon: require('../../img/star.png') },
],
title: {
component: {
name: 'InboxConversationHeader',
alignment: 'center',
},
},
},
});

setFillWithRightButtons = () =>
Navigation.mergeOptions(this, {
topBar: {
rightButtons: [
{ id: 'SEARCH', icon: require('../../img/clear.png') },
{ id: 'MORE', icon: require('../../img/star.png') },
],
title: {
component: {
name: 'InboxConversationHeader',
alignment: 'fill',
},
},
},
});
}