2017-09-11 15:17:16 qq_24815655 阅读数 709
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

React-Native 安卓自定义View(一)

在移动端开发中,使用React-Native的越来越多,其使用js作为开发语言,并且提供大量的组件,大大提升了移动端开发的效率。但是最近在使用的过程中发现,RN提供的一些组件不能满足特定的业务需求,需要通过自定义view来实现。
查了很多网上的文章,大部分的文章只是简单的介绍了如何自定义view,但是并没有介绍怎么通过RN控制view的样式(css),以及view的一些相关事件的使用(比如TextInput的onBlur()等)
那么还是自己来吧,我们首先来看一下,RN是怎么使用css来控制view的样式的。


自定义view并控制其样式:
我们首先看一下RN的TextInput,它的位置在在node_modules/react-native/Libraries/Components/TextInput/TextInput.js

rn_textInput render()

在render方法中判断当前系统,如果是安卓执行_renderAndroid()方法。在这个方法的返回中,发现实际是AndroidTextInput。
rn_textInput renderAndroid

在这里我们看到AndroidTextInput中有onFocus、onBlur、onChange等方法,这个在后面会介绍这些方法是如何被调用的。
同样,我们也看到在AndroidTextInput中有“{…props}”,这句话是什么意思就不用赘述了吧。

rn_AndroidTextInput

看到这里发现在引用Java了。组件的名字叫“AndroidTextInput”。通过搜索在rn的源码中找到ReactTextInputManager.java,如下:
rn_ReactTextInputManager.java

根据getName()方法可知,在js层使用的TextInput实际上就是这个manger提供的。那就来仔细查看这个类吧。在使用TextInput时,我们经常用到的样式大致有width、height、backgroundColor、fontSize等等,下面就以fontSize为例查找。在ReactTextInputManager.java中发现有这么一个方法:
rn_fontsize

在这里看到了这个方法使用了注解@ReactProp(name = ViewProps.FONT_SIZE,defaultFloat = ViewDefaults.FONT_SIZE_SP),由此推断,rn在创建这个input时会调用带有ReactProp注解的方法,并将对应的值传入。(通过查看源码证明就是如此)。我们还发现,在设置fontSize时我们并没有指定单位,比如“fontSize:20”在这里会不难发现其实单位是sp而非px。

好了,对于源码探究先到此结束,下面开始打造自己的TextInput。首先自定义一个view,extends EditText。

import com.facebook.react.bridge.ReactContext;


/**
 * @Title:
 * @Desc:
 * @CreateTime: 2017-08-04 11:07
 * @Creator: Liy
 * @Version: 1.0
 */

@SuppressLint("AppCompatCustomView")
public class RNEditText extends EditText {


    public RNEditText(ReactContext reactContext) {
        super(reactContext);
    }
}

代码很简单,只是定义了一个EditText,没有做其他事情。然后创建一个manager extends BaseViewManager,代码如下:

/**
 * @Title:
 * @Desc:
 * @CreateTime: 2017-08-04 13:44
 * @Creator: Liy
 * @Version: 1.0
 */

public class RNEditTextManager extends BaseViewManager<RNEditText, LayoutShadowNode> {


    public static final String MANAGER_NAME = "RNEditText";


    @Override
    public String getName() {
        return MANAGER_NAME;
    }

    @Override
    public LayoutShadowNode createShadowNodeInstance() {
        return new ReactTextInputShadowNode();
    }

    @Override
    public Class<? extends LayoutShadowNode> getShadowNodeClass() {
        return ReactTextInputShadowNode.class;
    }

    @Override
    protected RNEditText createViewInstance(ThemedReactContext reactContext) {
        final RNEditText rnEditText = new RNEditText(reactContext);
        return rnEditText;
    }

    @Override
    public void updateExtraData(RNEditText root, Object extraData) {

    }


}

这个manager也很简单,下面就把fontSize加上去。如下:

@ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = ViewDefaults.FONT_SIZE_SP)
    public void setFontSize(RNEditText view, float fontSize) {
        view.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                (int)   Math.ceil(PixelUtil.toPixelFromSP(fontSize)));
    }

其实就是将rn里的源码复制到这里。然后在js层验证发现是有效果的。做到这里,我们如果想定义一个rn源码里不存在的样式是否可行呢,答案是肯定的。通过查看源码发现,rn在处理样式和属性的方式是一样的,事实上rn会把所有的样式都转换成为属性,然后去对应的viewManager类中查找带有ReactProp注解的方法。

在后续的章节中会介绍如何处理自定义view的一些事件。

