Skip to main content

Overview

The cryptocurrency detail view provides comprehensive information about a specific cryptocurrency, including price data, market statistics, supply information, and percentage changes over different time periods. Users navigate to the detail screen by tapping on any cryptocurrency card in the list view. The navigation is implemented using Expo Router:
CryptoCard.tsx
const CryptoCard = ({ crypto }: Props) => {
  const router = useRouter();

  return (
    <Pressable onPress={() => router.push(`/crypto/${crypto.id}`)}>
      <TouchableOpacity
        onPress={() =>
          router.push({
            pathname: '/crypto/[id]',
            params: { id: crypto.id || '' },
          })
        }
      >
        {/* Card content */}
      </TouchableOpacity>
    </Pressable>
  );
};
The detail screen uses dynamic routing with the cryptocurrency ID as a URL parameter (/crypto/[id]).

CryptoDetailScreen Component

The detail screen fetches and displays comprehensive cryptocurrency data:

Component Structure

CryptoDetailScreen.tsx
const CryptoDetailScreen = ({ id }: { id: string }) => {
  const navigation = useNavigation();
  const [cryptoDetails, setCryptoDetails] = useState<CryptoApiResponse | null>(null);
  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    const fetchDetails = async () => {
      setLoading(true);
      try {
        const details = await getCryptoDetails(id);
        setCryptoDetails(details);
        
        // Update navigation title with crypto name and symbol
        navigation.setOptions({
          title: `${details.name} (${details.symbol})`,
        });
      } catch (error) {
        console.error(error);
      } finally {
        setLoading(false);
      }
    };

    fetchDetails();
  }, [id]);

  // ... render logic
};

Dynamic Title

The screen title dynamically updates to show the cryptocurrency name and symbol:
navigation.setOptions({
  title: `${details.name} (${details.symbol})`,
});
// Example: "Bitcoin (BTC)"

Data Fields Displayed

The detail view shows 12 key data fields organized in a responsive grid layout:

Information Grid

CryptoDetailScreen.tsx
const volumenCambio = ((cryptoDetails.volume24 - cryptoDetails.volume24a) / 
  cryptoDetails.volume24a) * 100;

return (
  <ScrollView contentContainerStyle={styles.container}>
    <View style={styles.gridContainer}>
      {/* Grid items */}
    </View>
  </ScrollView>
);

Field Breakdown

Unidad monetaria (Name ID)
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Unidad monetaria:</Text>
  <Text>{cryptoDetails.nameid}</Text>
</View>
Shows the unique identifier for the cryptocurrency.Ranking
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Ranking:</Text>
  <Text>#{cryptoDetails.rank}</Text>
</View>
Market cap ranking position.
Precio (BTC)
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Precio (BTC):</Text>
  <Text>{cryptoDetails.price_btc}</Text>
</View>
Current price in Bitcoin.Precio (USD)
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Precio (USD):</Text>
  <Text>{formatToUSD(Number(cryptoDetails.price_usd))}</Text>
</View>
Current price in US Dollars, formatted as currency.
Cambio 1h
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Cambio 1h:</Text>
  <Text>{cryptoDetails.percent_change_1h}%</Text>
</View>
Price change over the last hour.Cambio 24h
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Cambio 24h:</Text>
  <Text>{cryptoDetails.percent_change_24h}%</Text>
</View>
Price change over the last 24 hours.Cambio 7d
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Cambio 7d:</Text>
  <Text>{cryptoDetails.percent_change_7d}%</Text>
</View>
Price change over the last 7 days.
Capitalización de mercado
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Capitalización de mercado:</Text>
  <Text>{formatToUSD(Number(cryptoDetails.market_cap_usd))}</Text>
</View>
Total market capitalization in USD.Cambio de volumen
const volumenCambio = ((cryptoDetails.volume24 - cryptoDetails.volume24a) / 
  cryptoDetails.volume24a) * 100;

<View style={styles.gridItem}>
  <Text style={styles.detailText}>Cambio de volumen:</Text>
  <Text>{volumenCambio.toFixed(2)}%</Text>
</View>
24-hour volume change calculation.
Suministro circulante
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Suministro circulante:</Text>
  <Text>{formatToUSD(Number(cryptoDetails.csupply))}</Text>
</View>
Current circulating supply.Suministro total
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Suministro total:</Text>
  <Text>{formatToUSD(Number(cryptoDetails.tsupply))}</Text>
</View>
Total supply currently in existence.Suministro máximo
<View style={styles.gridItem}>
  <Text style={styles.detailText}>Suministro máximo:</Text>
  <Text>{formatToUSD(Number(cryptoDetails.msupply))}</Text>
</View>
Maximum possible supply (if applicable).

Grid Layout

The detail view uses a responsive 2-column grid layout:
const styles = StyleSheet.create({
  gridContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-between',
    gap: 12,
  },
  gridItem: {
    backgroundColor: '#7bc4ef',
    width: '48%',  // Two columns with gap
    padding: 12,
    borderRadius: 8,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
  },
});
Each grid item is styled with a light blue background (#7bc4ef), rounded corners, and subtle shadows for visual depth.

Loading and Error States

The component handles three states during the data fetching lifecycle:
if (loading) {
  return (
    <ActivityIndicator 
      size="large" 
      color="#0000ff" 
      style={styles.loader} 
    />
  );
}

Volume Change Calculation

The screen calculates the 24-hour volume change percentage:
const volumenCambio = (
  (cryptoDetails.volume24 - cryptoDetails.volume24a) / 
  cryptoDetails.volume24a
) * 100;
This formula computes:
  • volume24: Current 24-hour trading volume
  • volume24a: Previous 24-hour trading volume
  • Result: Percentage change formatted to 2 decimal places

Styling Details

Container Styles

const styles = StyleSheet.create({
  container: {
    padding: 16,
    backgroundColor: '#f9f9f9',
    flexGrow: 1,
  },
  loader: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    height: '100%',
  },
  errorContainer: {
    justifyContent: 'center',
    alignItems: 'center',
    marginTop: 20,
  },
  errorText: {
    fontSize: 18,
    color: '#e74c3c',
    fontWeight: 'bold',
  },
  detailText: {
    fontSize: 18,
    marginBottom: 8,
    color: '#34495e',
  },
});

Key Features

  • Comprehensive Data: 12 different data points about each cryptocurrency
  • Dynamic Title: Navigation header updates with cryptocurrency name
  • Responsive Grid: 2-column layout optimized for mobile viewing
  • Loading States: Clear visual feedback during data fetching
  • Error Handling: Graceful handling of missing or failed data
  • Formatted Values: Currency and percentage formatting using utility functions
  • Calculated Metrics: Volume change computed from API data
  • Scrollable Content: ScrollView ensures all data is accessible on smaller screens
  • Visual Hierarchy: Styled grid items with shadows and consistent spacing

Build docs developers (and LLMs) love