国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

手把手教你如何自定義 React Native 底部導航欄

LiuZh / 2125人閱讀

摘要:在本指南中,我將向你演示如何創建自定義標簽欄以并與一起使用。我們將導入并使用創建默認選項卡導航器。接下來,我們將添加實際的自定義標簽欄組件。例如,當前的實現假設選項卡導航器中總會有個,聚光燈顏色在選項卡欄組件中是寫死。

如果你覺得 React Navigation 默認 Tab 組件看起來太平淡,或者想創造一些更現代的東西,那么你想法就和我一樣。 在本指南中,我將向你演示如何創建自定義標簽欄以并與 React Navigation 一起使用。

想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!

源碼已發布到 github,如果有需要,請點擊這里。

這是最終完成的樣子:

首先,讓我們初始化一個新項目并安裝幾個依賴項。在終端運行如下命令:

$ react-native init CustomTabBar
$ cd CustomTabBar
$ npm install react-navigation react-native-gesture-handler react-native-pose

React Navigation 從 V3 開始需要依賴 react-native-gesture-handler 庫,react-native-pose 是一個很棒的庫,我們將用它來制作非常簡單的動畫。

react-native-gesture-handler 需要通過 link 命令將一些配置自動關聯到原生中。

react-native link react-native-gesture-handler

現在我們可以啟動應用程序了。

首先——我們創建如下一個目錄結構,方便代碼管理:

/android
/ios
...
/src
  /AppEntry.js
  /router
    /router.js
    /index.js
  /components
  /screens
/index.js

首先,我們將創建一個 src 目錄,將我們的代碼與項目根目錄中的其他文件(package.json,app.json,.gitignore 等)分開。 screenscomponentsrouter 目錄是知名其意的。

我們從項目的根目錄中刪除默認的App.js文件,并在 index.js 中寫入import /src/AppEntry.js

/* /index.js */

import { AppRegistry } from "react-native";
import App from "./src/AppEntry";
import { name as appName } from "./app.json";

AppRegistry.registerComponent(appName, () => App);

現在我們想要使用 react-navigation 創建路由器,但是首先我們需要創建一些 screen(就是頁面)。我們將創建一個通用的 Screen 組件,它接受一個名稱并顯示它來模擬多個 Screen

/src/screens/index.js 添加如下內容:

/* /src/screens/index.js */
import React from "react"

import Screen from "./Screen"

export const HomeScreen = () => 
export const SearchScreen = () => 
export const FavoritesScreen = () => 
export const ProfileScreen = () => ;

現在我們創建 Screen 組件。

/* /src/screens/Screen.js */

import React from "react";
import { Text, View, StyleSheet } from "react-native";

const S = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#bbbbbb",
    justifyContent: "center",
    alignItems: "center"
  },
  text: { fontSize: 28, color: "#222222", textAlign: "center" }
});

const Screen = ({ name }) => (
  
    This is the "{name}" screen
  
);

export default Screen;

接著創建路由,首先在 /src/router/index.js 在添加如下內容:

/* /src/router/index.js */

export { default as Router } from "./router";

現在讓我們在 router.js 中創建基本的 BottomTabNavigator。 我們將導入 screens 并使用createBottomTabNavigator 創建默認選項卡導航器。

/* /src/router/router.js */

import { createAppContainer, createBottomTabNavigator } from "react-navigation";

import {
  HomeScreen,
  SearchScreen,
  FavoritesScreen,
  ProfileScreen
} from "../screens";

const TabNavigator = createBottomTabNavigator({
  HomeScreen,
  SearchScreen,
  FavoritesScreen,
  ProfileScreen
});

export default createAppContainer(TabNavigator);

現在我們在 AppEntry.js 中渲染路由:

/* /src/AppEntry.js */

import React from "react";

import { Router } from "./router";

export default () => ;

當我們重新加載應用程序時,應該會如下內容:

默認標簽欄支持圖標,我們將在本教程中使用 ascii 字符,當然在實際應用中可以使用 react-native-vector-icons 或自定義圖標字體。

讓我們創建一個 Icon 組件,接受參數為 namecolor 并返回圖標。

/* /src/components/index.js */

export { default as Icon } from "./Icon";


/ /src/components/Icon.js /

import React from "react";
import { Text } from "react-native";

const iconMap = {
  home: "?",
  search: "?",
  favorites: "?",
  profile: "?"
};

const Icon = ({ name, color, style, ...props }) => {
  const icon = iconMap[name];

  return {icon};
};

export default Icon;

現在我們可以在路由器中使用這個組件。我們在 router.js 中更改 screens ,以接受帶有navigationOptions 配置的對象。默認選項卡欄將 tintColor 傳遞給圖標組件,因此我們使用它來設置圖標顏色。

