android - 创建具有不同回调的 TouchableOpacity 项目网格的最佳方法?

标签 android react-native

我有一个应用程序,我想在其中将图像列表显示为网格,列表中的第一个元素是“添加”按钮。我还需要每个图像都是可触摸的。目前我的代码如下所示:

class RNtest extends Component {
    constructor() {
        super();

        this.state = {
            data: [],
            counter: 0 //Used to give unique numbers to the items
        };
    }

    itemPicker() {
        var temp = this.state.data;
        temp.push({text: this.state.counter});
        this.setState({
            data: temp,
            counter: this.state.counter + 1
        });
    }

    onPress() {
        console.warn('YO!');
    }

    render()  {
        return (
            <ScrollView style={styles.body}>

                <View style={styles.section}>
                    <Text style={styles.sectionHeader}>ITEMS</Text>

                    <View style={styles.gallery}>
                        <TouchableOpacity
                            style={styles.addButton}
                            onPress={this.itemPicker.bind(this)}
                        >
                            <Text>ADD</Text>
                        </TouchableOpacity>

                        {this.state.data.map(function(item) {
                            return (
                                <TouchableOpacity
                                    style={styles.item}
                                    onPress={this.onPress.bind(this)}
                                >
                                        <Text>{item.text}</Text>
                                </TouchableOpacity>
                            );
                        })}
                    </View>
                </View>

            </ScrollView>
        );
    }

}

样式表以备不时之需:

var styles = StyleSheet.create ({
    addButton: {
        alignItems: 'center',
        justifyContent: 'center',
        height: 72,
        width: 72,
        borderRadius: 2,
        marginVertical: 6,
        marginRight: 6,
        backgroundColor: 'white'
    },
    gallery: {
        flexDirection: 'row',
        flexWrap: 'wrap'
    },
    item: {
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: '#DCFFC2',
        height: 72,
        width: 72,
        borderRadius: 2,
        margin: 6
    },
    section: {
        flexDirection: 'column',
        paddingTop: 10
    },
    sectionHeader: {
        fontSize: 13,
        fontWeight: '400',
        paddingBottom: 1,
        color: '#A7A7A7'
    },
    body: {
        flex: 1,
        backgroundColor: '#EEEEEE',
        paddingVertical: 10,
        paddingHorizontal: 20
    },
});

显然 onPress 函数不起作用,因为显然 this 在 for 循环内不可见。

我可以使用 ListView,但在 renderRow 中我必须检查要呈现的项目是否是添加按钮,这也会使其他一些部分变得更加困难。

我可以在这种情况下使用 refs 吗,这是个好主意吗?

我在 Android 模拟器上运行 React Native 0.27.2。

最佳答案

如果您目前遇到的唯一问题是与范围相关的,则最好通过为处理您的 this.state 的 map 函数指定范围来更正此问题。数据。但是,我看到了一些其他问题需要对您的代码进行评论。

  1. 您的 itemPicker 函数通过 push 函数直接改变您的状态。选择使用诸如 concat 之类的函数,它将返回一个新数组(或扩展运算符)。引用docs为什么你不应该像这样直接改变状态。

  2. 确保您将唯一的 key 添加到您正在创建的生成的 TouchableOpacity 项中(请参阅 React 的警告)

我修改了您的代码示例以演示这些概念:

import React, { Component } from 'react';
import {
    ScrollView,
    StyleSheet,
    Text,
    TouchableOpacity,
    View
} from 'react-native';

class RNTest extends Component {
    constructor(props) {
        super(props);

        this.state = {
            data: [],
            counter: 0
        };
    }

    itemPicker() {
        // 'push' will mutate, concat will return a new array
        this.setState({
            data: this.state.data.concat({text: this.state.counter}),
            counter: this.state.counter + 1
        });
    }

    createButton (item, index) {
        // add a unique key, per react warnings
        return (
            <TouchableOpacity
                key={index}
                style={styles.item}
                onPress={this.onPress}>
                    <Text>{item.text}</Text>
            </TouchableOpacity>
        );
    }

    onPress() {
        console.warn('YO!');
    }

    render()  {
        return (
            <ScrollView style={styles.body}>

                <View style={styles.section}>
                    <Text style={styles.sectionHeader}>ITEMS</Text>

                    <View style={styles.gallery}>
                        <TouchableOpacity
                            style={styles.addButton}
                            onPress={this.itemPicker.bind(this)}
                        >
                            <Text>ADD</Text>
                        </TouchableOpacity>

                        {this.state.data.map(this.createButton, this)}
                    </View>
                </View>

            </ScrollView>
        );
    }

}

export default RNTest;

关于android - 创建具有不同回调的 TouchableOpacity 项目网格的最佳方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37923578/

相关文章:

javascript - 这是 shouldComponentUpdate 的合理实现吗?

android - 在 Android Studio 中运行重建项目后会发生什么?

ios - 文本输入垂直对齐

android - 自定义 View 转换为位图返回黑色图像

android - 无法将数据获取到下一个 Activity

react-native - 如何在 React Native 中重新父组件?

react-native - Reanimated v3 - 布局动画 - React-native 中的淡入和淡出

javascript - react native : how to use require(path) with dynamic urls?

java - Android 多点触控无法正常工作

java - 电池使用,会发生什么?