在React Native中实现SwipeableListView示例

我一直在使用SoundCloud API开发音乐播放器应用程序,这是我在开发有关编辑播放列表(尤其是从列表中删除曲目)的功能时的故事。

首先,这是这个故事的输出

为了实现可滑动的列表视图,我用谷歌搜索了两个开源组件。

  • https://github.com/jemise111/react-native-swipe-list-view
  • https://github.com/dancormier/react-native-swipeout

但是,我发现了一篇有趣的文章,RN从v0.27.0开始已经添加了我需要的组件。 👍

这是一项实验性功能,至今仍然没有有关如何使用它的官方文档,因此对于像我这样的人来说,找到它并不容易。 😞

无论如何, SwipeableListView基本上是ListView的扩展组件。 因此,除了与滑动相关的功能外,它的用法类似于ListView

创建数据源

首先,我们需要使用行数据创建数据源,但是两者之间创建数据源的方式略有不同。

以下是为ListView创建数据源的一般方法。

  const ds = new ListView.DataSource({rowHasChanged:(r1,r2)=> r1!== r2}); 
this.state = {
数据源:ds.cloneWithRows(tracks),
};

下面是如何创建SwipeableListView数据源。

  const ds = SwipeableListView.getNewDataSource(); 
this.state = {
数据源:
ds.cloneWithRowsAndSections(... this.genDataSource(tracks)),
};

在这里,我们发现两个区别:一个是如何创建DataSource对象,另一个是cloneWithRows不支持cloneWithRows方法。 因此,您应该管理dataBlob,sectionIdentities,rowIdentities,这是通过genDataSource方法完成的。

  genDataSource( rowDataArray < any >){ 
const dataBlob = {};
const sectionIDs = ['Section 0'];
const rowIDs = [[]];

/ **
*下面的dataBlob示例:
{
“第0节”:{
“第0行”:{
id:“ 0”,
文字:“第0行文字”
},
“第1行”:{
id:“ 1”,
文字:“第1行文字”
}
}
}
* /
dataBlob ['Section 0'] = {};
rowData.forEach(( elindex )=> {
const rowName =`$ {index}`;
dataBlob [sectionIDs [0]] [rowName] = {
id:rowName,
... el,
};
rowIDs [0] .push(rowName);
});
返回[dataBlob,sectionID,rowID];
}

重要的是要认识到,当您使用cloneWithRows您只需要将行数据(主要是数组)作为dataBlob传递,但是在这种情况下,需要对行数据进行调整以供以后使用。 上面的代码段中介绍了简单格式。

renderRow和renderQuickActions

renderRowListView renderRow 。 但是,如果在单击“打开行”时关闭了选定的行,则应检查当前是否存在任何行。

  onSelectRow( rowID ){ 
const openID = this.state.dataSource.getOpenRowID();
如果(openID &&(openID === rowID)){
this.setState({
dataSource:this.state.dataSource.setOpenRowID(null),
});
}
//添加更多代码
}
  renderRow( rowDatasectionIDrowID ){ 
const {title,artist,image_url} = rowData;
返回(
this.onSelectRow(rowID)}>
생략

);
}

getOpenRowID是一种返回当前打开的行的rowID的方法。 如果没有打开的行,则返回null 。 因此,要关闭打开的行,您可以比较两个值(选定的行ID和当前打开的行ID),并将null传递给setOpenRowID以关闭行。

用户滑出时可见的区域由renderQuickActions控制,有两种方法可以呈现快速动作。

  1. 预定义的标准组件
  2. 用户定义的自定义组件

在第一种情况下,可以将SwipeableQuickActionsSwipeableQuickActionButton组合在一起,以一种简便的方式呈现快速动作。

  renderStandardQuickActions( rowDataobjectsectionIDstringrowIDstring ){ 
返回(

<SwipeableQuickActionButton
imageSource = {{uri:'https://unsplash.it/300/300?random'}}
imageStyle = {styles.thumbnail}
onPress = {()=> {}}
text = {'Action'}
textStyle = {{color:'white'}}
/>

);
}

但是,正如您在上面看到的, SwipeableQuickActionButton接收图像和文本道具,这意味着它在内部包含图像和文本组件。 对于Image,它是必填属性。 (我不知道为什么它是必需的道具,因为我找不到与它们有关的任何有用的用例)

因此,我的render方法返回自定义操作按钮。

  onDeleteRow( index ){ 
曲目= [
... tracks.slice(0,index),
... tracks.slice(index + 1),
];
  const ds = SwipeableListView.getNewDataSource(); 
this.setState({
数据源:ds.cloneWithRowsAndSections(... this.genDataSource(tracks)),
});
}
  renderCustomQuickActions( rowDataobjectsectionIDstringrowIDstring ){ 
返回(

<TouchableHighlight
style = {[styles.actionButton,{backgroundColor:'gold'}]}
underlayColor =“ transparent”
onPress = {()=> 控制台 .log(rowID)}>


<TouchableHighlight
style = {[styles.actionButton,{backgroundColor:'goldenrod'}]}
underlayColor =“ transparent”
onPress = {()=> this.onDeleteRow(parseInt(rowID))}>



);
}

包起来

做完了! 这不容易吗? SwipeableListView包含非常基本的功能,用于在列表视图中进行刷卡。 如果您需要更复杂的动画或更多的自定义设置,则应使用第三方组件,但如果不需要, SwipeableListView可能是不错的选择!

您可以查看完整的源代码,还可以通过小吃测试示例应用程序。 另外,您也可以使用此故事的韩语版本。