React Native 开发APP_一个程序媛。的博客-程序员秘密_"toast ref=\"toast\" position='center' duration='2

技术标签: react native  

记录一下项目中主要用到的技术点吧~

一.电子签名的显示,文件存储到手机,上传

电子签名用到的组件:react-native-signature-capture

写文件react-native-fs

上传用到的组件react-native-fetch-blob


import React, { Component, Fragment } from "react";
import { StyleSheet, View, TextInput, Text,TouchableOpacity, Image, FlatList, Dimensions,
} from "react-native";
import { common_url, fetchRequest } from "../../utils/request";
import Dialog, { DialogButton, DialogContent, DialogFooter, DialogTitle } from "react-native-popup-dialog";
import SignatureCapture from "react-native-signature-capture";
import RNFetchBlob from "react-native-fetch-blob";
var RNFS = require('react-native-fs');
export default class SignConstract extends Component {
  constructor(props) {
    super(props);
    this.state = {
      visible:false,
      contract:"",
      signImg:"",
    };
  }

 
  //签名
  _onSaveEvent(result) {
    if(result.encoded!=undefined){
      this.setState({
        signImg:result.encoded,  //result.encoded base64编码,用于签名图片的显示
      })
    }

     
    var timestamp = (new Date()).getTime();
    const path = RNFS.PicturesDirectoryPath + '/'+timestamp+'signature.png';
      // write the file
      RNFS.writeFile(path, result.encoded, 'base64')
        .then((success) => {
          console.log('存储在手机的文件路径path', path);
        })
        .catch((err) => {
          console.log(err.message);
        });


    //转化后的本地路径
    this.upload(result.pathName)
  }
 //上传文件
  upload(pathName){
    DeviceStorage.get("ownerId").then((ownerId) => {
      var declareId ="1";
      let body = [{
        name: "declareId", data:declareId
      },
        {
          name: "sign",
          filename: "测试",
          type: "image/png",
          data: RNFetchBlob.wrap(pathName)
        }];
  
      RNFetchBlob.fetch("POST", common_url+"hserp_owners/participateSing", {
        // 上传图片要设置Header
        "Content-Type":"multipart/form-data",
      }, body)
        .uploadProgress((written, total) => {
          // 本地查找进度
        })
        .progress((received, total) => {
          let perent = received / total;
          console.log("上传进度打印", perent);
        })
        .then((response) => response.json())
        .then((response) => {
          console.log("上传信息返回", response);
        })
        .catch((error) => {
          // 错误信息
          console.log(error);
        });


    });
  }
  //保存签名
  saveSign() {
    this.refs["sign"].saveImage();
  }
  //清除签名
  resetSign() {
    this.refs["sign"].resetImage();
  }

  render() {
    return (
      <View style={styles.container}>
          <View style={
   { flex: 1 }}>
            <View style={styles.content}>
              <View style={styles.rowBorder}>
              <TouchableOpacity style={styles.rowContent} onPress={() => {
                this.setState({
                  visible: true
                });
              }}>
                <Text style={
   {color:theme.color}}>签名:</Text>
                <Image source={
   { uri: "data:image/jpg;base64," + this.state.signImg }} style={styles.img}/>
              </TouchableOpacity>
            </View>

          </View>
          {/*确认*/}
          <Dialog
            width={0.9}
            height={0.7}
            visible={this.state.visible}
            footer={
              <DialogFooter>
                <DialogButton
                  text="取消"
                  onPress={() => {
                    this.setState({
                      visible: false
                    });
                  }}
                />
                <DialogButton
                  text="确定"
                  onPress={() => {
                    this.setState({
                      visible: false
                    }, () => {
                      this.saveSign();
                    });
                  }}
                />
              </DialogFooter>
            }
            dialogTitle={<DialogTitle title="签名确认"/>}>
            <DialogContent style={
   { flex: 1 }}>
              <View style={
   { flex: 1 }}>
                <SignatureCapture
                  ref="sign"
                  style={
   { flex: 1 }}
                  minStrokeWidth={5}
                  maxStrokeWidth={5}
                  showNativeButtons={false}
                  saveImageFileInExtStorage={true}  //是否存储在手机
                  onSaveEvent={this._onSaveEvent.bind(this)}
                />
              </View>
            </DialogContent>
          </Dialog>
        <View style={styles.btn}>
          <Text style={styles.white}
                onPress={() => {
                  if(!this.state.signImg){
                    this.refs.toast.show("请签名", 4000);
                    return false

                  }else{
                    Actions.Renovation({sign:this.state.path})
                  }

                }}>下一步</Text>
        </View>
      </View>

    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: theme.gray
  },
});

 

