ReactNative ListView inconsistent separator lines

2019-06-18 23:10发布

On Android 4.4, ListView separator lines are inconsistent in thickness, and some do not render. I can't see how this can be a code issue, this is how I render them:

     separator: {
        height: 1,
        backgroundColor: 'grey',
      }
      ...
      <ListView
      renderSeparator={(sectionID, rowID) =>
        <View key={`${sectionID}-${rowID}`} style={styles.separator} />
      }
      .../>

Here is a screenshot of a View with this problem:

enter image description here

This issue does not happen on iOS or Android 6.

Anyone had this problem before?

Update

I did a test, this is not Android4 issue. It happens on all API version when running on Nexus One device (in android emulator)

6条回答
戒情不戒烟
2楼-- · 2019-06-19 00:05

Actually there is no fix. It's RN "render-canvas-bug". But I found hack solution.

<ListView
    style={Style.listView}
    dataSource={data}
    renderRow={(data) => this._renderRow(data)}
    />`

Style.listView: { backgroundColor: '#fff', }, // or another backgroundColor you need

Then:

_renderRow(goods) {

    return (
        <View key={'goods_' + goods.id} style={Style.listView_item}>
            <TouchableOpacity or View or ...
                style={[Style.flex, Style.flexRow, Style.separatorRow, Style.u_paddingVerticalS, Style.u_middle]}
                onPress={() => this._xyz(goods)}>
                <View>
                    <AppFont>{goods.name}</AppFont>
                </View>
            </TouchableOpacity or View or ...>
        </View>
    );
}

Only important TouchableOpacity style is Style.separatorRow to render your separator. This style should be inside listView_item, where you can use another styles.

listView: {
    backgroundColor: '#fff',
},
listView_item: {
    paddingHorizontal: em(1.5),
},
flex: {
    flex: 1,
},
flexRow: {
    flexDirection: 'row',
},
separatorRow: {
    marginBottom: 1,
    borderBottomWidth: 1,
    borderBottomColor: Colors.canvasColor,
},

You can use StyleSheet.hairlineWidth instead of 1 but it's not a must.

查看更多
混吃等死
3楼-- · 2019-06-19 00:06

I had the same issue and solved changing the view height from a number to StyleSheet.hairlineWidth as some folks said before. Trying to be more visual/specific:

Before:

renderItemSeparator() {
    return (
        <View style={{ height: .2, backgroundColor: 'rgba(0,0,0,0.3)' }} />
    );
}

After:

renderItemSeparator() {
    return (
        <View style={{ height: StyleSheet.hairlineWidth, backgroundColor: 'rgba(0,0,0,0.3)' }} />
    );
}
查看更多
别忘想泡老子
4楼-- · 2019-06-19 00:08

Just give the height:hairlineWidth in style

查看更多
虎瘦雄心在
5楼-- · 2019-06-19 00:11

I had this issue on iOS and worked around it by adding a hairline margin, like so:

<View
    style={{
      ...styles,
      borderWidth: StyleSheet.hairlineWidth,
      margin: StyleSheet.hairlineWidth,
    }}
>
    {// ...row content}
</View>

查看更多
劳资没心,怎么记你
6楼-- · 2019-06-19 00:12

I reported it on GitHub

My workaround was to style the containing view and text like this:

const styles = StyleSheet.create({
      rowViewContainer: {
        flex: 1,
        paddingRight: 15,
        paddingTop: 13,
        paddingBottom: 13,
        borderBottomWidth: 0.5,
        borderColor: '#c9c9c9',
        flexDirection: 'row',
        alignItems: 'center',
      },
      rowText: {
        marginLeft: 15,
      },
    });

This is the ListView:

<ListView
            dataSource={this.state.dataSource}
             renderRow={(data) => <View style={styles.rowViewContainer}>
               <Text style={styles.rowText}>
                 {data.bb_first_name}
               </Text>
             </View>}
          />

Looks nice:

enter image description here

查看更多
放荡不羁爱自由
7楼-- · 2019-06-19 00:12

This happens because you have empty rows in your data source. You can style your separators to see it

example

To avoid this just filter your data.

查看更多
登录 后发表回答