|
| 1 | +Embora a visualização da Web integrada tenha muitos recursos, não é possível lidar com todos os casos de uso no React Native. Você pode, no entanto, estender a visualização da web com código nativo sem bifurcar o React Native ou duplicar todo o código de visualização da web existente. |
| 2 | + |
| 3 | +Antes de fazer isso, você deve estar familiarizado com os conceitos de [componentes de interface do usuário nativos](https://reactnative.dev/docs/native-components-android). Você também deve se familiarizar com o [código nativo para visualizações da web](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java), pois você terá que usar isso como referência ao implementar novos recursos, embora não seja necessária uma compreensão profunda. |
| 4 | + |
| 5 | +## Código Nativo |
| 6 | + |
| 7 | +Para começar, você precisará criar uma subclasse de `RNCWebViewManager`, `RNCWebView` e `RNCWebViewClient`. Em seu gerenciador de visualizações, você precisará substituir: |
| 8 | + |
| 9 | +- `createReactWebViewInstance` |
| 10 | +- `getName` |
| 11 | +- `addEventEmitters` |
| 12 | + |
| 13 | +```java |
| 14 | +@ReactModule(name = CustomWebViewManager.REACT_CLASS) |
| 15 | +public class CustomWebViewManager extends RNCWebViewManager { |
| 16 | + /* Este nome deve corresponder ao que estamos nos referindo em JS */ |
| 17 | + protected static final String REACT_CLASS = "RCTCustomWebView"; |
| 18 | + |
| 19 | + protected static class CustomWebViewClient extends RNCWebViewClient { } |
| 20 | + |
| 21 | + protected static class CustomWebView extends RNCWebView { |
| 22 | + public CustomWebView(ThemedReactContext reactContext) { |
| 23 | + super(reactContext); |
| 24 | + } |
| 25 | + } |
| 26 | + |
| 27 | + @Override |
| 28 | + protected RNCWebView createRNCWebViewInstance(ThemedReactContext reactContext) { |
| 29 | + return new CustomWebView(reactContext); |
| 30 | + } |
| 31 | + |
| 32 | + @Override |
| 33 | + public String getName() { |
| 34 | + return REACT_CLASS; |
| 35 | + } |
| 36 | + |
| 37 | + @Override |
| 38 | + protected void addEventEmitters(ThemedReactContext reactContext, WebView view) { |
| 39 | + view.setWebViewClient(new CustomWebViewClient()); |
| 40 | + } |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +Você precisará seguir as etapas usuais para [registrar o módulo](native-modules-android.md#register-the-module). |
| 45 | + |
| 46 | +### Adicionando novas propriedades |
| 47 | + |
| 48 | +Para adicionar uma nova propriedade, você precisará adicioná-la a `CustomWebView` e depois expô-la em `CustomWebViewManager`. |
| 49 | + |
| 50 | +```java |
| 51 | +public class CustomWebViewManager extends RNCWebViewManager { |
| 52 | + ... |
| 53 | + |
| 54 | + protected static class CustomWebView extends RNCWebView { |
| 55 | + public CustomWebView(ThemedReactContext reactContext) { |
| 56 | + super(reactContext); |
| 57 | + } |
| 58 | + |
| 59 | + protected @Nullable String mFinalUrl; |
| 60 | + |
| 61 | + public void setFinalUrl(String url) { |
| 62 | + mFinalUrl = url; |
| 63 | + } |
| 64 | + |
| 65 | + public String getFinalUrl() { |
| 66 | + return mFinalUrl; |
| 67 | + } |
| 68 | + } |
| 69 | + |
| 70 | + ... |
| 71 | + |
| 72 | + @ReactProp(name = "finalUrl") |
| 73 | + public void setFinalUrl(WebView view, String url) { |
| 74 | + ((CustomWebView) view).setFinalUrl(url); |
| 75 | + } |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +### Adicionando novos eventos |
| 80 | + |
| 81 | +Para eventos, primeiro você precisará criar uma subclasse de evento. |
| 82 | + |
| 83 | +```java |
| 84 | +// NavigationCompletedEvent.java |
| 85 | +public class NavigationCompletedEvent extends Event<NavigationCompletedEvent> { |
| 86 | + private WritableMap mParams; |
| 87 | + |
| 88 | + public NavigationCompletedEvent(int viewTag, WritableMap params) { |
| 89 | + super(viewTag); |
| 90 | + this.mParams = params; |
| 91 | + } |
| 92 | + |
| 93 | + @Override |
| 94 | + public String getEventName() { |
| 95 | + return "navigationCompleted"; |
| 96 | + } |
| 97 | + |
| 98 | + @Override |
| 99 | + public void dispatch(RCTEventEmitter rctEventEmitter) { |
| 100 | + init(getViewTag()); |
| 101 | + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); |
| 102 | + } |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +Você pode acionar o evento em seu cliente de visualização da web. Você pode conectar manipuladores existentes se seus eventos forem baseados neles. |
| 107 | + |
| 108 | +Você deve consultar [RNCWebViewManager.java](https://github.com/react-native-webview/react-native-webview/blob/master/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java) na base de código react-native-webview para ver quais manipuladores estão disponíveis e como eles são implementados. Você pode estender quaisquer métodos aqui para fornecer funcionalidade extra. |
| 109 | + |
| 110 | +```java |
| 111 | +public class NavigationCompletedEvent extends Event<NavigationCompletedEvent> { |
| 112 | + private WritableMap mParams; |
| 113 | + |
| 114 | + public NavigationCompletedEvent(int viewTag, WritableMap params) { |
| 115 | + super(viewTag); |
| 116 | + this.mParams = params; |
| 117 | + } |
| 118 | + |
| 119 | + @Override |
| 120 | + public String getEventName() { |
| 121 | + return "navigationCompleted"; |
| 122 | + } |
| 123 | + |
| 124 | + @Override |
| 125 | + public void dispatch(RCTEventEmitter rctEventEmitter) { |
| 126 | + init(getViewTag()); |
| 127 | + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams); |
| 128 | + } |
| 129 | +} |
| 130 | + |
| 131 | +// CustomWebViewManager.java |
| 132 | +protected static class CustomWebViewClient extends RNCWebViewClient { |
| 133 | + @Override |
| 134 | + public boolean shouldOverrideUrlLoading(WebView view, String url) { |
| 135 | + boolean shouldOverride = super.shouldOverrideUrlLoading(view, url); |
| 136 | + String finalUrl = ((CustomWebView) view).getFinalUrl(); |
| 137 | + |
| 138 | + if (!shouldOverride && url != null && finalUrl != null && new String(url).equals(finalUrl)) { |
| 139 | + final WritableMap params = Arguments.createMap(); |
| 140 | + dispatchEvent(view, new NavigationCompletedEvent(view.getId(), params)); |
| 141 | + } |
| 142 | + |
| 143 | + return shouldOverride; |
| 144 | + } |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +Finalmente, você precisará expor os eventos em `CustomWebViewManager` através de `getExportedCustomDirectEventTypeConstants`. Observe que atualmente, a implementação padrão retorna `null`, mas isso pode mudar no futuro. |
| 149 | + |
| 150 | +```java |
| 151 | +public class CustomWebViewManager extends RNCWebViewManager { |
| 152 | + ... |
| 153 | + |
| 154 | + @Override |
| 155 | + public @Nullable |
| 156 | + Map getExportedCustomDirectEventTypeConstants() { |
| 157 | + Map<String, Object> export = super.getExportedCustomDirectEventTypeConstants(); |
| 158 | + if (export == null) { |
| 159 | + export = MapBuilder.newHashMap(); |
| 160 | + } |
| 161 | + export.put("navigationCompleted", MapBuilder.of("registrationName", "onNavigationCompleted")); |
| 162 | + return export; |
| 163 | + } |
| 164 | +} |
| 165 | +``` |
| 166 | + |
| 167 | +## Interface JavaScript |
| 168 | + |
| 169 | +Para usar sua visualização da Web personalizada, você pode criar uma classe para ela. Sua classe deve retornar um componente `WebView` com o prop `nativeConfig.component` definido para seu componente nativo (veja abaixo). |
| 170 | + |
| 171 | +Para obter seu componente nativo, você deve usar `requireNativeComponent`: o mesmo que para componentes personalizados regulares. |
| 172 | + |
| 173 | +```javascript |
| 174 | +import React, { Component } from 'react'; |
| 175 | +import { requireNativeComponent } from 'react-native'; |
| 176 | +import { WebView } from 'react-native-webview'; |
| 177 | + |
| 178 | +export default class CustomWebView extends Component { |
| 179 | + render() { |
| 180 | + return ( |
| 181 | + <WebView {...this.props} nativeConfig={{ component: RCTCustomWebView }} /> |
| 182 | + ); |
| 183 | + } |
| 184 | +} |
| 185 | + |
| 186 | +const RCTCustomWebView = requireNativeComponent('RCTCustomWebView'); |
| 187 | +``` |
| 188 | + |
| 189 | +Se você quiser adicionar props customizadas ao seu componente nativo, você pode usar `nativeConfig.props` na visualização da web. |
| 190 | + |
| 191 | +Para eventos, o manipulador de eventos deve sempre ser definido para uma função. Isso significa que não é seguro usar o manipulador de eventos diretamente de `this.props`, pois o usuário pode não ter fornecido um. A abordagem padrão é criar um manipulador de eventos em sua classe e, em seguida, invocar o manipulador de eventos fornecido em `this.props` se ele existir. |
| 192 | + |
| 193 | +Se você não tiver certeza de como algo deve ser implementado do lado do JS, consulte [WebView.android.tsx](https://github.com/react-native-webview/react-native-webview/blob/master/src/WebView.android.tsx) na fonte React Native WebView. |
| 194 | + |
| 195 | +```javascript |
| 196 | +export default class CustomWebView extends Component { |
| 197 | + _onNavigationCompleted = (event) => { |
| 198 | + const { onNavigationCompleted } = this.props; |
| 199 | + onNavigationCompleted && onNavigationCompleted(event); |
| 200 | + }; |
| 201 | + |
| 202 | + render() { |
| 203 | + return ( |
| 204 | + <WebView |
| 205 | + {...this.props} |
| 206 | + nativeConfig={{ |
| 207 | + component: RCTCustomWebView, |
| 208 | + props: { |
| 209 | + finalUrl: this.props.finalUrl, |
| 210 | + onNavigationCompleted: this._onNavigationCompleted, |
| 211 | + }, |
| 212 | + }} |
| 213 | + /> |
| 214 | + ); |
| 215 | + } |
| 216 | +} |
| 217 | +``` |
| 218 | + |
| 219 | +## Traduções |
| 220 | + |
| 221 | +Esse arquivo está disponível em: |
| 222 | + |
| 223 | +- [Inglês](Custom-Android.md) |
0 commit comments