Как получить заголовок раздела ListView в Stick

У меня есть кнопки, отображаемые в верхней части экрана (используется реакция-нативная прокрутка-табуляция). Под кнопками у меня есть ListView с заголовком раздела.

Есть ли способ заставить заголовок придерживаться нижнего края вида табуляции при прокрутке?

G9HxH.gif

Мне было трудно попытаться получить заголовок раздела ListView, чтобы придерживаться нижней части Facebook TabBar, и по умолчанию он должен придерживаться верхней части экрана.

Когда я прокручиваю, заголовок секции скользит под панелью вкладок.

Любые мысли об этом? Есть ли что-нибудь, что я должен изменить в FacebookTabBar.js, чтобы сделать эту работу?

Без панели вкладок вверху

nobar

С панелью вкладок вверху

Примечание: странно, как этот GIF не показывает полную анимацию правильно; вы можете себе представить, что список прокручивается много, а заголовок раздела скользит под панелью вкладок.

withbar

стили заголовка разделов

catListHeaderContainer: {
    padding: 12,
    backgroundColor: '#1F2036',
}

стили FacebookTabBar

var styles = StyleSheet.create({
  tab: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingBottom: 10,
  },

  tabs: {
    height: 60,
    flexDirection: 'row',
    paddingTop: 5,
    borderWidth: 0,
    borderTopWidth: 0,
    borderLeftWidth: 0,
    borderRightWidth: 0,
    borderBottomColor: 'rgba(0,0,0,0)',
  },

  activeTabTitle: {
    marginTop: 40,
    color: '#3B5998',
  },

  nonActiveTabTitle: {
    marginTop: 40,
    color: '#BDBDBD',
  },

});

Ответ 1

Прямо сейчас, если вы посмотрите этот код, вы можете заметить, что Category является прямым дочерним элементом ScrollView ( тег tabTitle='Search').

Моя попытка сделать эту работу состояла в том, чтобы позволить View быть прямым дочерним элементом ScrollView и написать Category как дочерний элемент View.

<ScrollView tabTitle='Search' tabLabel="ion|ios-search" style={styles.tabView}>
  <View style={styles.categoryContain}>
    <Category/>
  </View>
</ScrollView>

Затем я ввел View следующим образом:

categoryContain: {
  top: 0,
  height: deviceHeight,
},

Это, похоже, частично решает проблему. Частично, потому что, например, если я нажимаю Ячейка 2, а затем вытаскиваю список вверх, просмотр списка прокручивается правильно, а заголовки разделов придерживаются того, что я ожидаю.

Однако, если я изначально нажимаю (постоянно удерживая кнопку мыши) и вытаскиваю список, а затем пытаюсь потянуть его после этого, список и заголовок его раздела скользят за панель вкладок, таким образом отображая исходное поведение, которое не то, что я хочу видеть.

Вытягивание списка

enter image description here

Изначально потянув вниз, а затем подтянув список

enter image description here

Ответ 2

Заголовки ListView не вставляются, для этого вам нужно использовать renderSectionHeader и cloneWithRowsAndSections вместо cloneWithRows.

Из документа React Native в ListView

renderSectionHeader function 

(sectionData, sectionID) => renderable

If provided, a sticky header is rendered for this section. The sticky behavior means that it will scroll with the content at the top of the section until it reaches the top of the screen, at which point it will stick to the top until it is pushed off the screen by the next section header.

Я занялся этим же вопросом сегодня. Вот как я справился с этим. Сначала в getInitialState:

getInitialState: function() {

  return {
    dataBlob: {},
    dataSource: new ListView.DataSource({
    rowHasChanged: (r1, r2) => r1 !== r2,
    sectionHeaderHasChanged: (s1, s2) => s1 !== s2
    }),
  }
},

Затем, во время моего вызова API, который возвращает данные, я добавляю данные ответа к моему объекту dataBlob. Ключ, который хранит его, считается sectionId для ListView.DataSource. В этом случае sectionId будет датой сообщений, которые я получаю:

  getAllPosts: function() {

    api.getAllPosts()
      .then((responseData) => {
        var tempDataBlob = this.state.dataBlob;
        var date = new Date(responseData.posts[0].day).toDateString();
        tempDataBlob[date] = responseData.posts;
        this.setState({
          dataBlob: tempDataBlob
        });
        ;
      }).then(() => {
        this.setState({
          dataSource: this.state.dataSource.cloneWithRowsAndSections(this.state.dataBlob),
          loaded: true
        })
      })
      .done();
  },

cloneWithRowsAndSections принимает dataBlob (в моем случае, объект) в качестве своего первого аргумента и необязательные аргументы sectionIDs и rowIDs.

Вот как выглядит renderListView:

  renderListView: function() {
    return (
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderPostCell}
        renderSectionHeader={this.renderSectionHeader}
        renderFooter={this.renderFooter}
        onEndReached={() => {this.getAllPosts(this.state.currentDay)}}
        onEndReachedThreshold={40}
        style={styles.postsListView} />
      )
  },

И вот как выглядит renderSectionHeader:

  renderSectionHeader: function(sectionData, sectionID) {
    return (
      <View style={styles.section}>
        <Text style={styles.sectionText}>{sectionID}</Text>
      </View>
      )
  },

Вот как это выглядит в конце: imgur