23、React Native 中的图像显示控制与离线处理

React Native图像显示控制与离线处理

React Native 中的图像显示控制与离线处理

在 React Native 开发中,图像显示控制和离线处理是非常重要的部分,它们能够显著提升应用的用户体验。下面将详细介绍图像显示控制和离线处理的相关内容。

图像显示控制

在 React Native 中,图像的显示控制包括图像大小调整、懒加载和图标渲染等方面。

图像大小调整

图像的 width height 样式属性决定了其在屏幕上的渲染大小。若没有设置这两个属性,图像将无法渲染。以下是一个示例代码,展示了如何使用滑块动态调整图像的尺寸:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
  Text,
  Image,
  Slider,
} from 'react-native';
import { fromJS } from 'immutable';
import styles from './styles';

class ResizingImages extends Component {
  state = {
    data: fromJS({
      source: require('./images/flux.png'),
      width: 100,
      height: 100,
    }),
  };

  get data() {
    return this.state.data;
  }

  set data(data) {
    this.setState({ data });
  }

  render() {
    const {
      source,
      width,
      height,
    } = this.data.toJS();
    return (
      <View style={styles.container}>
        <Image
          source={source}
          style={{ width, height }}
        />
        <Text>Width: {width}</Text>
        <Text>Height: {height}</Text>
        <Slider
          style={styles.slider}
          minimumValue={50}
          maximumValue={150}
          value={width}
          onValueChange={(v) => {
            this.data = this.data
              .merge({
                width: v,
                height: v,
              });
          }}
        />
      </View>
    );
  }
}

AppRegistry.registerComponent(
  'ResizingImages',
  () => ResizingImages
);

上述代码中, ResizingImages 组件通过滑块改变图像的 width height 状态,从而实现图像大小的动态调整。

懒加载图像

有时候,我们不希望图像在渲染时立即加载。例如,当图像还未在屏幕上显示时,提前加载可能会影响性能。这时可以使用懒加载,在图像加载时显示占位符图像。以下是实现懒加载的代码:

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

const placeholder = require('./images/placeholder.png');

const Placeholder = props =>
  new Map([
    [true, null],
    [false, (
      <Image
        {...props}
        source={placeholder}
      />
    )],
  ]).get(props.loaded);

class LazyImage extends Component {
  static propTypes = {
    style: PropTypes.shape({
      width: PropTypes.number.isRequired,
      height: PropTypes.number.isRequired,
    }),
  };

  constructor() {
    super();
    this.state = {
      loaded: false,
    };
  }

  render() {
    const {
      props: {
        style: {
          width,
          height,
        },
      },
      state: {
        loaded,
      },
    } = this;
    return (
      <View style={{ width, height }}>
        <Placeholder loaded={loaded} {...this.props} />
        <Image
          {...this.props}
          onLoad={() => this.setState({
            loaded: true,
          })}
        />
      </View>
    );
  }
}

export default LazyImage;

使用 LazyImage 组件的示例代码如下:

/* eslint-disable global-require */
import React, { Component } from 'react';
import {
  AppRegistry,
  View,
} from 'react-native';
import styles from './styles';
import LazyImage from './LazyImage';
import Button from './Button';

const remote = 'https://facebook.github.io/react/img/logo_small_2x.png';

class LazyLoading extends Component {
  state = {
    source: null,
  }

  render() {
    return (
      <View style={styles.container}>
        <LazyImage
          style={{ width: 200, height: 100 }}
          resizeMode="contain"
          source={this.state.source}
        />
        <Button
          label="Load Remote"
          onPress={() => this.setState({
            source: { uri: remote },
          })}
        />
      </View>
    );
  }
}

AppRegistry.registerComponent(
  'LazyLoading',
  () => LazyLoading
);

在上述代码中, LazyImage 组件初始状态下 loaded false ,会显示占位符图像。当图像加载完成后, loaded 变为 true ,占位符图像将被替换为实际图像。

图标渲染

在 React Native 组件中渲染图标可以提高应用的可用性。可以使用 react-native-vector-icons 包来引入各种矢量字体包。安装步骤如下:
1. 运行 npm install react-native-vector-icons --save 安装依赖。
2. 运行 react-native link 进行链接。

以下是一个渲染 FontAwesome 图标的示例代码:

