ReactNative(3){多列布局、实现滚动效果、ReactNative路由}

多列布局

// rnc react native component
import React, {Component} from 'react';
// 组件或者API使用时,需要提前导入
import {Text, View, FlatList, Dimensions, Image} from 'react-native';
// 获取屏幕的宽高
const {height, width} = Dimensions.get('window');
// rpx换算为物理像素  使用方法  例如:30rpx  rpx(30)
const rpx = x => (width / 750) * x;
export default class App extends Component {
  // 实现一个加载网络请求获取数据,并显示到页面 需要经过以下步骤:
  // 发送请求  接收数据  存本地  做展示
  // 页面上数据 需要发生改变 一般存储在组件状态中 state
  state = {result: []};
  // 挂在时触发
  componentDidMount() {
    // 发送请求
    const url = 'https://api.apiopen.top/getWangYiNews';
    // 发送请求 JS代码  早期xmlHttpRequest
    // 新的webAPI 建议使用Fetch
    fetch(url)
      .then(res => res.json())
      .then(data => {
        console.log(data);
        this.setState({result: data.result});
      });
  }
  render() {
    return (
      <FlatList
        data={this.state.result}
        keyExtractor={(item, index) => index}
        renderItem={this._renderItem}
        // 列数
        numColumns={2}
        // 每行的样式 多列布局使用
        columnWrapperStyle={{
          justifyContent:'space-evenly',
          marginTop:rpx(10)
        }}
        ></FlatList>
    );
  }
  _renderItem = ({item}) => (
    // 计算每个元素的宽度 rpx
    // 每个块填充10 两个边 总共4个
    // 750-10*4  710/2
    // 355
    <View style={{width:rpx(355)}}>
      <Image
        source={{uri: item.image}}
        style={{width: '100%', height: rpx(200),borderRadius:rpx(10)}}></Image>
      <Text style={{fontSize: rpx(30), padding: rpx(10)}}>{item.title}</Text>
    </View>
  );
}

实现滚动效果

// rnc
/***
 * 横向滚动展示 通过FlatList实现轮播效果
 *
 *
 */
import React, {Component} from 'react';
import {Text, View, Dimensions, FlatList, Image} from 'react-native';
// rpx计算
const rpx = x => (Dimensions.get('window').width / 750) * x;
export default class App extends Component {
  banners = [
    'http://www.codeboy.com:9999/img/index/banner1.png',
    'http://www.codeboy.com:9999/img/index/banner2.png',
    'http://www.codeboy.com:9999/img/index/banner3.png',
    'http://www.codeboy.com:9999/img/index/banner4.png',
  ];
  // 挂在时触发
  componentDidMount() {
    // 启动一个定时器 实现自动滚动
    setInterval(() => {
      // 下一张
      this.current++;
      // 判断 越界情况 重置为0
      if (this.current == this.banners.length) this.current = 0;
      // 调用FlatList的滚动到指定位置方法
      this.f1.scrollToIndex({index: this.current});
    }, 2500);
  }
  render() {
    return (
      <FlatList
        data={this.banners}
        keyExtractor={(item, index) => index}
        renderItem={this._renderItem}
        // 横向排列
        horizontal
        // 按页滚动
        pagingEnabled
        // 监控滚动
        onScroll={this._onScroll}
        // ref绑定  需要调用FlatList提供到的方法
        // 当前组件类中 this.f1就代表FlatList组件对象
        ref={el => (this.f1 = el)}></FlatList>
    );
  }
  // 默认滚动第一个 下标为0
  current = 0;
  _onScroll = e => {
    // RN的事件经过特殊处理,如果打印需要先执行persist
    // e.persist();
    // console.log(e.nativeEvent.contentOffset.x);
    // 滚动过程中 滚动的距离 偏移量
    const offset_x = e.nativeEvent.contentOffset.x;
    // 滚动的位置的宽度
    const w = e.nativeEvent.layoutMeasurement.width;
    // 滚动的偏移量/滚动位置的宽度  计算出滚动的是第几个 第几页
    // console.log(offset_x / w);
    // 后续滚动 是按页滚动的 取整
    this.current = Math.round(offset_x / w);
  };
  _renderItem = ({item}) => (
    <Image
      source={{uri: item}}
      style={{width: rpx(750), height: rpx(300)}}></Image>
  );
}

