2020-12-02

解决方法有很多乐于分享的很少

前言:公司要求在已完成的项目中禁用跟随系统字体大小变化 自己的项目中增加一键改变字体的大小(类似系统设置、微信) 看上去是不是觉得多此一举


结果图.gif

一.网上找到有人提问怎么做,没见有人给出详细解决方案
我来贴下 我的做法 下面2方法可以写在入口文件index.js 也可以放在全局文件中:

A.禁用跟随系统变换字体大小

TextInput.defaultProps =Object.assign({},TextInput.defaultProps, {
  defaultProps: false,
  allowFontScaling: false,
});
Text.defaultProps = Object.assign({}, Text.defaultProps, {
  allowFontScaling: false,
});

B. 使用到的改变全局项目字体大小的方法:

DeviceEventEmitter.addListener('changeFont', num => {
//传进来字体放大倍数
if (!num) {
    return;
  }
  Text.render = _.wrap(Text.render, function(func, ...args) {
    let originText = func.apply(this, args);
    let textStyle = originText.props && originText.props.style;
    let current_style = args[0].style;
    let getFontSize;
    if (current_style == null) {
      //如果为空 提供一个默认字体大小 pxToDp 只是我这边像素转换方法页可以直接写14
      getFontSize = pxToDp(14);
    } else if (
      current_style &&
      !current_style.fontSize &&
      current_style.length > 0
    ) {
      let pop_style;
      //倒序取值 因为有些组件有重新定义style 之后会成一个style数组 后一个style会覆盖前一个
      for (let index = current_style.length; index > 0; index--) {
        let nullDict = current_style[index];
        if (!!nullDict) {
          pop_style = nullDict;
          break;
        }
      }
      //有些sytle中会报NAN数值问题导致崩溃 有可能是在Text的style中没有添加fontSize问题 这边同意处理
      if (isNaN(pop_style.fontSize) == false) {
        getFontSize = pop_style.fontSize;
      } else {
        getFontSize = pxToDp(14);
      }
    } else {
      getFontSize =
        current_style && current_style.fontSize
          ? current_style.fontSize
          : pxToDp(14);
    }
    let orignStylefs = {fontSize: getFontSize * num};
    return React.cloneElement(originText, {
      style: [textStyle, orignStylefs] });
  });
});

二. 直接贴代码 在代码中标注
\color{red}{注意: 下列代码中已删除了界面布局,只保留滑动跟变换字体大小相关方法}

import React, {Component} from 'react';
import {
  View,
  Text,
  PanResponder,
  DeviceEventEmitter,
  Animated,
} from 'react-native';
import _ from 'lodash';


const lineWidth = deviceDpWidth - pxToDp(100);
const leftMar = pxToDp(18);
export default class AAAAAA extends Component {
  constructor(props) {
    super(props);
    this.state = {
      tramsformX: new Animated.ValueXY({x: -pxToDp(10), y: 0}), //滚动按钮初始位置
      currIndex: 0, //当前在第几个字号上0:标准 1:中: 2:大
      firstPosition: 0, //用来判断左右滑动方向
    };
  }

  componentWillMount() {
    this.watcher = PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onPanResponderGrant: this._handlePanResponderGrant,
      onPanResponderMove: this._handlePanResponderMove,
      onPanResponderRelease: this._handlePanResponderEnd,
      onPanResponderTerminate: this._handlePanResponderTerminate,
    });
  }

  _handlePanResponderGrant(evt, gestureState) {
    this.firstPosition = gestureState.x0;
    this.sTime = true; //防止多次拖拽
  }
  _handlePanResponderEnd() {}
  _handlePanResponderTerminate() {}
  componentWillUnmount() {
    this.rightSize.remove();
    this.leftSize.remove();
  }

  componentDidMount() {
    //通知执行左右滑动 动画
    this.rightSize = DeviceEventEmitter.addListener('rightSize', () => {
      let idx = this.state.currIndex === 2 ? 2 : this.state.currIndex + 1;
      this._startAnimatedRight(idx);
      this.setState({
        currIndex: idx,
      });
    });
    this.leftSize = DeviceEventEmitter.addListener('leftSize', () => {
      let idx = this.state.currIndex === 0 ? 0 : this.state.currIndex - 1;
      this._startAnimatedLeft(idx);
      this.setState({
        currIndex: idx,
      });
    });
    //进入界面 滚动到之前保存选中的 字体大小等级
    DataStorage.get(StorageText.SETFONTSIZE).then(data => {
      if (data) {
        this.setState({
          currIndex: data,
        });
        this._startAnimatedRight(data);
      }
    });
  }