import React, { Component } from 'react';
import {
  AppRegistry,
  View,
  Picker,
  ListView,
  Text,
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';
import { fromJS } from 'immutable';
import styles from './styles';
import iconNames from './icon-names.json';

class RenderingIcons extends Component {
  state = {
    data: fromJS({
      selected: 'Web Application Icons',
      icons: iconNames,
      listSource: new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2,
      }),
    }),
  }

  get data() {
    return this.state.data;
  }

  set data(data) {
    this.setState({ data });
  }

  updateListSource = (selected) => {
    this.data = this.data
      .update('listSource', listSource =>
        listSource.cloneWithRows(
          this.data
            .getIn(['icons', selected])
            .toJS()
        )
      )
      .set('selected', selected);
  }

  componentWillMount() {
    this.updateListSource(this.data.get('selected'));
  }

  render() {
    const {
      updateListSource,
    } = this;
    const selected = this.data
      .get('selected');
    const categories = this.data
      .get('icons')
      .keySeq()
      .toJS();
    const listSource = this.data
      .get('listSource');
    return (
      <View style={styles.container}>
        <View style={styles.picker}>
          <Picker
            selectedValue={selected}
            onValueChange={updateListSource}
          >
            {categories.map(c => (
              <Picker.Item
                key={c}
                label={c}
                value={c}
              />
            ))}
          </Picker>
        </View>
        <ListView
          style={styles.icons}
          dataSource={listSource}
          renderRow={icon => (
            <View style={styles.item}>
              <Icon
                name={icon}
                style={styles.itemIcon}
              />
              <Text style={styles.itemText}>
                {icon}
              </Text>
            </View>
          )}
        />
      </View>
    );
  }
}

AppRegistry.registerComponent(
  'RenderingIcons',
  () => RenderingIcons
);

在这个示例中,用户可以通过选择不同的图标类别来显示相应的图标列表。

离线处理

在移动应用开发中,网络连接不稳定是常见的情况。因此,需要对网络状态进行检测、本地数据存储和数据同步等操作。

网络状态检测

使用 NetInfo 工具可以检测网络连接状态。以下是一个示例代码:

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  View,
  NetInfo,
} from 'react-native';
import { fromJS } from 'immutable';
import styles from './styles';

const connectedMap = {
  none: 'Disconnected',
  unknown: 'Disconnected',
  wifi: 'Connected',
  cell: 'Connected',
  mobile: 'Connected',
};

class NetworkState extends Component {
  state = {
    data: fromJS({
      connected: '',
    }),
  }

  get data() {
    return this.state.data;
  }

  set data(data) {
    this.setState({ data });
  }

  onNetworkChange = (info) => {
    this.data = this.data.set(
      'connected',
      connectedMap[info]
    );
  }

  componentWillMount() {
    NetInfo.addEventListener(
      'change',
      this.onNetworkChange
    );
  }

  componentWillUnmount() {
    NetInfo.removeEventListener(
      'change',
      this.onNetworkChange
    );
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>{this.data.get('connected')}</Text>
      </View>
    );
  }
}

AppRegistry.registerComponent(
  'NetworkState',
  () => NetworkState
);

在这个示例中, NetworkState 组件会根据 NetInfo change 事件更新网络连接状态,并在界面上显示相应的信息。

本地数据存储

AsyncStorage API 可用于在 React Native 应用中存储数据,它在 iOS 和 Android 平台上的使用方式相同。以下是一个允许用户输入键值对并存储的示例代码:

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  TextInput,
  View,
  ListView,
  AsyncStorage,
} from 'react-native';
import { fromJS } from 'immutable';
import styles from './styles';
import Button from './Button';

class StoringData extends Component {
  state = {
    data: fromJS({
      key: null,
      value: null,
      source: new ListView.DataSource({
        rowHasChanged: (r1, r2) => r1 !== r2,
      }),
    }),
  }

  get data() {
    return this.state.data;
  }

  set data(data) {
    this.setState({ data });
  }

  setItem = () =>
    AsyncStorage
      .setItem(
        this.data.get('key'),
        this.data.get('value')
      )
      .then(() => {
        this.data = this.data
          .delete('key')
          .delete('value');
      })
      .then(() => this.loadItems())

  clearItems = () =>
    AsyncStorage
      .clear()
      .then(() => this.loadItems())

  async loadItems() {
    const keys = await AsyncStorage.getAllKeys();
    const values = await AsyncStorage.multiGet(keys);
    this.data = this.data
      .update(
        'source',
        source => source.cloneWithRows(values)
      );
  }

  componentWillMount() {
    this.loadItems();
  }

