我已经尝试用几种方法来预装图像,但没有任何成功。

这是我最小的工作例子,请注意,如果有几个不同的图像,如果加载一个新的图像,就会发生闪烁(例如,我有两个蓝色的按钮,在我点了第一个后,第二个会正常工作,但如果我再点一个橙色的按钮,就会再次出现第一次闪烁,至少在应用启动后我没有点过另一个橙色按钮)。

import React, { Component } from 'react';
import {StyleSheet, Text, TouchableWithoutFeedback, View, Image, ScrollView, 
Button, BackHandler} from 'react-native';
export default class Touchables extends Component {
  constructor(props) {
    super(props);
    this.state = {alarm1: (<Image source={require("./assets/alarmoff.png")} 
  style={styles.imageButton}/>),
  componentWillMount(){
  //trying to preload all Images, but it does not help.
    (<Image source={require("./assets/alarmon.png")} style= 
      {styles.imageButton}/>)
  render() {
    return (
      <ScrollView style={styles.contentContainer}>
     <View style={{flex: 3, flexDirection: 'row'}}>
        <View style={styles.container}>
          <TouchableWithoutFeedback onPressIn={() => this.setState({alarm1: 
             <Image source={require("./assets/alarmon.png")} style={styles.imageButton}/>})} onPressOut={() => this.setState({alarm1:  <Image source={require("./assets/alarmoff.png")} style={styles.imageButton}/>})}>
            <View style={styles.button}>
              {this.state.alarm1}
            </View>
          </TouchableWithoutFeedback>
          <Text style={styles.text}>This button flickers on first click. Restart App completly to see the issue. Reloading is not enough.</Text>
        </View>
       </View>
        <Button
         onPress={() => BackHandler.exitApp()}
         title="Exit App"
         color="#841584"
         accessibilityLabel="Android only I guess."
       </View>
     </ScrollView>
const styles = StyleSheet.create({
  container: {
    flex: 2,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
    marginBottom: 30
 button: {
    backgroundColor: '#fff',
    borderRadius: 20,
    padding: 10,
    marginBottom: 20,
    shadowColor: '#303838',
    shadowOffset: { width: 0, height: 5 },
    shadowRadius: 10,
    shadowOpacity: 0
  contentContainer: {
    paddingVertical: 20,
    flex: 1,
    backgroundColor: '#fff',
 text:{
    color: '#000',
    marginBottom: 30
 imageButton: {
   flex: 1,
   width: 240,
   height: 200,
   marginBottom: -15,
   marginTop: 10,
   resizeMode: 'cover'

所以我的问题是,我怎样才能阻止应用程序启动后图像的闪烁?

我为显示我的问题而建立的小演示应用程序的完整版本可在我的Github Repository

android
ios
react-native
frankenapps
frankenapps
发布于 2018-11-03
5 个回答
PushpikaWan
PushpikaWan
发布于 2018-11-11
已采纳
0 人赞同

在加载不同分辨率的图像时,可能会有一个性能问题。你可以使用https://github.com/DylanVann/react-native-fast-image模块来加载图像。

你可以添加并链接它,如下所示

# Install
yarn add react-native-fast-image
# Automatic linking. (other linking methods listed below)
react-native link react-native-fast-image

之后,你可以导入它并使用它,就像下面的例子一样

import FastImage from 'react-native-fast-image'
    const YourImage = () =>
      <FastImage
        style={styles.image}
        source={{
          uri: 'https://unsplash.it/400/400?image=1',
          headers:{ Authorization: 'someAuthToken' },
          priority: FastImage.priority.normal,
        resizeMode={FastImage.resizeMode.contain}

我从那个 repo 中复制了这个例子。你也可以在那里找到文档。试试吧。它将提高图像加载性能。那么很可能闪烁的问题就会得到解决。

谢谢你的提示。问题是,我似乎不能用这个模块使用本地图片,这对我来说很重要。
@frankenapps 据我所知,本地图片也需要相关设备的相关分辨率,否则,图片将被转换为相关类型和显示。
react-native-fast-image资源库看起来已经死了,要小心选择这个路径github.com/DylanVann/react-native-fast-image/issues/685
Fahmid
Fahmid
发布于 2018-11-11
0 人赞同

对我来说,当我把图像组件放在FlatList ListHeaderComponent组件中时,会造成闪烁的问题。所以。

  • 导致闪烁的代码。

    ListHeaderComponent={HeadComponent}

  • HeadComponent基本上是在render里面,并且有代码const HeadComponent = () => { return (<Image...

  • 修复闪烁的代码。

    ListHeaderComponent={this.renderHeader}

  • 替换代码4】是一个使用代码renderHeader () { return (<Image...返回与HeadComponent相同内容的函数

    Hope this helps someone.

    Darshil Rathod
    Darshil Rathod
    发布于 2018-11-11
    0 人赞同

    当我把图像组件放在FlatList ListHeaderComponent组件中时,会引起闪烁的问题。

    为了解决这个问题,我添加了useCallBack钩子

    const ListComponent = useCallBack(() => {
    // your code
    }, [])
    ListHeaderComponent={ListComponent}
    

    For me it solved the flickering issue

    frankenapps
    frankenapps
    发布于 2018-11-11
    0 人赞同

    好吧,我有一个变通的办法(算是吧...)。 在我的componentDidMount()中我现在确实将按钮设置为按下的状态,等待一段时间,直到图像被显示和缩放,然后我再将状态设置为关闭,就像这样。

    componentDidMount(){
       this.setState({alarm1: <Image source={require("./assets/alarmon.png")} style={styles.imageButton}/>})
       setTimeout(()=>{this.setState({alarm1: <Image source={require("./assets/alarmoff.png")} style={styles.imageButton}/>})}, 1000); 
    

    我试着把超时时间降低到一秒以内,但在我的旧手机(而且很慢)上,应用加载后第一次按压时又开始闪烁。

    这显然会导致按钮的状态在应用加载后被改变,但如果所有按钮在应用启动后闪烁一次,在我看来,这比每个按钮在第一次按下时闪烁要好。