模态和平面清单

时间:2019-03-27 01:21:13

标签: react-native react-native-flatlist

我从事我的第一个React-native项目,也从事我的javascript工作。我至少需要一个具有自己的数据库信息的新闻应用程序。后端已经完成。现在,我正在与该应用程序作斗争-我想要一个带有Modal的弹出窗口,其中包含来自我的api的信息,例如news_image,news_content和news_title。新闻在FlatList中,现在我要单击一个项目以在模式弹出窗口中显示内容。因此,这是我在奋斗的代码。我总是出错。所以我该如何解决这个问题?坦克很多!

import React from "react";
import {
  AppRegistry,
  FlatList,
  Image,
  Platform,
  ScrollView,
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  ActivityIndicator,
  ListView,
  YellowBox,
  Alert,
  TextInput
} from "react-native";
import { WebBrowser } from "expo";
import Button from "react-native-button";
import Modal from "react-native-modalbox";
import Slider from "react-native-slider";
import { MonoText } from "../components/StyledText";
export default class NewsFeed extends React.Component {
  static navigationOptions = {
    title: "HomeScreen"
  };
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true
    };
    YellowBox.ignoreWarnings([
      "Warning: componentWillMount is deprecated",
      "Warning: componentWillReceiveProps is deprecated"
    ]);
  }
  FlatListItemSeparator = () => {
    return (
      <View
        style={{
          height: 0.5,
          width: "100%",
          backgroundColor: "#000"
        }}
      />
    );
  };
  webCall = () => {
    return fetch("http://XXXXXXXXXXXX.com/connection.php")
      .then(response => response.json())
      .then(responseJson => {
        this.setState(
          {
            isLoading: false,
            dataSource: responseJson
          },
          function() {
            // In this block you can do something with new state.
          }
        );
      })
      .catch(error => {
        console.error(error);
      });
  };
  onClose() {
    console.log("Modal just closed");
  }
  onOpen() {
    console.log("Modal just opened");
  }
  onClosingState(state) {
    console.log("the open/close of the swipeToClose just changed");
  }
  componentDidMount() {
    this.webCall();
  }
  render() {
    if (this.state.isLoading) {
      return (
        <View
          style={{ flex: 1, justifyContent: "center", alignItems: "center" }}
        >
          <ActivityIndicator size="large" />
        </View>
      );
    }
    return (
      <View style={styles.MainContainer}>
        <FlatList
          data={this.state.dataSource}
          ItemSeparatorComponent={this.FlatListItemSeparator}
          renderItem={({ item }) => (
            <View style={{ flex: 1, flexDirection: "row" }}>
              <Image
                source={{ uri: item.news_image }}
                style={styles.imageView}
              />
              <Text
                onPress={() => this.refs.modal.open()}
                style={styles.textView}
              >
                {item.news_title}
                {"\n"}
                <Text style={styles.textCategory}>{item.author}</Text>
              </Text>
              <Text style={styles.textViewDate}>{item.created_at}</Text>
              <Modal
                style={[styles.modal]}
                position={"bottom"}
                ref={"modal"}
                swipeArea={20}
              >
                <ScrollView>
                  <View style={{ width: "100%", paddingLeft: 10 }}>
                    {item.news_content}
                  </View>
                </ScrollView>
              </Modal>
            </View>
          )}
          keyExtractor={(item, index) => index.toString()}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
  MainContainer: {
    justifyContent: "center",
    flex: 1,
    margin: 5
  },
  imageView: {
    width: "25%",
    height: 100,
    margin: 7,
    borderRadius: 7
  },
  textView: {
    width: "100%",
    height: "100%",
    textAlignVertical: "center",
    padding: 10,
    fontSize: 20,
    color: "#000"
  },
  textViewDate: {
    width: "30%",
    textAlignVertical: "center",
    padding: 15,
    color: "#afafaf"
  },
  textCategory: {
    color: "#d3d3d3",
    fontSize: 12
  },
  modal: {
    justifyContent: "center",
    alignItems: "center",
    height: "90%"
  }
});

