Несовместимые разделительные строки ReactNative ListView

В Android 4.4 линии-разделители ListView имеют неодинаковую толщину, а некоторые из них не отображаются. Я не понимаю, как это может быть проблемой кода, вот как я их визуализирую:

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

Вот скриншот представления с этой проблемой:

введите описание изображения здесь

Эта проблема не возникает на iOS или Android 6.

У кого-нибудь была эта проблема раньше?

Обновить

Я сделал тест, это не проблема Android4. Это происходит во всех версиях API при работе на устройстве Nexus One (в эмуляторе Android).


person Giannis    schedule 24.06.2016    source источник
comment
Это проблема масштабирования? Это происходит на реальном устройстве? У меня была эта проблема с симулятором iOS раньше.   -  person JayGarcia    schedule 24.06.2016
comment
Об этом сообщил пользователь (происходит на устройстве), и я воспроизвел это на эмуляторе.   -  person Giannis    schedule 24.06.2016
comment
Я избавился от необходимости визуализировать отдельный вид separator, установив для bottomBorderWidth каждой строки значение 1px. Вы пробовали это?   -  person JayGarcia    schedule 24.06.2016
comment
Проблема все еще существует с bottomBorderWidth. Похоже, что расстояние между элементами строки не соответствует.   -  person Giannis    schedule 24.06.2016


Ответы (7)


У меня была эта проблема на iOS, и я обошел ее, добавив границу волосяного покрова, например:

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

person Julian K    schedule 12.10.2018
comment
Я исправил то же самое решение в моем собственном базовом компоненте ListItem внутри FlatList, просто добавив marginBottomWidth = borderBottomWidth, в моем случае это было 1 / PixelRatio.getPixelSizeForLayoutSize(1). В react-native=0.57.8, android. - person andrew.creamentas; 29.03.2019

Просто укажите высоту:hairlineWidth в стиле

person Gopal    schedule 02.11.2016
comment
StyleSheet.hairlineWidth, чтобы быть более конкретным. - person kwishnu; 07.01.2017
comment
На самом деле это не решает проблему. Также не устанавливаются границы самих элементов. - person Jacob Lauritzen; 02.05.2017
comment
Привет @ Яннис, ты нашел какое-нибудь решение ?? Я также столкнулся с такой же проблемой, не могли бы вы помочь мне, если у вас есть какое-либо решение? - person Vikas S; 23.08.2019

У меня была та же проблема, и я решил изменить высоту просмотра с числа на StyleSheet.hairlineWidth, как говорили некоторые люди ранее. Пытаюсь быть более наглядным/конкретным:

До:

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

После:

renderItemSeparator() {
    return (
        <View style={{ height: StyleSheet.hairlineWidth, backgroundColor: 'rgba(0,0,0,0.3)' }} />
    );
}
person Eddie Teixeira    schedule 16.11.2018

На самом деле исправления нет. Это RN "ошибка рендеринга холста". Но я нашел решение взлома.

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

Style.listView: { backgroundColor: '#fff', }, // или другой фоновый цвет, который вам нужен

Затем:

_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>
    );
}

Единственным важным стилем TouchableOpacity является Style.separatorRow для отображения вашего разделителя. Этот стиль должен быть внутри listView_item, где вы можете использовать другие стили.

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

Вы можете использовать StyleSheet.hairlineWidth вместо 1, но это не обязательно.

person Jonáš Krutil    schedule 09.02.2017
comment
Где я могу получить больше информации об ошибке RN render-canvas-bug? - person Mighty; 22.03.2018

Я сообщил об этом на GitHub.

Мой обходной путь заключался в том, чтобы стилизовать содержащее представление и текст следующим образом:

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,
      },
    });

Это ListView:

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

Выглядит хорошо:

введите здесь описание изображения

person AdamG    schedule 13.05.2017

Это происходит потому, что в вашем источнике данных есть пустые строки. Вы можете стилизовать свои разделители, чтобы увидеть это

пример

Чтобы избежать этого, просто отфильтруйте свои данные.

person Lyudmila Promyslova    schedule 25.04.2017
comment
Нет, это проблема рендеринга. - person Giannis; 25.04.2017

Я столкнулся с той же проблемой при попытке отобразить разделитель шириной 0,5.

Он правильно отображался на устройствах с соотношением пикселей 2 (например, iPhone SE 2-го поколения), но отображал случайную ширину на устройствах с соотношением пикселей 3 (например, iPhone 12).

Как следует из других ответов, использование Stylesheet.hairlineWidth устраняет проблему случайной ширины, но проблема заключалась в том, что ширина была меньше 0,5 на устройствах с соотношением пикселей 3.

Итак, это исправило мою проблему:

import { PixelRatio, View } from 'react-native';
...

export const Divider = () => {
  const width = PixelRatio.roundToNearestPixel(0.5);
  ...

  return <View style={{ width }} ... />
}
person Dangular    schedule 25.05.2021