使用动态页面视图反应原生ViewPagerAndroid

时间:2016-05-25 14:54:52

标签: android reactjs react-native

我正在我的一个组件中实现ViewPagerAndroid。寻呼机的子页面视图是动态的(也许这就是问题?)我得到了android错误'指定的孩子已经有了父。你必须首先在孩子的父母上调用removeView()。这是组件:

var PageContent = React.createClass({
    propTypes: {
        page: React.PropTypes.oneOfType([
          React.PropTypes.object, React.PropTypes.bool
        ]),
        pageNext: React.PropTypes.oneOfType([
          React.PropTypes.object, React.PropTypes.bool
        ]),
        pagePrevious: React.PropTypes.oneOfType([
          React.PropTypes.object, React.PropTypes.bool
        ]),
        positionY: React.PropTypes.object,
        positionYNext: React.PropTypes.object,
        positionYPrevious: React.PropTypes.object,
        pageDensity: React.PropTypes.number,
        updatePage: React.PropTypes.func
      },
      initialPageIndex() {
        if (this.props.page.number === 1)
          return 0;
        return 1;
      },
      onPageSelected(e) {
        var initialPageIndex = this.initialPageIndex();
        var position = e.nativeEvent.position;
        console.warn(position);
        // The initial page can have an index in the PageViewer
        // of zero or one, so we must determine the new page number
        // by checking the viewer position in terms of the true pages array.
        if (position < initialPageIndex) {
          // the user turned to the previous page!
          this.props.updatePage(this.props.page.number - 1);
        } else if (position > initialPageIndex) {
          // the user turned to the next page!
          this.props.updatePage(this.props.page.number + 1);
        }
      },
      render() {
        var pagePrevious = this.props.pagePrevious;
        var page = this.props.page;
        var pageNext = this.props.pageNext;
        var pageViews = [pagePrevious, page, pageNext].map((current, i) => {
          if (!current) return null;
          var titles = <Titles page={current}/>;
          var image = current.image
            ? <Image
                source={current.image}
              />
            : null;
          var text = <PageText page={current} pageDensity={this.props.pageDensity}/>

          var view =
            <View key={i}>
              {titles}
              {image}
              {text}
            </View>;
          return view;
        }).filter((current) => {return !!current});

        // we must dynamically determine the initial page index.  
        // Do not use state because we can derive this from the current page state.
        var initialPageIndex = this.initialPageIndex();

        return (
          <View style={styles.containerViewPager}>
            <ViewPagerAndroid
              style={styles.viewPager}
              initialPage={initialPageIndex}
              pageMargin={10}
              onPageSelected={this.onPageSelected}>
              {pageViews}
            </ViewPagerAndroid>
          </View>
        );
      }
    });

我正在为每个动态页面视图设置键属性。页面查看器是否支持动态页面?

1 个答案:

答案 0 :(得分:1)

我使用ViewPagerAndroid组件的方式存在很多问题。我试图完成页面视图数据的延迟加载(仅加载页面的数据,如果它与当前页面相邻),我的想法是在任何给定时间将页面查看的数量限制为所需的页面查看数量。

但是当您开始交换不同的子视图组件时,ViewPagerAndroid表现得很奇怪。动态添加其他页面视图是完全正确的,但是当您开始在页面视图中传递新的键属性时,它会中断。这是有道理的。寻呼机旨在自行处理用户交互和页面更改,您可以挂钩来完成您需要做的任何工作。从概念上讲,我试图在每个状态变化上构建一个全新的寻呼机。

解决方案是让页面视图担心延迟加载。为寻呼机提供应用中需要的视图,并让这些子视图管理其内容。这里是一个子页面视图没有变异的示例,每个都是延迟加载(基于用户在寻呼机中的位置):

var TestPagerAndroid = React.createClass({
  getInitialState() {
    return {
      currentPage: 0
    };
  },
  isAdjacentPage(pageNumber) {
    var currentPage = this.state.currentPage;
    var adjacentPages = [currentPage - 1, currentPage, currentPage + 1];
    return pageNumber >= 0 && pageNumber <= BOOK_LENGTH
      && adjacentPages.indexOf(pageNumber) !== -1;
  },
  getPageContent(pageNumber) {
    console.warn('store access count');
    var store = MOCK_DATA_STORE;
    return <Text>{store[pageNumber]}</Text>;
  },
  onPageSelected(e) {
    var currentPage = e.nativeEvent.position;
    this.setState({ currentPage });
  },
  render() {
    var pageViews = [];
    for (let i=0; i <=  BOOK_LENGTH; i++) {
      pageViews.push(
        <View style={styles.container} key={i}>
          <TestPageView
            pageNumber={i}
            isAdjacentPage={this.isAdjacentPage}
            getPageContent={this.getPageContent}
          />
        </View>
      );
    }
return (
      <View style={styles.containerViewPager}>
        <ViewPagerAndroid
          style={styles.viewPager}
          initialPage={0}
          pageMargin={10}
          onPageSelected={this.onPageSelected}>
          {pageViews}
        </ViewPagerAndroid>
      </View>
    );
  }
});

var TestPageView = React.createClass({
  render() {
    var pageNumber = this.props.pageNumber;
    var isAdjacent = this.props.isAdjacentPage(this.props.pageNumber);
    var content = isAdjacent
      ? this.props.getPageContent(pageNumber): null;
    return (
      <View>
        {content}
      </View>
    );
  }
});