Ошибка загрузки родной базы шрифта

Я получаю ошибку: You started loading 'Roboto_medium', but used it before it finished loading при использовании родной базы.

Я следовал инструкциям на официальной странице.

Для создания реагировать нативное приложение я использую create-react-native-app,

App.js

export default class App extends React.Component {

async componentWillMount() {
  await Expo.Font.loadAsync({
  'Roboto': require('native-base/Fonts/Roboto.ttf'),
  'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
  'Ionicons': require('@expo/vector-icons/fonts/Ionicons.ttf'),
 });
}

 render() {
   return (
    <Container>
      <StatusBar hidden={true} />

    <Button>
      <Text>
        Button
      </Text>
    </Button>

    <ListaItens />
    </Container>
  );
}
} 

7 ответов

Решение

Вам нужно подождать, пока шрифты не загрузятся. Вы можете сделать что-то вроде этого

import React from "react";
import { StatusBar } from "react-native";
import { Container, Button, text, ListItem, Text } from "native-base";
import Expo from "expo";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loading: true };
  }

  async componentWillMount() {
    await Expo.Font.loadAsync({
      Roboto: require("native-base/Fonts/Roboto.ttf"),
      Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
      Ionicons: require("@expo/vector-icons/fonts/Ionicons.ttf"),
    });
    this.setState({ loading: false });
  }

  render() {
    if (this.state.loading) {
      return <Expo.AppLoading />;
    }
    return (
      <Container>
        <StatusBar hidden={true} />

        <Button>
          <Text>Button</Text>
        </Button>

        <ListItem />
      </Container>
    );
  }
}

Этот новый код для expo SDK 35, который был изменен на основе ответа @akhil xavier

Сначала установите expo-font

expo install 'expo-font'

вот App.js

import React from "react";
import * as Font from "expo-font";
import { ActivityIndicator } from "react-native";
import { Root } from "native-base";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { loading: true };
  }

  async componentWillMount() {
    await Font.loadAsync({
      Roboto: require("native-base/Fonts/Roboto.ttf"),
      Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
      Ionicons: require("@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf"),
    });
    this.setState({ loading: false });
  }

  render() {
    if (this.state.loading) {
      return <ActivityIndicator />;
    }
    return (
      <Root>
       <RootPage /> // starter component (i.e. nav)
      </Root>
    );
  }
}

Решение, которое мне подходит, приведено ниже. Ошибка заключалась в том, что я импортировал шрифт как (Fonts), но при его вызове не заметил 's'. Исправлено, убедившись, что имя импорта похоже на то, что вы вызываете loadAsync. В вашем проекте должен быть установлен 'expo-font', чтобы он работал

import React from "react";
import * as Font from "expo-font";
import { AppLoading } from "expo";
import MealsNavigator from "./navigation/MealsNavigator";


const fetchFonts = () => {
  return Font.loadAsync({
    "open-sans": require("./assets/fonts/OpenSans-Regular.ttf"),
    "open-sans-bold": require("./assets/fonts/OpenSans-Bold.ttf")
  });
};

export default function App() {
  const [fontLoaded, setFontLoaded] = useState(false);
  if (!fontLoaded) {
    return (
      <AppLoading
        startAsync={fetchFonts}
        onFinish={() => setFontLoaded(true)}
        onError={err => console.log(err)}
      />
    );
  }
  return <MealsNavigator />;
}

Если у кого-то возникла эта проблема с семейством шрифтов MaterialIcons, у меня была похожая проблема, и я обнаружил, что это решение работает:

https://javascriptrambling.blogspot.com.au/2018/03/expo-icon-fonts-with-react-native-and.html

Вам в основном нужно:

  1. Установите шрифты (используя npm install)
  2. Сделайте Font.loadAsync для шрифтов в вашей функции componentWillMount().
  3. Не забудьте пометить функцию componentWillMount() как асинхронную
  4. Условно отображается либо как "загрузка", либо с представлением, зависящим от состояния "загруженного" флага.

Например:

import React from 'react';
import { View } from 'react-native';
import { Avatar } from 'react-native-elements';
import { AppLoading, Font } from 'expo';

import FontAwesome  
  from './node_modules/@expo/vector-icons/fonts/FontAwesome.ttf';

import MaterialIcons  
  from './node_modules/@expo/vector-icons/fonts/MaterialIcons.ttf';


export default class App extends React.Component {
  state = {
    fontLoaded: false
  };

  async componentWillMount() {
    try {
      await Font.loadAsync({
        FontAwesome,
        MaterialIcons
      });
      this.setState({ fontLoaded: true });
    } catch (error) {
      console.log('error loading icon fonts', error);
    }
  }

  render() {
    if (!this.state.fontLoaded) {
      return <AppLoading />;
    }

    return (
      <View>
        <Text>My App</Text>
        <Avatar
          small
          rounded
          icon={{ name: 'add' }}
        /> 
      </View>
    );
  }
}

Вы должны пойти node_modules/yourPlugin/index.js найти fontFamily и удалить его

Это способ, которым я использую для загрузки шрифтов в свой проект. Я считаю это более абстрактным по сравнению со всеми другими ответами.

Что вам нужно сделать, так это создать собственный крючок для загрузки шрифтов.

Вы можете сделать это примерно так

Создайте папку с именем, в которой вы находитесь. Тогда внутри hooks папку создайте файл с именем

Внутри useFonts.js напиши вот так

      import * as Font from 'expo-font';

export default useFonts = async () =>
  await Font.loadAsync({
    Roboto: require('native-base/Fonts/Roboto.ttf'),
    Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
    Ionicons: require('@expo/vector-icons/fonts/Ionicons.ttf'),
  });

Теперь в твоем App.js напиши вот так

      import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React, { useState } from 'react';

import useFonts from './hooks/useFonts';

export default function App() {
  const [IsReady, SetIsReady] = useState(false);

  // This function will start the fontLoading
  const LoadFonts = async () => {
    await useFonts();
  };

  // This is a check to ensure fonts get loaded
  if (!IsReady) {
    return (
      <AppLoading
        startAsync={LoadFonts}
        onFinish={() => SetIsReady(true)}
        onError={() => {}}
      />
    );
  }

  // If fonts are successfully loaded then show the rest of your App
  return (
    <Container>
      <StatusBar hidden={true} />

      <Button>
        <Text>Button</Text>
      </Button>

      <ListaItens />
    </Container>
  );
}

Одна из причин, по которой он должен загружать шрифт, заключается в том, что вы используете компонент Native Base Text. Если вместо этого вы импортируете компонент React Native Text, вам даже не придется загружать шрифты, и вы не увидите эту ошибку.

Другие вопросы по тегам