/* /src/router/router.js */
    
import { createAppContainer, createBottomTabNavigator } from "react-navigation";
import React from "react";
import {
  HomeScreen,
  SearchScreen,
  FavoritesScreen,
  ProfileScreen
} from "../screens";

import {Icon} from "../components"

const TabNavigator = createBottomTabNavigator({
  HomeScreen: {
    screen: HomeScreen,
    navigationOptions: {
      tabBarIcon: ({ tintColor }) => 
    }
  },
  SearchScreen: {
    screen: SearchScreen,
    navigationOptions: {
      tabBarIcon: ({ tintColor }) => 
    }
  },
  FavoritesScreen: {
    screen: FavoritesScreen,
    navigationOptions: {
      tabBarIcon: ({ tintColor }) => 
    }
  },
  ProfileScreen: {
    screen: ProfileScreen,
    navigationOptions: {
      tabBarIcon: ({ tintColor }) => 
    }
  }
});
export default createAppContainer(TabNavigator);

運行效果如下:

現在我們的標簽欄看起來好一點,但它仍然是 react-navigation 的默認標簽欄。 接下來,我們將添加實際的自定義標簽欄組件。

讓我們從創建一個自定義 TabBar 組件開始,該組件只渲染一些文本并打印傳遞過來的 props ,這樣我們就可以看到我們從導航器中得到了什么 props

/* /src/components/index.js */

export { default as Icon } from "./Icon";
export { default as TabBar } from "./TabBar";


/* /src/components/TabBar.js */

import React from "react";
import { Text } from "react-native";

const TabBar = props => {
  console.log("Props", props);

  return Custom Tab Bar;
};

export default TabBar;

使用自定義標簽欄需要配置 createBottomTabNavigator 第二個參數, 我們可以添加以下配置作為createBottomTabNavigator 的第二個參數。

如果我們查看標簽欄打印了什么,我們會看到導航欄中有 navigation.state狀態,其中也包含路由。還有 renderIcon 函數,onTabPress 和很多我們可能需要的東西。此外,我們還注意到我們在路由器配置中 tabBarOptions 是如何被注入到組件中的。

現在重新編寫 TabBar 組件。首先,讓我們嘗試重新創建默認選項卡欄。我們將在容器上設置一些樣式,以便將選項卡按鈕排成一行,并為每個路由呈現一個選項卡按鈕。我們可以使用 renderIcon 函數來渲染正確的圖標——通過查看源代碼,該函數需要傳入一個對象參數: { route, focused, tintColor }。我們添加了onPress 處理程序、易訪問性標簽,這樣就有了默認的選項卡欄。

/* /src/components/TabBar.js */

import React from "react";
import { View, Text, StyleSheet, TouchableOpacity } from "react-native";

const S = StyleSheet.create({
  container: { flexDirection: "row", height: 52, elevation: 2 },
  tabButton: { flex: 1, justifyContent: "center", alignItems: "center" }
});

const TabBar = props => {
  const {
    renderIcon,
    getLabelText,
    activeTintColor,
    inactiveTintColor,
    onTabPress,
    onTabLongPress,
    getAccessibilityLabel,
    navigation
  } = props;

  const { routes, index: activeRouteIndex } = navigation.state;

  return (
    
      {routes.map((route, routeIndex) => {
        const isRouteActive = routeIndex === activeRouteIndex;
        const tintColor = isRouteActive ? activeTintColor : inactiveTintColor;

        return (
           {
              onTabPress({ route });
            }}
            onLongPress={() => {
              onTabLongPress({ route });
            }}
            accessibilityLabel={getAccessibilityLabel({ route })}
          >
            {renderIcon({ route, focused: isRouteActive, tintColor })}

            {getLabelText({ route })}
          
        );
      })}
    
  );
};

export default TabBar;

運行后,效果如下:

現在我們知道我們可以靈活地創建自己的標簽欄,因此我們可以開始實際擴展它。 我們將使用 react-native-pose 創建一個動畫視圖,該視圖將突出顯示活動路徑 - 我們將此視圖稱為聚光燈。

首先我們可以去掉標簽。然后我們在標簽欄后面添加一個絕對視圖,它將顯示聚光燈效果。我們使用Dimensions API 計算聚光燈的偏移量。

/* /src/components/TabBar.js */

import React from "react";
import { View, Text, StyleSheet, TouchableOpacity, Dimensions } from "react-native";
import posed from "react-native-pose";

const windowWidth = Dimensions.get("window").width;
const tabWidth = windowWidth / 4;

const SpotLight = posed.View({
  route0: { x: 0 },
  route1: { x: tabWidth },
  route2: { x: tabWidth * 2 },
  route3: { x: tabWidth * 3 }
});