这里就不把结果贴出来了,有兴趣的同学可以找我要源码。
我的QQ:243869018

2018-12-17 10:23:51 wayne214 阅读数 216
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

中文doc:仅供参考
import Storage from ‘react-native-storage’;
import {AsyncStorage} from ‘react-native’;

var storage = new Storage({
    // 最大容量,默认值1000条数据循环存储
    size: 1000,

    // 存储引擎:对于RN使用AsyncStorage,对于web使用window.localStorage
    // 如果不指定则数据只会保存在内存中,重启后即丢失
    storageBackend: AsyncStorage,

    // 数据过期时间,默认一整天(1000 * 3600 * 24 毫秒),设为null则永不过期
    defaultExpires: 1000 * 3600 * 24,

    // 读写时在内存中缓存数据。默认启用。
    enableCache: true,

    // 如果storage中没有相应数据,或数据已过期,
    // 则会调用相应的sync方法,无缝返回最新数据。
    // sync方法的具体说明会在后文提到
    // 你可以在构造函数这里就写好sync的方法
    // 或是在任何时候,直接对storage.sync进行赋值修改
    // 或是写到另一个文件里,这里require引入
    // sync: require('你可以另外写一个文件专门处理sync')

})

// 最好在全局范围内创建一个(且只有一个)storage实例,方便直接调用

// 对于web
// window.storage = storage;

// 对于react native
// global.storage = storage;

// 这样,在此**之后**的任意位置即可以直接调用storage
// 注意:全局变量一定是先声明,后使用
// 如果你在某处调用storage报错未定义
// 请检查global.storage = storage语句是否确实已经执行过了

// 使用key来保存数据。这些数据一般是全局独有的,常常需要调用的。
// 除非你手动移除,这些数据会被永久保存,而且默认不会过期。
storage.save({
    key: 'loginState',  // 注意:请不要在key中使用_下划线符号!
    data: {
        from: 'some other site',
        userid: 'some userid',
        token: 'some token'
    },

    // 如果不指定过期时间,则会使用defaultExpires参数
    // 如果设为null,则永不过期
    expires: 1000 * 3600
});

// 读取
storage.load({
    key: 'loginState',

    // autoSync(默认为true)意味着在没有找到数据或数据过期时自动调用相应的sync方法
    autoSync: true,

    // syncInBackground(默认为true)意味着如果数据过期,
    // 在调用sync方法的同时先返回已经过期的数据。
    // 设置为false的话,则等待sync方法提供的最新数据(当然会需要更多时间)。
    syncInBackground: true,

    // 你还可以给sync方法传递额外的参数
    syncParams: {
        extraFetchOptions: {
            // 各种参数
        },
        someFlag: true,
    },
}).then(ret => {
    // 如果找到数据,则在then方法中返回
    // 注意:这是异步返回的结果(不了解异步请自行搜索学习)
    // 你只能在then这个方法内继续处理ret数据
    // 而不能在then以外处理
    // 也没有办法“变成”同步返回
    // 你也可以使用“看似”同步的async/await语法

    console.log(ret.userid);
    this.setState({user: ret});
}).catch(err => {
    //如果没有找到数据且没有sync方法,
    //或者有其他异常,则在catch中返回
    console.warn(err.message);
    switch (err.name) {
        case 'NotFoundError':
            // TODO;
            break;
        case 'ExpiredError':
            // TODO
            break;
    }
})


// 使用key和id来保存数据,一般是保存同类别(key)的大量数据。
// 所有这些"key-id"数据共有一个保存上限(无论是否相同key)
// 即在初始化storage时传入的size参数。
// 在默认上限参数下,第1001个数据会覆盖第1个数据。
// 覆盖之后,再读取第1个数据,会返回catch或是相应的sync方法。
var userA = {
    name: 'A',
    age: 20,
    tags: [
        'geek',
        'nerd',
        'otaku'
    ]
};

storage.save({
    key: 'user',  // 注意:请不要在key中使用_下划线符号!
    id: '1001',   // 注意:请不要在id中使用_下划线符号!
    data: userA,
    expires: 1000 * 60
});

//load 读取
storage.load({
    key: 'user',
    id: '1001'
}).then(ret => {
    // 如果找到数据,则在then方法中返回
    console.log(ret.userid);
}).catch(err => {
    // 如果没有找到数据且没有sync方法,
    // 或者有其他异常,则在catch中返回
    console.warn(err.message);
    switch (err.name) {
        case 'NotFoundError':
            // TODO;
            break;
        case 'ExpiredError':
            // TODO
            break;
    }
})

