如何使用ListView交换行动画? (React Native)

时间:2016-10-09 01:36:20

标签: listview reactjs react-native layout-animation

我正在尝试使用React Native ListView

动画交换两行

这是我的数据源代码(在我的渲染方法中):

const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1.id !== r2.id})
var dataSource = ds.cloneWithRows(state.todoLists[this.props.index].todos.slice())

这是我的交换代码(使用MobX):

    var {todo, i} = forID(state.todoLists[list].todos, id) //Gets index and todo from  id
    state.todoLists[list].todos.splice(i, 1)
    state.todoLists[list].todos.push({...todo, done: !todo.done})

正如您所看到的,等式是持久的,因为数组项目只是向下移动。

如果我尝试LayoutAnimation,我会觉得这很奇怪: enter image description here

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我怀疑问题在于(根据您的说法)您在render方法中创建了DataSource。您应该在构造函数(或ListView.DataSource)中创建componentWillMount对象,然后在数据更改时调用cloneWithRows,而不是render。问题是,通过在每个渲染上重新创建一个新的DataSource,它永远不会调用rowHasChanged函数,因为数据源中从未有过先前的状态。

示例正确实施

在下面的示例中,我在构造函数中设置数据源并将其存储在状态中。然后一旦安装,我就加载todos,并在状态下更新数据源,这将触发重新渲染。

然后,当你想将todo移动到底部时,你会调用this.moveItemToBottom(id)来修改状态,并更新状态的数据源,并在设置LayoutAnimation后重新渲染。



class TodoList extends Component {
  constructor(props, context) {
    super(props, context);

    this.state = {
      ds: new ListView.DataSource({
        rowHasChanged: (r1, r2) => (r1 !== r2),
      }),
    }; 
  }

  componentDidMount() {
    loadInitialData();
  }
  
  loadInitialData() {
    // Do something to get the initial list data
    let todos = someFuncThatLoadsTodos();

    this.setState({
      ds: this.state.ds.cloneWithRows(todos),
    });
  }

  moveItemToBottom(id) {
    // get your state somewhere??
    let todos = state.todoLists[list].todos;

    let {todo, i} = forID(state.todoLists[list].todos, id)
    todos.splice(i, 1).push({...todo, done: !todo.done});
    
    LayoutAnimation.easeInEaseOut();
    this.setState({
      ds: this.state.ds.cloneWithRows(todos),
    });
  }
  
  render() {
    return (
      <ListView
        dataSource={this.ds}
        // Other props
      />
    );
  }
}
&#13;
&#13;
&#13;

编辑/注意:我的例子没有考虑与MobX有关的任何事情。我还没有使用它,但是从粗略的看,你可能需要观察todos列表并在它更新时更新数据源,并且让moveItemToBottom方法更新MobX状态并依赖于observable使用克隆的数据源到setState