├── README.md
└── ScreenUtil.js
/README.md:
--------------------------------------------------------------------------------
1 | # ReactNativeScreenUtil
2 | ReactNative屏幕工具适配类
3 | 直接导入引用即可.
4 | 新增iPhoneX适配, 让你不用升级ReactNative即可适配iPhoneX.
5 | 此设计类以iPhone6为基准,可自行修改.
6 | 如果各位有更好的适配或者其他适合作为工具的方法,欢迎提issue分享给大家。
7 |
8 | 个人也已经添加了一些其他常用方法,比如判断字符串(对象,数组)是否为空,时间戳转换 , AsyncStorage 的增删改查等, 觉得有的方法用不上可以手动删除,在此只做整理,方便日后使用
9 |
10 | 相关链接:
11 |
12 | 适配iPhoneX的效果及相关方法: http://blog.csdn.net/u011272795/article/details/78592605
13 |
14 | 屏幕适配工具类使用方法: http://blog.csdn.net/u011272795/article/details/73824558
15 |
16 | #### 2018/8/15更新:
17 | 字体适配添加了是否根据手机文字缩放系数来缩放字体,避免在每个text都写相应的设置方法,详情请查看setSptext方法
18 |
19 | #### 2018/8/15更新:
20 | 优化了适配方法setSptext和scaleSize,
21 | 添加了scaleHeight方法,根据不同手机的高度不同来进行适配,使尺寸更加合适
22 |
23 | #### 2018/7/12更新:
24 | 调整了适配方法setSptext和scaleSize,
25 | 最新的屏幕适配方法在android上的效果非常好,iOS未测试,如果iOS上效果不好,请使用最初的版本。
26 | 添加了判断目标是否为空的方法,详情请查阅工具中的isEmpty方法.
27 |
--------------------------------------------------------------------------------
/ScreenUtil.js:
--------------------------------------------------------------------------------
1 | /**
2 | * zhuoyuan93@gmail.com
3 | * 屏幕工具类 以及一些常用的工具类封装
4 | * ui设计基准,iphone 6 2倍图
5 | * width:750px
6 | * height:1334px
7 | * @2x
8 | */
9 | import {
10 | PixelRatio,
11 | Dimensions,
12 | Platform,
13 | AsyncStorage
14 | } from 'react-native';
15 |
16 | export let screenW = Dimensions.get('window').width;
17 | export let screenH = Dimensions.get('window').height;
18 | const fontScale = PixelRatio.getFontScale();
19 | export let pixelRatio = PixelRatio.get();
20 | //像素密度
21 | export const DEFAULT_DENSITY = 2;
22 | //px转换成dp
23 | //以iphone6为基准,如果以其他尺寸为基准的话,请修改下面的defaultWidth和defaultHeight为对应尺寸即可. 以下为1倍图时
24 | const defaultWidth = 375;
25 | const defaultHeight = 667;
26 | const w2 = defaultWidth / DEFAULT_DENSITY;
27 | //px转换成dp
28 | const h2 = defaultHeight / DEFAULT_DENSITY;
29 |
30 | //缩放比例
31 | const _scaleWidth = screenW / defaultWidth;
32 | const _scaleHeight = screenH / defaultHeight;
33 |
34 | // iPhoneX
35 | const X_WIDTH = 375;
36 | const X_HEIGHT = 812;
37 |
38 | /**
39 | * 屏幕适配,缩放size , 默认根据宽度适配,纵向也可以使用此方法
40 | * 横向的尺寸直接使用此方法
41 | * 如:width ,paddingHorizontal ,paddingLeft ,paddingRight ,marginHorizontal ,marginLeft ,marginRight
42 | * @param size 设计图的尺寸
43 | * @returns {number}
44 | */
45 | export function scaleSize(size: Number) {
46 | return size * _scaleWidth;
47 | }
48 |
49 | /**
50 | * 屏幕适配 , 纵向的尺寸使用此方法应该会更趋近于设计稿
51 | * 如:height ,paddingVertical ,paddingTop ,paddingBottom ,marginVertical ,marginTop ,marginBottom
52 | * @param size 设计图的尺寸
53 | * @returns {number}
54 | */
55 | export function scaleHeight(size: Number) {
56 | return size * _scaleHeight;
57 | }
58 |
59 | /* 最初版本尺寸适配方案 也许你会更喜欢这个
60 | export function scaleSize(size: Number) {
61 | let scaleWidth = screenW / w2;
62 | let scaleHeight = screenH / h2;
63 | let scale = Math.min(scaleWidth, scaleHeight);
64 | size = Math.round((size * scale + 0.5));
65 | return size / DEFAULT_DENSITY;
66 | }*/
67 |
68 | /**
69 | * 设置字体的size(单位px)
70 | * @param size 传入设计稿上的px , allowFontScaling 是否根据设备文字缩放比例调整,默认不会
71 | * @returns {Number} 返回实际sp
72 | */
73 | function setSpText(size: Number, allowFontScaling = false) {
74 | const scale = Math.min(_scaleWidth, _scaleHeight);
75 | const fontSize = allowFontScaling ? 1 : fontScale;
76 | return size * scale / fontSize;
77 | }
78 |
79 | export function setSpText2(size: Number) {
80 | let scaleWidth = screenW / w2;
81 | let scaleHeight = screenH / h2;
82 | let scale = Math.min(scaleWidth, scaleHeight);
83 | size = Math.round((size * scale + 0.5));
84 |
85 | return size / DEFAULT_DENSITY * fontScale;
86 | }
87 |
88 | /**
89 | * 判断是否为iphoneX
90 | * @returns {boolean}
91 | */
92 | export function isIphoneX() {
93 | return (
94 | Platform.OS === 'ios' &&
95 | ((screenH === X_HEIGHT && screenW === X_WIDTH) ||
96 | (screenH === X_WIDTH && screenW === X_HEIGHT))
97 | )
98 | }
99 |
100 | /**
101 | * 根据是否是iPhoneX返回不同的样式
102 | * @param iphoneXStyle
103 | * @param iosStyle
104 | * @param androidStyle
105 | * @returns {*}
106 | */
107 | export function ifIphoneX(iphoneXStyle, iosStyle = {}, androidStyle) {
108 | if (isIphoneX()) {
109 | return iphoneXStyle;
110 | } else if (Platform.OS === 'ios') {
111 | return iosStyle
112 | } else {
113 | if (androidStyle) return androidStyle;
114 | return iosStyle
115 | }
116 | }
117 |
118 |
119 | /**
120 | * 判断对象,数组,字符串是否为空
121 | * @param str (null|undefined|''|' '|[]|{}) 均判断为空,返回true
122 | * @returns {boolean}
123 | */
124 | export function isEmpty(str) {
125 | if (!str) {
126 | return true;
127 | } else if (typeof str === 'object' && Object.keys(str).length === 0) {
128 | return true;
129 | } else if (str.replace(/(^\s*)|(\s*$)/g, "").length === 0) {
130 | return true;
131 | }
132 | return false;
133 | }
134 |
135 | //时间处理
136 | Date.prototype.format = function (format) {
137 | let date = {
138 | "M+": this.getMonth() + 1,
139 | "d+": this.getDate(),
140 | "h+": this.getHours(),
141 | "m+": this.getMinutes(),
142 | "s+": this.getSeconds(),
143 | "q+": Math.floor((this.getMonth() + 3) / 3),
144 | "S+": this.getMilliseconds()
145 | };
146 | if (/(y+)/i.test(format)) {
147 | format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
148 | }
149 | for (let k in date) {
150 | if (new RegExp("(" + k + ")").test(format)) {
151 | format = format.replace(RegExp.$1, RegExp.$1.length === 1
152 | ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
153 | }
154 | }
155 | return format;
156 | };
157 |
158 | //获取时间差 current:1497235409744 当前时间 start:1497235419744 开始时间
159 | export function getRemainingime(current: Number, start: Number) {
160 |
161 | let time = start - current;
162 | if (time < 0) {
163 | return ["0", "0", "0", "0", "0", "0"];
164 | }
165 | let year = Math.floor(time / (365 * 30 * 24 * 3600 * 1000));//年
166 |
167 | let month = Math.floor(time / (30 * 24 * 3600 * 1000));//月
168 |
169 | let days = Math.floor(time / (24 * 3600 * 1000));//日
170 | let temp1 = time % (24 * 3600 * 1000);
171 | let temp2 = temp1 % (3600 * 1000);
172 | let minutes = Math.floor(temp2 / (60 * 1000));//分
173 | let hours = Math.floor(temp1 / (3600 * 1000));//时
174 | let temp3 = temp2 % (60 * 1000);
175 | let seconds = Math.round(temp3 / 1000);//秒
176 |
177 | let strs = [year, toNormal(month), toNormal(days), toNormal(hours), toNormal(minutes), toNormal(seconds)];
178 | return strs;//["0", "0", "2", "7", "33", "30"]0年0月2日 7时33分30秒
179 | }
180 |
181 | //1497235419
182 | export function getRemainingimeDistance(distance: Number) {
183 | let time = distance * 1000;
184 | if (time < 0) {
185 | return ["0", "0", "0", "0", "0", "0"];
186 | }
187 |
188 | let year = Math.floor(time / (365 * 30 * 24 * 3600 * 1000));//年
189 |
190 | let month = Math.floor(time / (30 * 24 * 3600 * 1000));//月
191 |
192 | let days = Math.floor(time / (24 * 3600 * 1000));//日
193 | let temp1 = time % (24 * 3600 * 1000);
194 | let hours = Math.floor(temp1 / (3600 * 1000));//时
195 | let temp2 = temp1 % (3600 * 1000);
196 | let minutes = Math.floor(temp2 / (60 * 1000));//分
197 | let temp3 = temp2 % (60 * 1000);
198 | let seconds = Math.round(temp3 / 1000);//秒
199 |
200 | let strs = [year, toNormal(month), toNormal(days), toNormal(hours), toNormal(minutes), toNormal(seconds)];
201 | // strs.splice(0, 1, String(Number(strs[0]) - 1970));//年
202 | // strs.splice(1, 1, String(Number(strs[1]) - 1));
203 | // strs.splice(2, 1, (Number(strs[2]) - 1) < 10 ? '0' + (Number(strs[2]) - 1) : String(Number(strs[2]) - 1));
204 | // strs.splice(3, 1, (Number(strs[3]) - 8) < 10 ? '0' + (Number(strs[3]) - 8) : String(Number(strs[3]) - 8));
205 | // strs.splice(4, 1, Number(strs[4]) < 10 ? '0' + Number(strs[4]) : String(Number(strs[4])));
206 | // strs.splice(5, 1, Number(strs[5]) < 10 ? '0' + Number(strs[5]) : String(Number(strs[5])));
207 | return strs;//["0", "0", "2", "7", "33", "30"]0年0月2日 7时33分30秒
208 | }
209 |
210 | export function toNormal(time: Number) {
211 | return time >= 10 ? time : '0' + time;
212 | }
213 |
214 | //转换成日期
215 | export function toDate(timestamp: Number, format1 = 'yyyy-MM-dd hh:mm:ss') {
216 | try {
217 | if (timestamp > 10000) {
218 | let date = new Date();
219 | date.setTime(timestamp);
220 | return date.format(format1);//2014-07-10 10:21:12
221 | } else {
222 | return '';
223 | }
224 | } catch (erro) {
225 | return '';
226 | }
227 | return '';
228 | }
229 |
230 | //转换成时间搓
231 | export function toTimestamp(date: String) {
232 | let timestamp = Date.parse(date);
233 | return timestamp / 1000; // 1497233827569/1000
234 | }
235 |
236 | //CST时间=>转换成日期yyyy-MM-dd hh:mm:ss
237 | export function getTaskTime(strDate) {
238 | if (null == strDate || "" == strDate) {
239 | return "";
240 | }
241 | let dateStr = strDate.trim().split(" ");
242 | let strGMT = dateStr[0] + " " + dateStr[1] + " " + dateStr[2] + " " + dateStr[5] + " " + dateStr[3] + " GMT+0800";
243 | let date = new Date(Date.parse(strGMT));
244 | let y = date.getFullYear();
245 | let m = date.getMonth() + 1;
246 | m = m < 10 ? ('0' + m) : m;
247 | let d = date.getDate();
248 | d = d < 10 ? ('0' + d) : d;
249 | let h = date.getHours();
250 | let minute = date.getMinutes();
251 | minute = minute < 10 ? ('0' + minute) : minute;
252 | let second = date.getSeconds();
253 | second = second < 10 ? ('0' + second) : second;
254 |
255 | return y + "-" + m + "-" + d + " " + h + ":" + minute + ":" + second;
256 | };
257 |
258 | //1497235419
259 | export function getRemainingimeDistance2(distance: Number) {
260 | let time = distance;
261 | let days = Math.floor(time / (24 * 3600 * 1000));
262 | let temp1 = time % (24 * 3600 * 1000);
263 | let hours = Math.floor(temp1 / (3600 * 1000));
264 | let temp2 = temp1 % (3600 * 1000);
265 | let minutes = Math.floor(temp2 / (60 * 1000));
266 | if (time <= 60 * 1000) {
267 | minutes = 1;
268 | }
269 | let temp3 = temp2 % (60 * 1000);
270 | let seconds = Math.round(temp3 / 1000);
271 | return [hours, minutes];//["0", "0", "2", "7", "33", "30"]0年0月2日 7时33分30秒
272 | }
273 |
274 |
275 | /**
276 | * 存储
277 | * @param key
278 | * @param value
279 | * @param successCallback
280 | * @param errorCallback
281 | */
282 | export function saveAsyncStorage(key, value, successCallback, errorCallback) {
283 | AsyncStorage.setItem(key, value, error => {
284 | if (error) {
285 | errorCallback(error);
286 | }
287 | else {
288 | successCallback();
289 | }
290 | })
291 | }
292 |
293 | /**
294 | * 取值
295 | * @param key
296 | * @param successCallback
297 | * @param errorCallback
298 | */
299 | export function getAsyncStorage(key, successCallback, errorCallback) {
300 | AsyncStorage.getItem(key, (error, result) => {
301 | if (error) {
302 | errorCallback(error);
303 | }
304 | else {
305 | successCallback(result);
306 | }
307 | })
308 | }
309 |
310 | /**
311 | * 删除对应key的
312 | * @param key
313 | * @param successCallback
314 | * @param errorCallback
315 | */
316 | export function removeAsyncStorage(key, successCallback, errorCallback) {
317 | AsyncStorage.getItem(key, error => {
318 | if (error) {
319 | errorCallback(error);
320 | }
321 | else {
322 | successCallback();
323 | }
324 | })
325 | }
326 |
327 | //
328 | // // 将当前时间换成时间格式字符串
329 | // var timestamp3 = 1403058804;
330 | // var newDate = new Date();
331 | // newDate.setTime(timestamp3);
332 | // // Wed Jun 18 2014
333 | // console.log(newDate.toDateString());
334 | // // 2014-06-18T02:33:24.000Z
335 | // console.log(newDate.toISOString());
336 | // // 2014-06-18T02:33:24.000Z
337 | // console.log(newDate.toJSON());
338 | // // 2014年6月18日
339 | // console.log(newDate.toLocaleDateString());
340 | // // 2014年6月18日 上午10:33:24
341 | // console.log(newDate.toLocaleString());
342 | // // 上午10:33:24
343 | // console.log(newDate.toLocaleTimeString());
344 | // // Wed Jun 18 2014 10:33:24 GMT+0800 (中国标准时间)
345 | // console.log(newDate.toString());
346 | // // 10:33:24 GMT+0800 (中国标准时间)
347 | // console.log(newDate.toTimeString());
348 | // // Wed, 18 Jun 2014 02:33:24 GMT
349 | // console.log(newDate.toUTCString());
350 | // // 2014-07-10 10:21:12
351 | // console.log(newDate.format('yyyy-MM-dd h:m:s'))
352 |
--------------------------------------------------------------------------------