ReactNative路由

  • react提供了router路由
  • roact-router-dom ReactNative为了能够在移动端有更好的使用体验,专门开发了针对RN的路由系统。
  • 官方网址:https://reactnavigation.org/

①生成几个测试页面

在页面中写入基础结构和识别内容,一定要生成组件结构,否则路由切换报错 

import React, { Component } from 'react'
import { Text, View } from 'react-native'

export default class APage extends Component {
  render() {
    return (
      <View>
        <Text style={{fontSize:30}}> C页面 </Text>
      </View>
    )
  }
}

App.js

// In App.js in a new project

import * as React from 'react';
import {View, Text} from 'react-native';

// 路由容器
import {NavigationContainer} from '@react-navigation/native';
// 栈式导航
import {createNativeStackNavigator} from '@react-navigation/native-stack';

// 1.引入页面组件
import APage from './pages/APage';
import BPage from './pages/BPage';
import CPage from './pages/CPage';
import DPage from './pages/DPage';
// 函数组件
function HomeScreen() {
  return (
    <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
      <Text>Home Screen</Text>
    </View>
  );
}

// 创建一个栈式导航
const Stack = createNativeStackNavigator();

// 应用根组件
function App() {
  return (
    // 最外层包裹一个路由容器
    <NavigationContainer>
      {/* 栈式导航 */}
      <Stack.Navigator>
        {/* 组件和路由名称的匹配对应关系 */}
        {/* name 路由名称 */}
        {/* component 组件名称 */}
        {/* 默认加载第一个Stack.Screen */}
        {/* <Stack.Screen name="Home" component={HomeScreen} /> */}
        {/* options 可定制属性 */}
        {/* 参数说明文档:https://reactnavigation.org/docs/native-stack-navigator#options */}
        <Stack.Screen
          name="A"
          component={APage}
          options={{
            headerTitle: '首页',
            headerStyle: {backgroundColor: 'orangered'},
            headerTitleStyle: {color: 'white'},
          }}></Stack.Screen>
        <Stack.Screen name="B" component={BPage}></Stack.Screen>
        <Stack.Screen name="C" component={CPage}></Stack.Screen>
        <Stack.Screen name="D" component={DPage}></Stack.Screen>
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

pages\APage.js

import React, {Component} from 'react';
import {Text, View, TouchableOpacity, StyleSheet} from 'react-native';

/**
 * 路由会向组件props注入两个属性
 * 1.navigation 包含操作路由的方法  跳转方法
 * 2.route  包含了路由的相关参数
 *
 */

export default class APage extends Component {
  render() {
    // 解构出跳转方法
    const {push} = this.props.navigation;
    // push('路由名称')
    return (
      <View style={{justifyContent: 'center', alignItems: 'center'}}>
        <TouchableOpacity
          activeOpacity={0.7}
          style={ss.btn}
          onPress={() => push('B')}>
          <Text style={{fontSize: 30, color: 'white'}}>跳转到B页面</Text>
        </TouchableOpacity>
        <TouchableOpacity
          activeOpacity={0.7}
          style={ss.btn}
          onPress={() => push('C')}>
          <Text style={{fontSize: 30, color: 'white'}}>跳转到C页面</Text>
        </TouchableOpacity>
        {/* 参数传递  通过push方法的第二个参数 */}
        <TouchableOpacity
          activeOpacity={0.7}
          style={ss.btn}
          onPress={() => push('D',{name:'JavaScript',msg:'JavaScript是React的基础'})}>
          <Text style={{fontSize: 30, color: 'white'}}>跳转到D页面</Text>
        </TouchableOpacity>
      </View>
    );
  }
}
const ss = StyleSheet.create({
  btn: {
    backgroundColor: '#007acc',
    padding: 10,
    marginTop:10
  },
});

pages\DPage.js

import React, {Component} from 'react';
import {Text, View} from 'react-native';

export default class DPage extends Component {
  // 组件挂在时
  componentDidMount() {
    // 获取路由参数
    // console.log(this.props);
    // const {name, msg} = this.props.route.params;
    // console.log('name:',name);
    // console.log('msg:',msg);
  }
  render() {
    const {name, msg} = this.props.route.params;
    return (
      <View>
        <Text style={{fontSize: 30}}> D页面 </Text>
        <Text style={{fontSize: 30}}>name:{name}</Text>
        <Text style={{fontSize: 30}}>msg:{msg}</Text>
      </View>
    );
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值