// --------------------------------------------------

// 获取某个key下的所有id
storage.getIdsForKey('user').then(ids => {
    console.log(ids);
});

// 获取某个key下的所有数据
storage.getAllDataForKey('user').then(users => {
    console.log(users);
});

// !! 清除某个key下的所有数据
storage.clearMapForKey('user');

// --------------------------------------------------

// 删除单个数据
storage.remove({
    key: 'lastPage'
});
storage.remove({
    key: 'user',
    id: '1001'
});

// !! 清空map,移除所有"key-id"数据(但会保留只有key的数据)
storage.clearMap();


//同步远程数据(刷新)
storage.sync = {
    // sync方法的名字必须和所存数据的key完全相同
    // 方法接受的参数为一整个object,所有参数从object中解构取出
    // 这里可以使用promise。或是使用普通回调函数,但需要调用resolve或reject。
    user(params){
        let {id, resolve, reject, syncParams: {extraFetchOptions, someFlag}} = params;
        fetch('user/', {
            method: 'GET',
            body: 'id=' + id,
            ...extraFetchOptions,
        }).then(response => {
            return response.json();
        }).then(json => {
            //console.log(json);
            if (json && json.user) {
                storage.save({
                    key: 'user',
                    id,
                    data: json.user
                });

                if (someFlag) {
                    // 根据syncParams中的额外参数做对应处理
                }

                // 成功则调用resolve
                resolve && resolve(json.user);
            }
            else {
                // 失败则调用reject
                reject && reject(new Error('data parse error'));
            }
        }).catch(err => {
            console.warn(err);
            reject && reject(err);
        });
    }


}


//有了上面这个sync方法,以后再调用storage.load时,如果本地并没有存储相应的user,那么会自动触发storage.sync.user去远程取回数据并无缝返回。

storage.load({
    key: 'user',
    id: '1002'
}).then()

//读取批量数据

// 使用和load方法一样的参数读取批量数据,但是参数是以数组的方式提供。
// 会在需要时分别调用相应的sync方法,最后统一返回一个有序数组。
storage.getBatchData([
    {key: 'loginState'},
    {key: 'checkPoint', syncInBackground: false},
    {key: 'balance'},
    {key: 'user', id: '1009'}
])
    .then(results => {
        results.forEach(result => {
            console.log(result);
        })
    })

//根据key和一个id数组来读取批量数据
storage.getBatchDataWithIds({
    key: 'user',
    ids: ['1001', '1002', '1003']
})
    .then()


/*
 这两个方法除了参数形式不同,还有个值得注意的差异。getBatchData会在数据缺失时挨个调用不同的sync方法(因为key不同)。
 但是getBatchDataWithIds却会把缺失的数据统计起来,将它们的id收集到一个数组中,然后一次传递给对应的sync方法(避免挨个查询导致同时发起大量请求),
 所以你需要在服务端实现通过数组来查询返回,还要注意对应的sync方法的参数处理(因为id参数可能是一个字符串,也可能是一个数组的字符串)。
 */
2018-12-17 02:29:54 weixin_34289744 阅读数 33
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

中文doc:仅供参考 import Storage from 'react-native-storage'; import {AsyncStorage} from 'react-native';

var storage = new Storage({
    // 最大容量,默认值1000条数据循环存储
    size: 1000,

    // 存储引擎:对于RN使用AsyncStorage,对于web使用window.localStorage
    // 如果不指定则数据只会保存在内存中,重启后即丢失
    storageBackend: AsyncStorage,

    // 数据过期时间,默认一整天(1000 * 3600 * 24 毫秒),设为null则永不过期
    defaultExpires: 1000 * 3600 * 24,

    // 读写时在内存中缓存数据。默认启用。
    enableCache: true,

    // 如果storage中没有相应数据,或数据已过期,
    // 则会调用相应的sync方法,无缝返回最新数据。
    // sync方法的具体说明会在后文提到
    // 你可以在构造函数这里就写好sync的方法
    // 或是在任何时候,直接对storage.sync进行赋值修改
    // 或是写到另一个文件里,这里require引入
    // sync: require('你可以另外写一个文件专门处理sync')

})

// 最好在全局范围内创建一个(且只有一个)storage实例,方便直接调用

// 对于web
// window.storage = storage;

// 对于react native
// global.storage = storage;

// 这样,在此**之后**的任意位置即可以直接调用storage
// 注意:全局变量一定是先声明,后使用
// 如果你在某处调用storage报错未定义
// 请检查global.storage = storage语句是否确实已经执行过了

