android ui组件实时刷新,Native UI 组件(Android)

这里有很多本地的 UI 部件准备被用到最新的应用程序中 - 其中一些是平台的一部分,其他的部分可以作为第三方库来使用,而且仍然还有更多的部分可能是在你自己的投资组合中使用。React Native 已经将几个最关键的平台组件进行了打包,如同ScrollView和TextInput,但是并不是所有都被打包了,所以当然也不可能是您以前写的应用程序。幸运的是,通过使用 React Native 应用程序可以很容易的将现有的组件进行无缝集成打包。

就如同本地模块指南,这是一个建立在假定你对 Android SDK 编程有些熟悉的基础上的更高级的指南。本指南将显示你该如何构建一个本地的 UI 组件, 帮助你遍历执行可用核心React Native库中可以使用的现有的 ImageViewcomponent 的一个子集。

ImageView 示例

在本例中我们将要完全了解实施要求来实现在 JavaScript 中允许使用 ImageViews。

本地视图是由扩展ViewManage或者更普遍的SimpleViewManager所创建和操纵的。在这种情况下SimpleViewManager是很方便的,因为它适用于普遍的属性,比如背景颜色、 不透明度和 Flexbox 布局。当然也有其他例子,当您在使用 FrameLayout 进行包装组件的时候,那么这时候您需要使用ViewManage,比如 ProgressBar。

这些子类在本质上是很单一的 — — 每个子类之中只有一个实例是通过这个桥接器创建的。他们将本地视图传递到了NativeViewHierarchyManager之中,这代表回到了通过使用它们原始的方法来设置并更新这些必要的视图的属性。ViewManagers通常也是这些视图的代表,它通过该桥接器将事件发送回 JavaScript。

传递一个视图很简单:

1.创建 ViewManager 子类2.使用@UIProp注释视图属性3.执行createViewInstance方法4.执行updateView方法5.在应用程序软件包中的createViewManagers中注册管理器6.执行 JavaScript 模块

1. 创建ViewManager子类

在本示例中,我们通过继承ReactImageView类型的SimpleViewManager来创建的视图管理器类ReactImageManager。它是由管理器管理的对象类型,这将成为一个本地视图。通过getName返回的名字将被用来从 Javascript 中引用本地视图类型。...public class ReactImageManager extends SimpleViewManager {  public static final String REACT_CLASS = "RCTImageView";  @Override

public String getName() {    return REACT_CLASS;

}

2. 注释视图属性

我们在 JavaScript 中使用@UIProp来注释需要被反映出来的属性。目前支持的类型有BOOLEAN,NUMBER,STRING,MAP和ARRAY。每个属性都被声明为公共静态最终字符串常量,并且给它们分配的值在 JavaScript 中都会成为属性的名称。@UIProp(UIProp.Type.STRING)  public static final String PROP_SRC = "src";  @UIProp(UIProp.Type.NUMBER)  public static final String PROP_BORDER_RADIUS = "borderRadius";  @UIProp(UIProp.Type.STRING)  public static final String PROP_RESIZE_MODE = ViewProps.RESIZE_MODE;

3. 执行createViewInstance方法

我们使用CreateViewInstance方法来创建视图,视图应将其自身初始化到默认状态,然后任何属性都会通过后续调用updateView来进行设置。@Override

public ReactImageView createViewInstance(ThemedReactContext context) {    return new ReactImageView(context, Fresco.newDraweeControllerBuilder(), mCallerContext);

}

4. 执行updateView方法

和 iOS 中有些不同的是在 Android 中,不是通过自动调用 setter 方法来给一个视图的属性进行赋值; 对于 Android 而言,你需要通过您的ViewManager中的updateView方法手动调用 setter。从CatalystStylesDiffMap中提取出来值,并且传递给视图实例。它是通过updateView和视图类的组合来检查属性的有效性,并采取相应的行动。@Override

public void updateView(final ReactImageView view,                         final CatalystStylesDiffMap props) {    super.updateView(view, props);    if (props.hasKey(PROP_RESIZE_MODE)) {

view.setScaleType(

ImageResizeMode.toScaleType(props.getString(PROP_RESIZE_MODE)));

}    if (props.hasKey(PROP_SRC)) {

view.setSource(props.getString(PROP_SRC));

}    if (props.hasKey(PROP_BORDER_RADIUS)) {

view.setBorderRadius(props.getFloat(PROP_BORDER_RADIUS, 0.0f));

}

view.maybeUpdateView();

}

}

5. 注册ViewManager

在 Java 中的最后一步是通过应用程序包的成员函数createViewManagers在应用程序中注册 ViewManager,这恰巧和Native Modules有些相似。@Override

public List createViewManagers(

ReactApplicationContext reactContext) {    return Arrays.asList(      new ReactImageManager()

);

}

6. 执行 JavaScript 模块

最后一步就是创建 JavaScript 模块来为您的新视图的用户定义 Java 和 JavaScript 之间的连接层。大量工作都是由 Java 和 JavaScript 中的 React 代码所完成,那么所有留给你的工作就是去描述propTypes。// ImageView.jsvar { requireNativeComponent } = require('react-native');var iface = {

name: 'ImageView',

propTypes: {

src: PropTypes.string,

borderRadius: PropTypes.number,

resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),

},

};module.exports = requireNativeComponent('RCTImageView', iface);

requireNativeComponent通常具有两个参数,第一个是本地视图的名称,第二个是描述组件接口的对象。组件接口应该声明一个友好的名称在调试消息中使用,并且必须声明本地视图所反映的propTypes。PropTypes用于检查用户使用本地视图的有效性。

事件

现在我们知道了如何公开使用 JS 中那些可以轻松控制的本地视图组件。但是我们该如何处理用户的事件呢,比如捏拉缩放或平移?当本地事件发生的时候,本地代码应该把事件传递给视图中的 JavaScript 代表,并且这两个视图都与getId()方法返回的值相连接。class MyCustomView extends View {

...   public void onReceiveNativeEvent() {

WritableMap event = Arguments.createMap();

event.putString("message", "MyMessage");

ReactContext reactContext = (ReactContext)getContext();

reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(

getId(),          "topChange",

event);

}

}

名字为topChange的事件对应于 JavaScript 里面的onChange回调 (映射是在UIManagerModuleConstants.java里面)。使用原始的事件来调用此回调。对于该事件,我们通常在包装组件中对它进行加工来形成一个更简单的 API。// MyCustomView.jsclass MyCustomView extends React.Component {

constructor() {    this._onChange = this._onChange.bind(this);

}

_onChange(event: Event) {    if (!this.props.onChange) {      return;

}    this.props.onChange(event.nativeEvent.message);

}

render() {    return ;

}

}

MyCustomView.propTypes = {  /**

* Callback that is called continuously when the user is dragging the map.

*/

onChange: React.PropTypes.func,

...

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值