const S = StyleSheet.create({
  container: { flexDirection: "row", height: 52, elevation: 2 },
  tabButton: { flex: 1, justifyContent: "center", alignItems: "center" },
  spotLight: {
    width: tabWidth,
    height: "100%",
    backgroundColor: "rgba(128,128,255,0.2)",
    borderRadius: 8
  }
});

const TabBar = props => {
  const {
    renderIcon,
    getLabelText,
    activeTintColor,
    inactiveTintColor,
    onTabPress,
    onTabLongPress,
    getAccessibilityLabel,
    navigation
  } = props;

  const { routes, index: activeRouteIndex } = navigation.state;

  return (
    
      
        
      
      {routes.map((route, routeIndex) => {
        const isRouteActive = routeIndex === activeRouteIndex;
        const tintColor = isRouteActive ? activeTintColor : inactiveTintColor;

        return (
           {
              onTabPress({ route });
            }}
            onLongPress={() => {
              onTabLongPress({ route });
            }}
            accessibilityLabel={getAccessibilityLabel({ route })}
          >
            {renderIcon({ route, focused: isRouteActive, tintColor })}

            {getLabelText({ route })}
          
        );
      })}
    
  );
};

export default TabBar;

運行效果如下:

請注意,我們從未指定動畫的持續時間和行為, Pos e負責使用合理的默認值。

現在我們將為選中圖標添加一些縮放:

/* /src/components/TabBar.js */

...

const Scaler = posed.View({
  active: { scale: 1.25 },
  inactive: { scale: 1 }
});

...

現在我們可以像這樣將圖標包裝在 Scaler 組件中。

/* /src/components/TabBar.js */


  {renderIcon({ route, focused: isRouteActive, tintColor })}


運行效果如下:

我們的標簽欄開始看起來很不錯。 剩下要做的就是稍微改善一下,改變配色方案,調整我們的聚光燈,我們的組件就完成了。

現在,我們可以在這里改進一些事情。 例如,當前的實現假設選項卡導航器中總會有 4 個 Screen,聚光燈顏色在選項卡欄組件中是寫死。樣式應該通過路由器上的 tabBarOptions 配置進行動態編寫的,這邊不會講這些,大家自己動手做做。

TabBar 組件的完整代碼:

/* /src/components/TabBar.js */

import React from "react";
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
  Dimensions
} from "react-native";
import posed from "react-native-pose";

const windowWidth = Dimensions.get("window").width;
const tabWidth = windowWidth / 4;
const SpotLight = posed.View({
  route0: { x: 0 },
  route1: { x: tabWidth },
  route2: { x: tabWidth * 2 },
  route3: { x: tabWidth * 3 }
});

const Scaler = posed.View({
  active: { scale: 1.25 },
  inactive: { scale: 1 }
});

const S = StyleSheet.create({
  container: {
    flexDirection: "row",
    height: 52,
    elevation: 2,
    alignItems: "center"
  },
  tabButton: { flex: 1 },
  spotLight: {
    width: tabWidth,
    height: "100%",
    justifyContent: "center",
    alignItems: "center"
  },
  spotLightInner: {
    width: 48,
    height: 48,
    backgroundColor: "#ee0000",
    borderRadius: 24
  },
  scaler: { flex: 1, alignItems: "center", justifyContent: "center" }
});

const TabBar = props => {
  const {
    renderIcon,
    activeTintColor,
    inactiveTintColor,
    onTabPress,
    onTabLongPress,
    getAccessibilityLabel,
    navigation
  } = props;

  const { routes, index: activeRouteIndex } = navigation.state;

  return (
    
      
        
          
        
      

      {routes.map((route, routeIndex) => {
        const isRouteActive = routeIndex === activeRouteIndex;
        const tintColor = isRouteActive ? activeTintColor : inactiveTintColor;

        return (
           {
              onTabPress({ route });
            }}
            onLongPress={() => {
              onTabLongPress({ route });
            }}
            accessibilityLabel={getAccessibilityLabel({ route })}
          >
            
              {renderIcon({ route, focused: isRouteActive, tintColor })}
            
          
        );
      })}
    
  );
};

export default TabBar;

路由器配置如下:

/ /src/router/router.js /

...

const TabNavigator = createBottomTabNavigator(
  /* screen config ommited */,
  {
    tabBarComponent: TabBar,
    tabBarOptions: {
      activeTintColor: "#eeeeee",
      inactiveTintColor: "#222222"
    }
  }
);

你的點贊是我持續分享好東西的動力,歡迎點贊!

歡迎加入前端大家庭,里面會經常分享一些技術資源。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103561.html

相關文章

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<