二. 图片压缩 

用到的组件:react-native-image-resizer,上传前自己用promise做了个处理压缩多图

import React, { Component } from "react";
import {StyleSheet, View, ScrollView, TextInput, Text, TouchableOpacity, Image, FlatList, Dimensions, DeviceEventEmitter, ImageBackground} from "react-native";
import { common_url, fetchRequest } from "../../utils/request";
import RNFetchBlob from "react-native-fetch-blob";
import ImageResizer from 'react-native-image-resizer';
export default class RepaireApply extends Component {
  constructor(props) {
    super(props);
    this.state = {
      imgArr: [],
      typeArr: [],
      date: "",
      total: "",
      imgId: ""
    };
  }

  componentWillMount() {
    this.getList();
    this.deEmitter = DeviceEventEmitter.addListener("left", (a) => {
      this.setState({
        imgArr: a
      });
    });
  }

  componentWillUnmount() {
    this.deEmitter.remove();
  }

  async save() {
      DeviceStorage.get("ownerId").then(async(ownerId) => {
        let arr = [];
        this.state.imgArr.map((item, index) => {
          arr.push(ImageResizer.createResizedImage(item, 100, 100, "PNG", 100 ))
        })

        let arr2 = [];
        let result=await Promise.all(arr)
        result.map((item, index) => {
          var obj = {
            name: "picture" + index,
            filename: "picture" + item.name,
            type: "image/png",
            data: RNFetchBlob.wrap(item.uri)
          };
          arr2.push(obj);
        });

        arr2.push({
          name: "request", data: this.state.requests
        }, {
          name: "size", data: this.state.imgArr.length + ""
        });
        RNFetchBlob.fetch("POST", common_url + "hserp_owners/repairMaintenance", {
          "Content-Type": "multipart/form-data"
        }, arr2)
          .uploadProgress((written, total) => {
         
          })
          .progress((received, total) => {
           
          })
          .then((response) => response.json())
          .then((response) => {
            
          })
          .catch((error) => {
            // 错误信息
            console.log(error);
          });
      });
  }

 

三. 手势系统运用:动态改变scrollview 的滑动方向

import React, { Component } from "react";
import { StyleSheet,  View,Text, TouchableOpacity,ScrollView, PanResponder} from "react-native";
import { fetchRequest } from "../../utils/request";
var Dimensions = require("Dimensions");
export default class ParkSpace extends Component {
  constructor(props) {
    super(props);
    this.state = {
      horizontal:false
    };
  }

  componentWillMount() {
    
    this._panResponder = PanResponder.create({

      // 要求成为响应者
      // nativeEvent
      // gestureState  dx - 从触摸操作开始时的累计横向路程    dy - 从触摸操作开始时的累计纵向路程


      //表示是否成为滑动事件的劫持者,如果返回是,则不会把滑动事件传递给它的子元素。
      onStartShouldSetPanResponder: (evt, gestureState) => false,

      //表示是否成为事件的劫持者,如果返回是,则不会把事件传递给它的子元素
      onStartShouldSetPanResponderCapture: (evt, gestureState) => false,


      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
      onStartShouldSetResponderCapture: (evt)=> true,
      VonMoveShouldSetResponderCapture: (evt)=> true,

      //开始手势操作
      onPanResponderGrant: (evt, gestureState) => {
        // this._highlight();
        this.setState({
          horizontal:true
        })
      },


      //触摸点移动
      onPanResponderMove: (evt, gestureState) => {
        this.state.ScreenWidth,gestureState.moveX,)
        console.log(`gestureState.moveX  : ${gestureState.moveX }   gestureState.moveY  : ${gestureState.moveY }`);
        if(gestureState.moveX<this.state.ScreenWidth){
         //动态改变
          this.setState({
            horizontal:true
          })
        }else{
          this.setState({
            horizontal:false
          })
        }
      },
      //用户放开了所有的触摸点,且此时视图已经成为了响应者
      onPanResponderRelease: (evt, gestureState) => {
      },
      //另一个组件已经成为了新的响应者,所以当前手势将被取消
      onPanResponderTerminate: (evt, gestureState) => {
      },
    });
  }

