Android Native UI Components

박은정·2022년 7월 25일
0

리액트네이티브

목록 보기
3/24
post-thumbnail

Android Native UI Components

react native 공식문서의 내용을 번역하며 공부했습니다.
제가 이해하기 편하도록 수정한 부분도 있어서 다를 겁니다....

최신 앱에서 사용할 수 있는 수 많은 네이티브 UI 위젯이 있습니다. 그 중 일부는 플랫폼의 일부이고, 다른 일부는 third-party 라이브러리로 사용할 수 있으며, 더 많은 네이티브 UI 위젯이 사용자의 포트폴리오에서 사용될 수도 있습니다.
리액트네이티브에는 ScrollView 및 TextInput과 같은 가장 중요한 플랫폼 컴포넌트가 몇 개 있지만 전부는 아니며, 이전 앱에서 직접 작성한 컴포넌트도 아닙니다.
다행히도 이러한 기존의 컴포넌트를 정리해서 나의 리액트네이티브 애플리케이션과 완벽하게 통합할 수 있습니다.

네이티브 모듈 가이드와 마찬가지로 이 가이드도 Android SDK 프로그래밍에 어느정도 익숙하다고 가정하는 고급 가이드입니다. 이 가이드에서는 기본 UI 컴포넌트를 구축하는 방법을 보여주며 핵심적인 기본 라이브러리인 리액트네이티브에서 사용할 수 있는 기존의 ImageView 컴포넌트의 자식요소를 구현하는 과정을 안내합니다. 이 가이드에서는 네이티브 UI 컴포넌트를 빌드하는 방법을 보여드리며, 핵심 React Native 라이브러리에서 사용할 수 있는 기존 ImageView 컴포넌트의 하위 집합을 구현하는 과정을 안내합니다.

ImageView example

이 예시에서는 자바스크립트에서 ImageViews를 사용할 수 있도록 구현 요구 사항을 살펴보겠습니다.

네이티브의 view는 ViewManager 또는 일반적인 SimpleViewManager를 확장해서 만들고 조작합니다. SimpleViewManager는 배경색, 불투명도, flexbox 레이아웃과 같은 일반적인 속성을 적용하기 때문에 편리합니다.

이러한 하위클래스는 기본적으로 단일 클래스이며 브릿지에 의해 각각 하나의 인스턴스만 생성됩니다. 이러한 하위클래스들은 view의 속성을 설정하고 업데이트할 수 있는 NativeViewHierarchyManager에 네이티브 view들을 전달합니다.

이렇게 전달하기 위해서는 아래 5단계 과정이 필요합니다.

  1. 하위클래스에 ViewManager 생성: Create the ViewManager subclass
  2. createViewInstance() 메서드 실행: Implement the createViewInstance method
  3. @ReactProp (혹은 @ReactPropGroup) 를 사용해서 view의 속성 설정기 표시: Expose view property setters using @ReactProp (or @ReactPropGroup) annotation
  4. application패키지의 createViewManagers에 manager등록: Register the manager in createViewManagers of the applications package.
  5. 자바스크립트에서 모듈 구현: Implement the JavaScript module

하나씩 살펴보자면,


하위클래스에 ViewManager 생성

이 예시에서는 ReactImageView유형의 SimpleViewManager를 확장하는 view manager 클래스 ReactImageManager를 생성합니다. ReactImageView는 manager가 관리하는 객체타입으로, 커스텀 네이티브 view가 됩니다. getName에서 반환한 이름은 자바스크립트에서 native view타입을 참조하는데 사용됩니다.

public class ReactImageManager extends SimpleViewManager<ReactImageView> {

  public static final String REACT_CLASS = "RCTImageView";
  ReactApplicationContext mCallerContext;