  render() {
    const {
      setItem,
      clearItems,
    } = this;
    const {
      source,
      key,
      value,
    } = this.data.toJS();
    return (
      <View style={styles.container}>
        <Text>Key:</Text>
        <TextInput
          style={styles.input}
          value={key}
          onChangeText={(v) => {
            this.data = this.data.set('key', v);
          }}
        />
        <Text>Value:</Text>
        <TextInput
          style={styles.input}
          value={value}
          onChangeText={(v) => {
            this.data = this.data.set('value', v);
          }}
        />
        <View style={styles.controls}>
          <Button
            label="Add"
            onPress={setItem}
          />
          <Button
            label="Clear"
            onPress={clearItems}
          />
        </View>
        <View style={styles.list}>
          <ListView
            enableEmptySections
            dataSource={source}
            renderRow={([k, v]) => (
              <Text>{v} ({k})</Text>
            )}
          />
        </View>
      </View>
    );
  }
}

AppRegistry.registerComponent(
  'StoringData',
  () => StoringData
);

在这个示例中,用户可以输入键值对,点击“Add”按钮将其存储到本地,点击“Clear”按钮可以清空本地存储的数据。

以下是一个简单的流程图,展示了本地数据存储的操作流程:

graph TD;
    A[输入键值对] --> B[点击Add按钮];
    B --> C[调用setItem方法];
    C --> D[存储数据到AsyncStorage];
    D --> E[更新列表数据];
    F[点击Clear按钮] --> G[调用clearItems方法];
    G --> H[清空AsyncStorage数据];
    H --> E;

通过上述内容,我们了解了 React Native 中图像显示控制和离线处理的相关技术。图像显示控制可以提升应用的视觉效果,而离线处理则能让应用在网络不稳定的情况下依然正常运行,为用户提供更好的体验。

React Native 中的图像显示控制与离线处理

数据同步

前面我们已经学习了如何检测网络连接状态以及如何在 React Native 应用中本地存储数据。现在,我们将结合这两个概念,实现一个能够检测网络中断并继续运行的应用。基本思路是仅在确定设备在线时进行网络请求。如果设备离线,我们可以将状态的任何更改本地存储起来。当设备重新联网时,我们可以将这些存储的更改与远程 API 进行同步。

实现数据同步模块

首先,我们需要实现一个抽象模块,该模块位于 React 组件和存储数据的网络调用之间。以下是 store.js 模块的代码:

import {
  NetInfo,
  AsyncStorage,
} from 'react-native';
import { Map as ImmutableMap } from 'immutable';

// 模拟数据,实际应用中应来自真实的网络 API 端点
const fakeNetworkData = {
  first: false,
  second: false,
  third: false,
};
// 默认假设设备未连接网络
let connected = false;
// 待同步的数据列表
const unsynced = [];

// 设置给定的键值对,应用使用此函数时无需关心网络是否连接
export const set = (key, value) =>
  // 返回一个 Promise,根据网络连接状态解析为布尔值
  new Promise((resolve, reject) => {
    if (connected) {
      // 在线状态,进行网络请求(此处为模拟)并解析 Promise
      fakeNetworkData[key] = value;
      resolve(true);
    } else {
      // 离线状态,使用 AsyncStorage 保存数据,并将键添加到待同步列表
      AsyncStorage
        .setItem(key, value.toString())
        .then(
          () => {
            unsynced.push(key);
            resolve(false);
          },
          err => reject(err)
        );
    }
  });

// 获取给定的键值对,应用无需关心网络连接状态
export const get = key =>
  new Promise((resolve, reject) => {
    if (connected) {
      // 在线状态,从网络获取数据
      resolve(
        key ?
          fakeNetworkData[key] :
          fakeNetworkData
      );
    } else if (key) {
      // 离线状态且请求特定键的值,从本地存储查找
      AsyncStorage
        .getItem(key)
        .then(
          item => resolve(item),
          err => reject(err)
        );
    } else {
      // 离线状态且请求所有值,获取所有键和值并解析为普通 JS 对象
      AsyncStorage
        .getAllKeys()
        .then(
          keys => AsyncStorage
            .multiGet(keys)
            .then(
              items => resolve(ImmutableMap(items).toJS()),
              err => reject(err)
            ),
          err => reject(err)
        );
    }
  });

// 模块加载时检查网络状态,设置 connected 状态
NetInfo.isConnected
  .fetch()
  .then(
    (isConnected) => { connected = isConnected; },
    () => { connected = false; }
  );