//右滑
  _startAnimatedRight(index) {
    Animated.spring(this.state.tramsformX, {
      toValue: {x: (lineWidth * index) / 2 - leftMar, y: 0}, //目标值
      velocity: 2, //附着在弹簧上物体的初始速度。默认值0(对象处于静止状态)。
      tension: 40, //控制速度。默认值40。可不写
      friction: 7, //控制“弹性”/过冲。默认值7。可不写
    }).start();
    setTimeout(() => {
      this.sTime = true; //防止多次拖拽
    }, 1000);
    this._tongzhi(index === 2 ? 2 : index);
  }

//左滑
  _startAnimatedLeft(index) {
    Animated.spring(this.state.tramsformX, {
      toValue: {x: (lineWidth * index) / 2 - leftMar, y: 0}, //目标值
      velocity: 2, //附着在弹簧上物体的初始速度。默认值0(对象处于静止状态)。
      tension: 40, //控制速度。默认值40。 可不写
      friction: 7, //控制“弹性”/过冲。默认值7。可不写
    }).start();
    setTimeout(() => {
      this.sTime = true; //防止多次拖拽
    }, 1000);
    this._tongzhi(index === 0 ? 0 : index);
  }

//重置字体大小
  _tongzhi(index) {
    this.changeFont = DeviceEventEmitter.emit(
      'changeFont',
      this.returnSize(index),
    );
  }

//判断左右滑动
  _handlePanResponderMove(evt, gestureState) {
    if (gestureState.moveX < this.firstPosition) {
      if (this.sTime == true) {
        this.sTime = false;
        DeviceEventEmitter.emit('leftSize');
      }
    } else if (gestureState.moveX > this.firstPosition) {
      if (this.sTime == true) {
        this.sTime = false;
        DeviceEventEmitter.emit('rightSize');
      }
    } else {
    }
  }

  //传入current 字体等级 获取缩放比例
  returnSize(current) {
    if (current == 0) {
      return 1; //标准正常字号
    } else if (current == 1) {
      return 放大; // eg:1.35
    } else {
      return 要多大;  //eg:1.5
    }
  }
  popView() {
//返回缓存选中的字号 重新进入app时 使用
    DataStorage.save(StorageText.SETFONTSIZE, this.state.currIndex);
    Actions.jump('Mine');
  }
  render() {
    return (
      <View style={{flex: 1, backgroundColor: 'white'}}>
          <Animated.Image
            source={require('../images/mine/btn.png')}
            activeOpacity={1}
            style={{
              height: pxToDp(40),
              width: pxToDp(40),
              marginTop: -pxToDp(23),
              transform: [
                //左右滑动
                {translateX: this.state.tramsformX.x},
                {translateY: this.state.tramsformX.y},
              ],
            }}
            {...this.watcher.panHandlers} //绑定手势
          />
        </View>
      </View>
    );
  }
}

\color{red}{注意: 在设置Text的Style中不要有下列方式不然会奔溃报错}

<Text style={[styles.xxxxx]}>123456</Text>

\color{red}{如果style确实要重新赋值要加上大括号并添加样式值要不然删除中括号}

要不这样
<Text style={[styles.xxxxx],{color:"red"}}>123456</Text>
要不然这样 两者选其一
<Text style={styles.xxxxx}>123456</Text>

问题: 各位还有哪些可行的 在已完成项目上实现一键改变项目字体大小的方式,请告诉我!有相关资料最好

希望对你有帮助!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. CSS 先导 (1) 历史 CSS was first proposed by Håkon Wium Lie...
    HikariXyc阅读 231评论 0 0
  • 【鼎典美育周三例会】2020.12.02 ️ 时间:周三上午8:30—12:00 ️地点:鼎典云兜兜岭杰校区艺术生...
    鼎典美育卷卷老师阅读 376评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,725评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    余生动听阅读 10,725评论 0 11
  • 可爱进取,孤独成精。努力飞翔,天堂翱翔。战争美好,孤独进取。胆大飞翔,成就辉煌。努力进取,遥望,和谐家园。可爱游走...
    赵原野阅读 3,355评论 1 1

友情链接更多精彩内容