  public ReactImageManager(ReactApplicationContext reactContext) {
    mCallerContext = reactContext;
  }

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

createViewInstance() 메서드 실행

view들은 createViewInstance메서드에서 생성됩니다. 그리고 그 view는 기본상태로 초기화되어야 합니다. 그리고 모든 속성들은 updateView의 call에 대해 설정됩니다. properties will be set via a follow up call to updateView.

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

@ReactProp (혹은 @ReactPropGroup) 를 사용해서 view의 속성 설정기 표시

자바스크립트에 반영될 속성은 @ReactpProp 또는 @ReactPropGroup으로 주석이 달린 setter메서드로 표시되어야 합니다. setter 메서드는 업데이트될 뷰를 첫번째 인자로, 속성값을 두번째 인자로 사용해야 합니다.
setter는 값을 반환하지 않고 공개되어야 합니다. 즉, 반환되는 타입은 자바/코틀린에서 void여야 합니다.
자바스크립트로 전송되는 속성의 타입은 setter의 인자의 타입에 의해 자동으로 결정됩니다. 현재 지원되는 값의 타입은 boolean, int, float, double, String, Boolean, Integer, ReadableArray, ReadableMap입니다. 코틀린에 해당하는 유형은 Boolean, Int, Float, Double, String, ReadableArray, ReadableMap입니다.

주석 @ReactProp에는 String타입의 필수 인자이름이 하나 있습니다. setter 메서드에 연결된 @ReactProp 주석에 할당된 이름은 자바스크립트 측의 속성을 참조하는데 사용됩니다.

이름을 제외하고 @ReactPro 주석에는 defaultBoolean, defaultInt, defaultFloat이라는 인수를 선택적으로 사용할 수 있습니다. 이러한 인수는 해당하는 유형이어야 하며, setter가 참조하는 속성이 컴포넌트에서 제거된 경우 제공된 값이 setter메서드에 전달됩니다.
"default"값은 원시 유형에 대해서만 제공되는 점을 유의해야합니다. setter가 복잡한 유형일 때 null은 해당 속성이 제거될 경우 기본 값으로 제공됩니다.

@ReactPropGroup으로 주석을 단 메서드에 대한 setter의 선언 요구사항은 @ReactProp와 다릅니다. 자세한 내용은 @ReactPropGroup 주석 클래스 문서를 참조하세요.

중요! 리액트JS에서 컴포넌트를 업데이트하면 setter메서드가 호출됩니다. 컴포넌트를 업데이트하는 방법 중 하나는 이전에 설정한 속성을 제거하는 것입니다. 이러한 경우, setter메서드도 호출되서 ViewManager에게 속성이 변경되었음을 알리는데 이때 "default"값이 제공됩니다. 원시유형의 경우 "default"값은 defaultBoolean, defaultFloat 등의 null로 설정된 값인 @ReactProp 주석의 인자를 사용할 수 있습니다.

 @ReactProp(name = "src")
  public void setSrc(ReactImageView view, @Nullable ReadableArray sources) {
    view.setSource(sources);
  }

  @ReactProp(name = "borderRadius", defaultFloat = 0f)
  public void setBorderRadius(ReactImageView view, float borderRadius) {
    view.setBorderRadius(borderRadius);
  }

  @ReactProp(name = ViewProps.RESIZE_MODE)
  public void setResizeMode(ReactImageView view, @Nullable String resizeMode) {
    view.setScaleType(ImageResizeMode.toScaleType(resizeMode));
  }

application패키지의 createViewManagers에 manager등록

마지막단계는 ViewManager를 애플리케이션에 등록하는 것입니다. 이 작업은 애플리케이션 패키지 구성원 함수 createViewManagers를 통해 NativeModules와 유사한 방식으로 수행됩니다.

 @Override
  public List<ViewManager> createViewManagers(
                            ReactApplicationContext reactContext) {
    return Arrays.<ViewManager>asList(
      new ReactImageManager(reactContext)
    );
  }

자바스크립트에서 모듈 구현

진짜진짜 마지막 단계는... 새로운 view의 사용자를 위해 자바/코틀린과 자바스크립트 사이의 인터페이스 게층을 정의하는 자바스크립트 모듈을 만드는 것입니다. 이 모듈의 컴포넌트 인터페이스를 Flow, 타입스크립트 또는 일반적인 old comments를 사용해서 문서화하는 것이 좋습니다.

import { requireNativeComponent } from 'react-native';

/**
 * Composes `View`.
 *
 * - src: string
 * - borderRadius: number
 * - resizeMode: 'cover' | 'contain' | 'stretch'
 */
module.exports = requireNativeComponent('RCTImageView');

requireNativeComponent 메서드는 네이티브 View의 이름을 사용합니다. 컴포넌트가 사용자 지정 이벤트 처리와 같은 정교한 작업을 수행해야 하는 경우 네이티브 컴포넌트를 다른 리액트 컴포넌트로 감싸야 합니다. 이러한 작업은 다음에 알아보겠습니다.

profile
새로운 것을 도전하고 노력한다

0개의 댓글