// 使用key来保存数据。这些数据一般是全局独有的,常常需要调用的。
// 除非你手动移除,这些数据会被永久保存,而且默认不会过期。
storage.save({
    key: 'loginState',  // 注意:请不要在key中使用_下划线符号!
    data: {
        from: 'some other site',
        userid: 'some userid',
        token: 'some token'
    },

    // 如果不指定过期时间,则会使用defaultExpires参数
    // 如果设为null,则永不过期
    expires: 1000 * 3600
});

// 读取
storage.load({
    key: 'loginState',

    // autoSync(默认为true)意味着在没有找到数据或数据过期时自动调用相应的sync方法
    autoSync: true,

    // syncInBackground(默认为true)意味着如果数据过期,
    // 在调用sync方法的同时先返回已经过期的数据。
    // 设置为false的话,则等待sync方法提供的最新数据(当然会需要更多时间)。
    syncInBackground: true,

    // 你还可以给sync方法传递额外的参数
    syncParams: {
        extraFetchOptions: {
            // 各种参数
        },
        someFlag: true,
    },
}).then(ret => {
    // 如果找到数据,则在then方法中返回
    // 注意:这是异步返回的结果(不了解异步请自行搜索学习)
    // 你只能在then这个方法内继续处理ret数据
    // 而不能在then以外处理
    // 也没有办法“变成”同步返回
    // 你也可以使用“看似”同步的async/await语法

    console.log(ret.userid);
    this.setState({user: ret});
}).catch(err => {
    //如果没有找到数据且没有sync方法,
    //或者有其他异常,则在catch中返回
    console.warn(err.message);
    switch (err.name) {
        case 'NotFoundError':
            // TODO;
            break;
        case 'ExpiredError':
            // TODO
            break;
    }
})


// 使用key和id来保存数据,一般是保存同类别(key)的大量数据。
// 所有这些"key-id"数据共有一个保存上限(无论是否相同key)
// 即在初始化storage时传入的size参数。
// 在默认上限参数下,第1001个数据会覆盖第1个数据。
// 覆盖之后,再读取第1个数据,会返回catch或是相应的sync方法。
var userA = {
    name: 'A',
    age: 20,
    tags: [
        'geek',
        'nerd',
        'otaku'
    ]
};

storage.save({
    key: 'user',  // 注意:请不要在key中使用_下划线符号!
    id: '1001',   // 注意:请不要在id中使用_下划线符号!
    data: userA,
    expires: 1000 * 60
});

//load 读取
storage.load({
    key: 'user',
    id: '1001'
}).then(ret => {
    // 如果找到数据,则在then方法中返回
    console.log(ret.userid);
}).catch(err => {
    // 如果没有找到数据且没有sync方法,
    // 或者有其他异常,则在catch中返回
    console.warn(err.message);
    switch (err.name) {
        case 'NotFoundError':
            // TODO;
            break;
        case 'ExpiredError':
            // TODO
            break;
    }
})

// --------------------------------------------------

// 获取某个key下的所有id
storage.getIdsForKey('user').then(ids => {
    console.log(ids);
});

// 获取某个key下的所有数据
storage.getAllDataForKey('user').then(users => {
    console.log(users);
});

// !! 清除某个key下的所有数据
storage.clearMapForKey('user');

// --------------------------------------------------

// 删除单个数据
storage.remove({
    key: 'lastPage'
});
storage.remove({
    key: 'user',
    id: '1001'
});

// !! 清空map,移除所有"key-id"数据(但会保留只有key的数据)
storage.clearMap();


//同步远程数据(刷新)
storage.sync = {
    // sync方法的名字必须和所存数据的key完全相同
    // 方法接受的参数为一整个object,所有参数从object中解构取出
    // 这里可以使用promise。或是使用普通回调函数,但需要调用resolve或reject。
    user(params){
        let {id, resolve, reject, syncParams: {extraFetchOptions, someFlag}} = params;
        fetch('user/', {
            method: 'GET',
            body: 'id=' + id,
            ...extraFetchOptions,
        }).then(response => {
            return response.json();
        }).then(json => {
            //console.log(json);
            if (json && json.user) {
                storage.save({
                    key: 'user',
                    id,
                    data: json.user
                });

                if (someFlag) {
                    // 根据syncParams中的额外参数做对应处理
                }

                // 成功则调用resolve
                resolve && resolve(json.user);
            }
            else {
                // 失败则调用reject
                reject && reject(new Error('data parse error'));
            }
        }).catch(err => {
            console.warn(err);
            reject && reject(err);
        });
    }


}


