Back to Components

News Tab

Tabs
7 months ago

About

News App Tab

A modern tab based on Expo Router, and Material Top Tabs. Features a beautiful dark theme, smooth animations, and responsive design similar to popular news apps.

✨ Features

  • Material Top Tabs Navigation - Smooth horizontal scrolling between categories
  • Auto-scroll Active Tab - Active tab automatically scrolls into view when swiping
  • Swipe Navigation - Natural swipe gestures between tabs

📦 Required Dependencies

Install the following packages in your Expo/React Native project:

bash
# Core navigation dependencies npm install @react-navigation/material-top-tabs react-native-tab-view # Required peer dependencies (if not already installed) npm install @react-navigation/native @react-navigation/bottom-tabs npm install react-native-screens react-native-safe-area-context npm install react-native-gesture-handler react-native-reanimated

Additional Dependencies

These should already be included in most Expo projects:

bash
npm install @expo/vector-icons expo-router

🚀 Installation

  1. Copy the news-app folder to your app/ directory:
app/ ├── news-app/ │ ├── _layout.tsx │ ├── top.tsx │ ├── pga.tsx │ ├── atp.tsx │ ├── wnba.tsx │ ├── ucl.tsx │ ├── uel.tsx │ ├── nfl.tsx │ └── nhl.tsx
  1. Add the route to your main navigation (e.g., in your index page):

📁 Project Structure

app/news-app/ ├── _layout.tsx # Material Top Tabs layout with custom header ├── top.tsx ├── pga.tsx ├── atp.tsx ├── wnba.tsx ├── ucl.tsx ├── uel.tsx ├── nfl.tsx └── nhl.tsx

🔧 How to Add New Tabs

1. Create a New Tab Component

Create a new file in app/news-app/ (e.g., mls.tsx):

typescript
import React from 'react'; import { Image, Text, TouchableOpacity, View, ScrollView } from 'react-native'; const mlsNews = [ { title: "MLS Cup Final Preview", timeAgo: "1h ago", readTime: "5m read", image: "https://picsum.photos/300/200?random=80" }, // Add more news items... ]; const NewsCard = ({ item }) => { return ( <TouchableOpacity style={{ backgroundColor: '#1a1a1a', borderRadius: 16, marginBottom: 16, overflow: 'hidden', marginHorizontal: 16 }} > <Image source={{ uri: item.image }} style={{ width: '100%', height: 120, backgroundColor: '#2a2a2a' }} resizeMode="cover" /> <View style={{ padding: 16 }}> <Text style={{ color: '#ffffff', fontSize: 16, fontWeight: '600', lineHeight: 22, marginBottom: 8 }}> {item.title} </Text> <View style={{ flexDirection: 'row', alignItems: 'center', gap: 16 }}> <Text style={{ color: '#888', fontSize: 14 }}> {item.timeAgo} </Text> <Text style={{ color: '#888', fontSize: 14 }}> {item.readTime} </Text> </View> </View> </TouchableOpacity> ); }; export default function MLSTab() { return ( <ScrollView style={{ flex: 1, backgroundColor: '#000' }}> <View style={{ paddingTop: 16 }}> <Text style={{ color: '#ffffff', fontSize: 24, fontWeight: '600', marginBottom: 16, paddingHorizontal: 16 }}> MLS News </Text> {mlsNews.map((item, index) => ( <NewsCard key={index} item={item} /> ))} </View> </ScrollView> ); }

2. Add to Layout

Update _layout.tsx to include your new tab:

typescript
<MaterialTopTabs.Screen name="mls" options={{ title: "MLS" }} />

Add it in the screens section alongside the other tabs.

🎨 Customization Options

Changing Colors

Update the color scheme in _layout.tsx:

typescript
// Change active tab color borderBottomColor: isFocused ? '#YOUR_COLOR' : 'transparent' // Change text colors color: isFocused ? '#YOUR_ACTIVE_COLOR' : '#YOUR_INACTIVE_COLOR'

Modifying Header

Customize the header in the CustomTabBar component:

typescript
{/* Custom header title */} <Text style={{ color: '#fff', fontSize: 20, fontWeight: '600' }}> Your App Name </Text>

🔄 Auto-scroll Feature

The active tab automatically scrolls into view when navigating. This is handled by:

typescript
useEffect(() => { if (scrollViewRef.current) { const activeIndex = state.index; const tabWidth = 90; const scrollX = Math.max(0, activeIndex * tabWidth - 50); scrollViewRef.current.scrollTo({ x: scrollX, animated: true }); } }, [state.index]);

📱 Platform Support

  • ✅ iOS
  • ✅ Android

🛠️ Development

File Structure Best Practices

  • Keep each tab as a separate component
  • Use consistent naming conventions
  • Maintain similar data structures across tabs
  • Keep styles inline for better performance

Performance Tips

  • Use lazy: false for better user experience
  • Implement proper image loading with placeholders
  • Consider virtualized lists for large datasets
  • Use React.memo for news cards if needed

🐛 Troubleshooting

📄 License

This component is all your after you bought the landing components.


Happy coding! 🚀

Posted by

E

eren

@eren