// 注册网络状态变化的监听器
NetInfo.addEventListener(
  'change',
  (info) => {
    // 更新 connected 状态
    connected = [
      'wifi',
      'unknown',
    ].includes(info.toLowerCase());
    // 在线且有待同步数据时,从存储加载数据并调用 set 方法进行同步
    if (connected && unsynced.length) {
      AsyncStorage
        .multiGet(unsynced)
        .then((items) => {
          items.forEach(([key, val]) => set(key, val));
          unsynced.length = 0;
        });
    }
  }
);

该模块导出了 set get 两个函数,分别用于设置和获取数据。 set 函数会根据网络连接状态决定是进行网络请求还是使用 AsyncStorage 本地存储数据。 get 函数同样会根据网络状态从网络或本地存储获取数据。此外,该模块还会在模块加载时检查网络状态,并注册网络状态变化的监听器,以便在网络恢复时同步本地存储的数据。

使用数据同步模块的主应用

以下是使用上述 set get 函数的主应用代码:

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  View,
  Switch,
  NetInfo,
} from 'react-native';
import { fromJS } from 'immutable';
import styles from './styles';
import { set, get } from './store';

// 用于将布尔值和其字符串表示形式转换为一致的布尔值
const boolMap = {
  true: true,
  false: false,
};

class SynchronizingData extends Component {
  // 组件状态,包含消息提示和三个开关状态
  state = {
    data: fromJS({
      message: null,
      first: false,
      second: false,
      third: false,
    }),
  }

  // 获取 Immutable.js 状态数据
  get data() {
    return this.state.data;
  }

  // 设置 Immutable.js 状态数据
  set data(data) {
    this.setState({ data });
  }

  // 生成绑定到给定键的保存处理函数
  save = key => (value) => {
    // 调用 set 函数,并根据解析结果设置用户消息
    set(key, value)
      .then(
        (connected) => {
          this.data = this.data
            .set(
              'message',
              connected ? null : 'Saved Offline'
            )
            .set(key, value);
        },
        (err) => {
          this.data = this.data.set('message', err);
        }
      );
  }

  // 组件挂载前获取初始数据
  componentWillMount() {
    // 先调用 NetInfo.fetch() 确保连接状态准确,再获取初始状态
    NetInfo.fetch().then(() =>
      get()
        .then(
          (items) => {
            this.data = this.data.merge(items);
          },
          (err) => {
            this.data = this.data.set('message', err);
          }
        )
    );
  }

  render() {
    // 获取保存方法
    const { save } = this;
    // 获取组件状态
    const {
      message,
      first,
      second,
      third,
    } = this.data.toJS();

    return (
      <View style={styles.container}>
        <Text>{message}</Text>
        <View>
          <Text>First</Text>
          <Switch
            value={boolMap[first.toString()]}
            onValueChange={save('first')}
          />
        </View>
        <View>
          <Text>Second</Text>
          <Switch
            value={boolMap[second.toString()]}
            onValueChange={save('second')}
          />
        </View>
        <View>
          <Text>Third</Text>
          <Switch
            value={boolMap[third.toString()]}
            onValueChange={save('third')}
          />
        </View>
      </View>
    );
  }
}

AppRegistry.registerComponent(
  'SynchronizingData',
  () => SynchronizingData
);

在这个应用中,用户可以通过三个开关来改变状态。当用户更改开关状态时, save 函数会调用 set 函数来保存数据。如果设备离线,会显示 Saved Offline 消息。组件挂载前会先检查网络状态,然后获取初始数据。

以下是数据同步的流程图:

graph TD;
    A[用户更改开关状态] --> B[调用 save 函数];
    B --> C[调用 set 函数];
    C --> D{是否在线};
    D -- 是 --> E[网络请求更新数据];
    D -- 否 --> F[本地存储数据并添加到待同步列表];
    G[网络状态变化] --> H{是否在线};
    H -- 是 --> I{是否有待同步数据};
    I -- 是 --> J[从本地存储加载数据并同步到网络];
    K[组件挂载] --> L[检查网络状态];
    L --> M[获取初始数据];

总结

通过上述内容,我们全面了解了 React Native 中图像显示控制和离线处理的相关技术。在图像显示方面,我们学习了如何调整图像大小、实现图像的懒加载以及在组件中渲染图标,这些技术可以提升应用的视觉效果和用户体验。在离线处理方面,我们掌握了网络状态检测、本地数据存储和数据同步的方法,使得应用在网络不稳定的情况下依然能够正常运行,为用户提供持续稳定的服务。这些技术的综合应用能够帮助开发者构建更加健壮、可靠的 React Native 应用。

内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件PLC的专业的本科生、初级通信联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境MCGS组态平台进行程序高校毕业设计或调试运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑互锁机制,关注I/O分配硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值