//有了上面这个sync方法,以后再调用storage.load时,如果本地并没有存储相应的user,那么会自动触发storage.sync.user去远程取回数据并无缝返回。

storage.load({
    key: 'user',
    id: '1002'
}).then()

//读取批量数据

// 使用和load方法一样的参数读取批量数据,但是参数是以数组的方式提供。
// 会在需要时分别调用相应的sync方法,最后统一返回一个有序数组。
storage.getBatchData([
    {key: 'loginState'},
    {key: 'checkPoint', syncInBackground: false},
    {key: 'balance'},
    {key: 'user', id: '1009'}
])
    .then(results => {
        results.forEach(result => {
            console.log(result);
        })
    })

//根据key和一个id数组来读取批量数据
storage.getBatchDataWithIds({
    key: 'user',
    ids: ['1001', '1002', '1003']
})
    .then()


/*
 这两个方法除了参数形式不同,还有个值得注意的差异。getBatchData会在数据缺失时挨个调用不同的sync方法(因为key不同)。
 但是getBatchDataWithIds却会把缺失的数据统计起来,将它们的id收集到一个数组中,然后一次传递给对应的sync方法(避免挨个查询导致同时发起大量请求),
 所以你需要在服务端实现通过数组来查询返回,还要注意对应的sync方法的参数处理(因为id参数可能是一个字符串,也可能是一个数组的字符串)。
 */
复制代码

转载于:https://juejin.im/post/5c1709edf265da611510b27f

2017-12-14 19:36:26 wanshaobo888 阅读数 1265
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

最近更新时间:2017年12月14日19:36:11

《我的博客地图》

    上学的时候希望尽早工作,融入社会,积累工作经验。工作之后才发现,工作永远干不完,而且每个项目都不一样,积累工作经验不是一时半会的事情,而是日积月累细心领悟的过程,因此,需要不断总结和积累所见所闻,保持学习,才能轻松驾驭工作。

    在react native项目中,一方面使用RN技术进行APP开发,同时还能在APP中嵌套使用网页,是常见的业务需求。常见方案有三种:使用html文件、URI地址、html代码片段。

0、概述

    import { WebView } from 'react-native';

    WebView组件,用于创建一个原生的WebView,可以用于访问一个网页;

1、HTML代码片段在WebView中的使用

    html代码片段如下html代码片段的内容可以是图文混编,来源于ajax接口返回的数据(string类型):

let HTML = '';

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />
        <style>
            html {
                font-size: 20px;
            }
            @media only screen and (min-width: 400px) {
                html {
                    font-size: 21.33333333px !important;
                }
            }
            @media only screen and (min-width: 414px) {
                html {
                    font-size: 22.08px !important;
                }
            }
            @media only screen and (min-width: 480px) {
                html {
                    font-size: 25.6px !important;
                }
            }
            body {
                margin: 0;
                padding: 1.5rem .8rem 1.5rem .8rem;
                color: #424242;
                line-height: 26px;
                font-size: .8rem;
            }
            .content{
                font-size: .8rem;
                line-height: 1.3rem;
            }
            img {
                width: 100%;
                display: block;
                margin: .5rem 0;
            }
            p{
                margin: 0;
                padding: 0;
            }
        </style>
    </head>
<body>
    <div class="content">
    <p>asdfasdf</p>
    </div>
</body>
</html>

    对HTML代码片段style样式适配(如:禁止长按触发)重置如下:

let arr = HTML.split("<style>");
let disableSelect =`* {-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}`
if(arr.length > 1){
    arr[1] = disableSelect + arr[1];
    HTML = arr.join("<style>");
}

    APP页面使用方法:

<WebView
            ref={webview => {this.webview = webview;}}
            onError = {()=>{
              ToastAndroid.show(`加载失败,请重试!`,ToastAndroid.SHORT,ToastAndroid.CENTER);
              this.props.navigation.goBack()
            }}
            javaScriptEnabled={true}
            domStorageEnabled={true}
            onMessage={this.onMessage}
            source={{html: HTML}}

/>

    获取WebView组件实例的方法:

<WebView ref={webview => {this.webview01 = webview;}} />

console.log(this.webview01);//对象内容如下

