android - 使用动态页面 View 对 native ViewPagerAndroid 使用react

标签 android reactjs react-native

我正在我的一个组件中实现 ViewPagerAndroid。寻呼机的子页面 View 是动态的(也许这就是问题所在?)我收到 android 错误“指定的子项已经有父项”。您必须首先对 child 的 parent 调用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>
        );
      }
    });

我正在为每个动态页面 View 设置关键属性。页面查看器支持动态页面吗?

最佳答案

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

但是当您开始交换不同的 subview 组件时,ViewPagerAndroid 的行为会很奇怪。动态添加额外的页面 View 是完全可以的,但是当您开始在页面 View 中传递新的关键属性时,它就会中断。这是有道理的。寻呼机旨在自行处理用户交互和页面更改,您可以挂接以执行您需要执行的任何工作。从概念上讲,我试图在每次状态更改时构建一个全新的寻呼机。

解决办法是让页面 View 担心延迟加载。为寻呼机提供应用程序中所需的 View ,并让这些 subview 管理其内容。下面是一个示例,其中子页面 View 不会发生变化,并且每个子页面 View 都是延迟加载的(基于用户在寻呼机中的位置):

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

关于android - 使用动态页面 View 对 native ViewPagerAndroid 使用react,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37440798/

相关文章:

android - 在操作栏图标上添加文本时出现 java.lang.NullPointerException

android - 嵌套的 recyclerview View ,如播放 Play 商店应用

javascript - 无法使用路由器上下文 [react-router v4]

javascript - React 性能并将向下箭头函数作为 props 传递

react-native - 如何从 React-Native 中的选择器获取多个值?

使用 getStringArray 时出现 java.lang.NullPointerException

Android 开发人员指南/Android Studio 报告错误的最小 API 级别

javascript - 如何在 ReactJs 中将值从父元素传递到子元素?

node.js - 如何以编程方式启动/停止 Metro Bundler

react-native - undefined 不是一个对象(评估 this.props.navigator.push)