2 个答案:

答案 0 :(得分:0)

检查下面的代码,并将其与您的代码进行比较。

我不确定您的错误位于何处或确切的错误是什么,但是您可以检查下面与您的代码相似的示例代码,以进行比较。

由于自动转换为JSON和其他一些Axios,因此我在fetch()上使用了'beneficial stuff'。

npm install --save axios

代码:

import React, { Component } from 'react'
import {
    ActivityIndicator,
    FlatList,
    Image,
    ScrollView,
    Text,
    TouchableOpacity,
    View
} from 'react-native';
import Axios from 'axios';
import Modal from "react-native-modalbox";

export default class NewsFeed extends Component {
    constructor(props) {
        super(props);
        this.state = {
            dataSource: [],
            selectedIndex : -1
        }
    }

    componentDidMount = () => {
        Axios.get('<URL>')
            .then(response => {
                const { data } = response;
                this.setState({dataSource : data});
            }).catch(error => {
                const { data } = error;
                console.log(data);
            });
    }

    _openModal = index => {
        this.setState({ selectedIndex : index });
        this.modalReference.open();
    }

    _renderSeparator = () => {
        return <View style={{ flex: 1, borderBottomWidth: 0.5, borderBottomColor: '#000000' }} />
    }

    _renderItem = ({item, index}) => {
        const {news_image, news_title, news_content, author, created_at} = item;

        return <TouchableOpacity onPress={() => this._openModal(index)} >
            <View style={{ flex: 1, flexDirection: 'row' }}>
                <Image style={{ flex: 1, width: null, height: 200 }} source={{ uri: news_image }} />
                <Text>{news_title}</Text>
                <Text>{author}</Text>
                <Text>{created_at}</Text>
            </View>
        </TouchableOpacity>;
    }

    render = () => {
        const { dataSource, selectedIndex } = this.state;
        const { news_content } = dataSource[selectedIndex];

        return dataSource.length === 0 ? 
            <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
              <ActivityIndicator size="large" />
            </View> : 
            <View style={styles.MainContainer}>
                <FlatList
                    data={dataSource}
                    keyExtractor={(item, index) => index.toString()}
                    ItemSeparatorComponent={this._renderSeparator}
                    renderItem={this._renderItem}
                />
                <Modal ref={reference => modalReference = reference}>
                    <ScrollView style={{ flex: 1, padding: 20 }}>
                        <Text>{news_content}</Text>
                    </ScrollView>
                </Modal>
            </View>
    }
}

答案 1 :(得分:0)

我认为这个问题是模态的, 您可以重新编写如下代码吗?

return (
  <View style={styles.MainContainer}>
    <FlatList
      data={this.state.dataSource}
      ItemSeparatorComponent={this.FlatListItemSeparator}
      renderItem={({ item }) => (
        <View style={{ flex: 1, flexDirection: "row" }}>
          <Image source={{ uri: item.news_image }} style={styles.imageView} />
          <Text onPress={() => { this.setState({ item: item.news_content }, () => this.refs.modal.open()); }} style={styles.textView}>
            {item.news_title}
            <Text style={styles.textCategory}>{item.author}</Text>
          </Text>
          <Text style={styles.textViewDate}>{item.created_at}</Text>
        </View>
      )}
      keyExtractor={(item, index) => index.toString()}
    />
    <Modal
      style={[styles.modal]}
      position={"bottom"}
      ref={"modal"}
      swipeArea={20}
    >
      <ScrollView>
        <View style={{ width: "100%", paddingLeft: 10 }}>
          {this.state.item}
        </View>
      </ScrollView>
    </Modal>
  </View>
);

仅单个模式就足以显示弹出屏幕。

您也可以尝试一下, 将您的引用更改为

ref={ref => this.modalRef = ref}

像这样使用

this.modalRef.open()