<WebView ref={‘WEBVIEW01_REF’/>

console.log(this.refs[WEBVIEW01_REF]);//对象内容如下

2、uri地址在WebView中的使用

    uri地址如下,uri的内容可以是PDF文件、doc文件,来源于ajax接口返回的数据(string类型):

let uri = 'http://abc.com/aa/bb/cc=='

<WebView
            source={{uri: uri}}

/>

3、WebView组件实例详解

    WebView组件实例是一个WebView对象,包括属性和方法,如下:

属性:context、props(domStorageEnabled、javaScriptEnabled、onError()、onMessage()、saveFormDataDisabled、scalesPageToFit、source:{}、thirdPartyCookiesEnabled、ref)、refs、state

方法:goBack()、goForward()、onLoadingError()、reloadd()、postMessage()......

    使用:

this.refs[WEBVIEW01_REF].onMessage();//在webview内部的网页中调用window.postMessage方法时可以触发此属性对应的函数,从而实现网页和RN之间的数据交换。 设置此属性的同时会在webview中注入一个postMessage的全局函数并覆盖可能已经存在的同名实现。

未完,待续...


2018-01-05 08:35:45 s349856186 阅读数 2823
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

点击打开链接


react-native -30 (每天一个Demo,共三十个,有些demo很不错哦)

https://github.com/fangwei716/30-days-of-react-native

  • 拖动九宫格

    https://raw.githubusercontent.com/fangwei716/ThirtyDaysOfReactNative/screenshots/screenshot/day18.gif
  • 手势解锁

    https://raw.githubusercontent.com/fangwei716/ThirtyDaysOfReactNative/screenshots/screenshot/day16.gif

自动管理Timer组件

此组件目前只支持ES5 语法,ES6语法请在componentWillUnmount() 中清除timer

https://github.com/reactjs/react-timer-mixin

蚂蚁金服组件库 antd-mobile

https://github.com/ant-design/ant-design-mobile

react-native-button

https://github.com/ide/react-native-button

点击图片放大缩小

https://github.com/ascoders/react-native-image-viewer

进度组件

https://github.com/oblador/react-native-progress

[图片上传失败...(image-8658f8-1511425885032)]

路由组件react-native-router-flux

https://github.com/aksonov/react-native-router-flux

简单的storage封装

https://github.com/jasonmerino/react-native-simple-store

tabBar组件react-native-tab-navigator

https://github.com/happypancake/react-native-tab-navigator

iconFont组件

https://github.com/oblador/react-native-vector-icons

分页组件 react-native-viewpager

https://github.com/race604/react-native-viewpager

导航组件 react-navigation

https://github.com/react-community/react-navigation

动画

https://github.com/oblador/react-native-animatable

轮播

https://github.com/nick/react-native-carousel

倒计时

https://github.com/buhe/react-native-countdown

设备信息

react-native-device-info

https://github.com/rebeccahughes/react-native-device-info

文件上传

react-native-fileupload

https://github.com/PhilippKrone/react-native-fileupload

图标

https://github.com/corymsmith/react-native-icons

https://github.com/oblador/react-native-vector-icons

图片选择器

react-native-image-picker

https://github.com/react-community/react-native-image-picker

iOS KeyChain管理

react-native-keychain

https://github.com/oblador/react-native-keychain

滚轮选择器

react-native-picker

https://github.com/beefe/react-native-picker

[图片上传失败...(image-689a68-1511950421120)]

Android 滚轮选择器

react-native-picker-Android

https://github.com/beefe/react-native-picker-android

可刷新列表

react-native-refreshable-listview

https://github.com/jsdf/react-native-refreshable-listview

可滚动标签

react-native-scrollable-tab-view

https://github.com/skv-headless/react-native-scrollable-tab-view

侧栏

react-native-side-menu

https://github.com/react-native-community/react-native-side-menu

轮播

react-native-swiper

https://github.com/leecade/react-native-swiper

音视频播放

react-native-video

https://github.com/react-native-community/react-native-video

分页浏览

react-native-viewpager

https://github.com/race604/react-native-viewpager

可滑动的底部或上部导航栏框架

react-native-scrollable-tab-view

https://github.com/skv-headless/react-native-scrollable-tab-view

底部或上部导航框架(不可滑动)

react-native-tab-navigator

https://github.com/happypancake/react-native-tab-navigator

CheckBox

react-native-check-box

https://github.com/crazycodeboy/react-native-check-box

启动白屏问题

react-native-splash-screen

https://github.com/crazycodeboy/react-native-splash-screen

简易路由跳转框架

react-native-simple-router

https://github.com/react-native-simple-router-community/react-native-simple-router

持久化存储

react-native-storage

https://github.com/sunnylqm/react-native-storage

分类ListView

react-native-sortable-listview

https://github.com/deanmcpherson/react-native-sortable-listview

将 HTML 目录作为本地视图的控件,其风格可以定制

react-native-htmlview

https://github.com/jsdf/react-native-htmlview

Toast

react-native-easy-toast

https://github.com/crazycodeboy/react-native-easy-toast

material组件库(各种漂亮的小组件)

https://github.com/xinthink/react-native-material-kit

base组件库(各种封装不错的小组件)

http://nativebase.io/docs/v0.4.6/components#anatomy https://github.com/GeekyAnts/NativeBase

按钮

https://github.com/mastermoo/react-native-action-button https://github.com/ide/react-native-button

输入框表单验证

https://github.com/gcanti/tcomb-form-native https://github.com/FaridSafi/react-native-gifted-form https://github.com/bartonhammond/snowflake

炫酷效果的 TextInput

https://github.com/halilb/react-native-textinput-effects https://github.com/zbtang/React-Native-TextInputLayout

聊天

https://github.com/FaridSafi/react-native-gifted-chat

地图

https://github.com/lelandrichardson/react-native-maps

动画

https://github.com/oblador/react-native-animatable

加载动画

https://github.com/maxs15/react-native-spinkit

抽屉效果

https://github.com/root-two/react-native-drawer

侧滑按钮

https://github.com/dancormier/react-native-swipeout https://github.com/jemise111/react-native-swipe-list-view

图表

https://github.com/tomauty/react-native-chart

下拉放大

https://github.com/lelandrichardson/react-native-parallax-view

可滑动的日历组件

https://github.com/cqm1994617/react-native-myCalendar

语言转化和一些常用格式转换

https://github.com/joshswan/react-native-globalize

单选多选ListView

https://github.com/hinet/react-native-checkboxlist

选择按钮

https://github.com/sconxu/react-native-checkbox

二维码

https://github.com/ideacreation/react-native-barcodescanner

制作本地库

https://github.com/frostney/react-native-create-library

影音相关

https://github.com/MisterAlex95/react-native-record-sound

安卓录音

https://github.com/bosung90/react-native-audio-android

提示消息的Bar

https://github.com/KBLNY/react-native-message-bar

iOS原生TableView

https://github.com/aksonov/react-native-tableview

点击弹出视图

https://github.com/jeanregisser/react-native-popover https://github.com/instea/react-native-popup-menu

3D Touch

https://github.com/madriska/react-native-quick-actions

双平台兼容的ActionSheet

https://github.com/beefe/react-native-actionsheet

照片墙

https://github.com/ldn0x7dc/react-native-gallery

键盘遮挡问题

https://github.com/wix/react-native-keyboard-aware-scrollview https://github.com/reactnativecn/react-native-inputscrollview

本地存储

https://github.com/sunnylqm/react-native-storage

星星

https://github.com/djchie/react-native-star-rating

国际化

https://github.com/joshswan/react-native-globalize

扫描二维码

https://github.com/lazaronixon/react-native-qrcode-reader

通讯录

https://github.com/rt2zz/react-native-contacts

加密

https://www.npmjs.com/package/crypto-js

缓存管理

https://github.com/reactnativecn/react-native-http-cache

ListView的优化

https://github.com/sghiassy/react-native-sglistview

图片和base64互转

https://github.com/xfumihiro/react-native-image-to-base64

安卓 iOS 白屏解决

https://github.com/mehcode/rn-splash-screen

Text跑马灯效果

https://github.com/remobile/react-native-marquee-label

清除按钮的输入框

https://github.com/beefe/react-native-textinput

webView-bridge相关

https://github.com/alinz/react-native-webview-bridge

判断横竖屏

https://github.com/yamill/react-native-orientation

PDF

https://github.com/cnjon/react-native-pdf-view

获取设备信息

https://github.com/rebeccahughes/react-native-device-info

手势放大缩小移动

https://github.com/kiddkai/react-native-gestures https://github.com/johanneslumpe/react-native-gesture-recognizers

下拉-上拉-刷新

https://github.com/FaridSafi/react-native-gifted-listview https://github.com/jsdf/react-native-refreshable-listview https://github.com/greatbsky/react-native-pull/wiki

下拉选择

https://github.com/alinz/react-native-dropdown

图片查看

https://github.com/oblador/react-native-lightbox

照片选择

https://github.com/marcshilling/react-native-image-picker https://github.com/ivpusic/react-native-image-crop-picker

图片加载进度条

https://github.com/oblador/react-native-image-progress

轮播视图

https://github.com/race604/react-native-viewpager https://github.com/FuYaoDe/react-native-app-intro https://github.com/appintheair/react-native-looped-carousel https://github.com/leecade/react-native-swiper

模态视图

https://github.com/maxs15/react-native-modalbox https://github.com/brentvatne/react-native-modal https://github.com/bodyflex/react-native-simple-modal

毛玻璃效果

https://github.com/react-native-fellowship/react-native-blur

头像库

https://github.com/oblador/react-native-vector-icons

滑动选项卡

https://github.com/skv-headless/react-native-scrollable-tab-view

文件上传

https://github.com/aroth/react-native-uploader

gif

动画

https://github.com/oblador/react-native-animatable

gif

图标

https://github.com/oblador/react-native-vector-icons

gif

图片选择器(可多选)

https://github.com/ivpusic/react-native-image-crop-picker

滚轮选择器

https://github.com/beefe/react-native-picker

下拉刷新listview

https://github.com/jsdf/react-native-refreshable-listview

[图片上传失败...(image-86b334-1511425885032)]

可滚动Tab

https://github.com/skv-headless/react-native-scrollable-tab-view

侧栏

https://github.com/react-native-community/react-native-side-menu

图片轮播

https://github.com/leecade/react-native-swiper

CheckBox

https://github.com/crazycodeboy/react-native-check-box

Toast

https://github.com/crazycodeboy/react-native-easy-toast

各种漂亮的小组件

https://github.com/xinthink/react-native-material-kit

base组件库

https://github.com/GeekyAnts/NativeBase

按钮

https://github.com/mastermoo/react-native-action-button

炫酷效果的 TextInput

https://github.com/halilb/react-native-textinput-effects https://github.com/zbtang/React-Native-TextInputLayout

聊天

https://github.com/FaridSafi/react-native-gifted-chat

百度地图

https://github.com/lovebing/react-native-baidu-map http://www.jianshu.com/p/eceb7e66fa5e

加载动画

https://github.com/maxs15/react-native-spinkit

侧滑按钮

https://github.com/dancormier/react-native-swipeout https://github.com/jemise111/react-native-swipe-list-view

图表

https://github.com/wuxudong/react-native-charts-wrapper

下拉放大

https://github.com/lelandrichardson/react-native-parallax-view

[图片上传失败...(image-9dccb8-1511425885033)]

可滑动的日历组件

https://github.com/cqm1994617/react-native-myCalendar

提示消息的Bar

https://github.com/KBLNY/react-native-message-bar

点击弹出视图

https://github.com/jeanregisser/react-native-popover

3D Touch

https://github.com/madriska/react-native-quick-actions

双平台兼容的ActionSheet

https://github.com/beefe/react-native-actionsheet

图片加载进度条

https://github.com/oblador/react-native-image-progress

模态视图

https://github.com/maxs15/react-native-modalbox https://github.com/bodyflex/react-native-simple-modal

毛玻璃效果

https://github.com/react-native-community/react-native-blur

按钮特效

https://github.com/dwicao/react-native-circle-button

折叠动画

https://github.com/jmurzy/react-native-foldview

方块滚动轮播图

https://github.com/archriss/react-native-snap-carousel

下拉选项组件

https://github.com/sohobloo/react-native-modal-dropdown

提示气泡toast

https://github.com/magicismight/react-native-root-toast

From表单

https://github.com/FaridSafi/react-native-gifted-form

线性渐变颜色

https://link.jianshu.com/?t=https://github.com/brentvatne/react-native-linear-gradient

app 引导页

https://github.com/fuyaode/react-native-app-intro

手势解锁密码

https://link.jianshu.com/?t=https://github.com/spikef/react-native-gesture-password

瀑布流列表

https://github.com/xudafeng/autoresponsive-react-native

折叠列表

https://github.com/naoufal/react-native-accordion

通讯录

https://github.com/i6mi6/react-native-alphabetlistview

多级菜单

https://github.com/vczero/react-native-tab-menu

image

tip提示框

https://github.com/chirag04/react-native-tooltip

image

pdf文件上传

https://link.jianshu.com/?t=https://github.com/wonday/react-native-pdf https://github.com/christopherdro/react-native-html-to-pdf

上传doc文档

https://github.com/philipphecht/react-native-doc-viewer

列表滑动删除

https://github.com/jemise111/react-native-swipe-list-view

image

IM聊天界面

https://github.com/Ice-MT/react-native-imUI

image
作者:光强_上海 链接:https://www.jianshu.com/p/18fd4b438958 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。



没有更多推荐了,返回首页