How to Get ListView Section Header to Stick

半城伤御伤魂 提交于 2019-12-03 02:04:43

问题


I have buttons displayed on the top of the screen (used react-native-scrollable-tab-view). Underneath the buttons, I have ListView with section header on it.

Is there a way to get the header to stick to the bottom edge of the tab-view when I am scrolling?

I have had a hard time trying to get ListView's section header to stick to the bottom of Facebook TabBar, and its default is to stick to the top of the screen.

When I scroll, the section header slides under the tab-bar.

Any thoughts on this? Is there anything I should change in FacebookTabBar.js to make this work?

Without tab bar at the top

With tab bar at the top

Note: It is strange how this GIF does not show the full animation correctly; you can imagine that the list is scrolled a lot and the section header slides under the tab bar.

Section header styles

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

FacebookTabBar styles

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:


ListView Headers don't stick, you'll need to use renderSectionHeader and cloneWithRowsAndSections instead of cloneWithRows to do this.

From the React Native documentation on 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.

I tackled this same issue today. Here's how I handled it. First, in getInitialState:

getInitialState: function() {

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

Then, during my API call that gets data back, I add that response data to my dataBlob object. The key that stores it is considered the sectionId for ListView.DataSource. In this case, that sectionId is going to be the date of the posts I retrieve:

  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 accepts a dataBlob (in my case, an object) as its first argument, and optional arguments of sectionIDs and rowIDs.

Here's how renderListView looks:

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

And here's how renderSectionHeader looks:

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

Here's how it looks in the end:




回答2:


Right now if you take a look at this code, you may notice that Category is a direct child of ScrollView (the tag with tabTitle='Search').

My attempt to make this work was to let View be the direct child of ScrollView and write Category as the child of View.

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

Then I styled View in the following way:

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

This seems to have solved the problem partially. Partially, because for example, if I click Cell 2 and then pull the list up, the list view scrolls properly, and the section headers stick in the way that I expect.

However, if I initially click (continuously holding down the mouse button) and pull down the list and then try pulling it up after that, the list and its section header slide behind the tab bar thus showing the original behavior, which is not what I want to see.

Pulling up the list

Initially pulling down, and then pulling up the list



来源:https://stackoverflow.com/questions/31066437/how-to-get-listview-section-header-to-stick

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!