  show(typeId,carType, price,number) {
    Actions.CartFee({"typeId":typeId,"carType": carType, "carPrice": price,"number":number,area:this.state.area });
  }

  render() {
    return (
      <View style={
   {display:"flex",height:"100%"}}>

        <ScrollView style={
   {flex:1}}
                    horizontal={this.state.horizontal} //水平
                    showsHorizontalScrollIndicator={true}
                    showsVerticalScrollIndicator={true}
                    removeClippedSubviews={false}
                    overScrollMode="always">

          <View  style={
   {width:this.state.parkWidth,height:this.state.parkHeight,backgroundColor: "#00ff00"}}
                 {...this._panResponder.panHandlers}>
            {this.state.cars.map((item) => {
              return (
                <TouchableOpacity style={
   { position: "absolute", left: (item.abscissa_y - 1) * this.state.cellWidth, top: (item.abscissa_x - 1) * this.state.cellHeight }}
                                  key={item.id}
                                  onPress={() => {
                                    if (item.state != "3") {
                                      this.refs.toast.show("该车位已租售,请重新选择", 4000
                                      return false;
                                    } else {
                                      this.show(item.type_id[0],item.type_id[1], item.price,item.parking_number);
                                    }
                                  }}
                >
                  <View style={
   { width:60,
                    height:30,
                    backgroundColor: "#848484",
                    borderColor: "#fff",
                    borderBottomWidth:2,
                    borderTopWidth:2,
                    borderLeftWidth:2,
                    transform: [{ rotate: item.angle+"deg"}]
                  }}>
                    <Text style={styles.zhu}>▎</Text>
                    <Text style={styles.zhu}>▎</Text>
                    <Text style={
   {position:"absolute", top:"30%", left:"30%", color:"white", fontSize:8,transform: [{ rotate: item.angle+"deg"}]}}>{item.parking_number}</Text>
                    <Text style={styles.tang}>▲</Text>

                  </View>
                </TouchableOpacity>
              );
            })}
          </View>
        </ScrollView>
        <Toast
          ref="toast"
          style={
   { backgroundColor:theme.toastColor}}
          position='center'
          fadeInDuration={theme.fadeInDuration}
          fadeOutDuration={theme.fadeOutDuration}
          opacity={0.7}
          textStyle={
   { color: "white" }}
        />
      </View>
    );
  }
}
const styles = StyleSheet.create({
});

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Rqlinna/article/details/105960196

智能推荐

Loading PDSC Debug Description failed for STMicroelectronics STM32F103ZF Disabling usage of PDSC Deb_cherry_lichao的博客-程序员秘密_loading pdsc debug description failed for stmicroe

用 STM32F103 软件仿真 ,还需要下载安装 STM32F103 pack 文件,如果在 MDK 中下载较慢,也可以点击此处下载,下载后双击安装即可。当Keil新建或者打开工程出现“Loading PDSC Debug Description failed for STMicroelectronics STM32F103ZF Disabling usage of PDSC De...

自制电吉他效果器 DIY PCB(一)前言_XieKKK-的博客-程序员秘密

接下来几篇文章将会教你如何用pcb技术自制电吉他效果器。

浏览器和服务器实现跨域(CORS)判定的原理_零度anngle的博客-程序员秘密

前端对Cross-Origin Resource Sharing 问题(CORS,中文又称'跨域')应该很熟悉了。众所周知出于安全的考虑,浏览器有个同源策略,对于不同源的站点之间的相互请求会做限制(跨域限制是浏览器行为,不是服务器行为。)。不过下午想到了一个略无趣的问题:浏览器和服务器到底是如何判定有没有跨域呢?本文主要分两个部分,一是对这个问题的总结,二是nginx下如何配置服务器允许跨域。

使用辅助信息进行张量分解_qq_37637914的博客-程序员秘密

Tensor Factorization Using Auxiliary Information摘要介绍2 辅助信息张量补全问题2.1使用低秩分解的张量分析摘要现有的大多数张量(或多路阵列)分析方法仅假设要完成的张量等级较低。 但是,例如,当将它们应用于张量完成问题时,如果仅观察到有限的条目,则它们的预测精度往往会大大变差。 在本文中,除了低秩假设之外,我们还建议使用数据之间的关系作为辅助信息,以提高张量分解的质量。 我们介绍了两种使用从关系式导出的图拉普拉斯算子的正则化方法,并为近似解设计了迭代算法。

Word排版——毕业论文专业排版3——编号+多级列表_不懂音乐的欣赏者的博客-程序员秘密_毕业论文多级列表

文章目录概要自动编号调整列表级别调整缩进编号缩进调整标题文字缩进其他文本的编号概要  编号和多级列表的结合,可以使得文档可以自动对需要的内容进行编号。自动编号的好处如下:调整列表的缩进,可以修改整个列表的格式列表中间插入新内容后,自动便后,后续列表自动更新编号,如下图所示。插入新列表后,后面的序号自动更新。自动编号  下面将继续上一节内容继续讲解如何使用多级列表给各章节...

十年磨一剑,两万字长文深剖析分享IC验证经验_Hack电子的博客-程序员秘密

有人认为我验证做得很牛,也有人认为我的验证早就丢下了;有人认为我发现了各个项目的不少问题,也有人认为我在CMM库的几百个问题单大部分属纯净水。好吧,无论怎样,我还是把我在验证中如何发现和定...

随便推点

吐血整理:机器学习的30个基本概念,都在这里了(手绘图解)_hzbooks的博客-程序员秘密

导读:本文主要介绍机器学习基础知识,包括名词解释(约30个)、基础模型的算法原理及具体的建模过程。作者:梅子行、毛鑫宇来源:大数据DT(ID:hzdashuju)01空间表征在学习深奥...

android 自定义推送布局_Notification的基本用法以及使用RemoteView实现自定义布局_Great Leon的博客-程序员秘密

Notification的作用Notification是一种全局效果的通知,在系统的通知栏中显示。既然作为通知,其基本作用有:显示接收到短消息、即时信息等显示客户端的推送(广告、优惠、新闻等)显示正在进行的事物(后台运行的程序,如音乐播放进度、下载进度)Notification的基本操作:Notification的基本操作主要有创建、更新和取消三种。一个Notification的必要属性有三项,如...

java二维数组转稀疏数组IO流存盘并写出到控制台后恢复为二维数组_莫说海无岸的博客-程序员秘密_io写出二维数组

一个类中声明两个方法方法1.将二维数组存入txt文件中方法2.读取txt文件并写出到新的二维数组中package sparseArray;import java.io.*;import java.util.ArrayList;import java.util.List;public class readwrite { /**\ * 将二维数组存入txt文件中 * @param array */ public static void save

GetLastError_jidongdong66的博客-程序员秘密

GetLastError<br />参考资料 1<br />《Windows核心编程》(第五版) 

BM25 文本相似度算法_Little Coder的博客-程序员秘密_bm25相似度

BM25, 下一代的TF-IDF新版的lucence不再把TF-IDF作为默认的相关性算法,而是采用了BM25(BM是Best Matching的意思)。BM25是基于TF-IDF并做了改进的算法。BM25算法,通常用来作搜索相关性评分。一句话概况其主要思想:对Query进行语素解析,生成语素qi;然后,对于每个搜索结果D,计算每个语素qi与D的相关性得分,最后,将qi相对于D的相关性得分进...

超实用的Chrome插件,没有之一!_普通网友的博客-程序员秘密

今天是给大家推荐插件和软件的一天,个人觉得都是很实用的哦,尤其是最后一个,相信大家也是比较熟悉的了,需要的小伙伴赶快安排起来吧!一、OSD noteOSD note是一款基于神奇编程语言 ...

推荐文章

热门文章

相关标签