화면 위에 항상 떠있는 FAB를 만들어보도록 하겠습니다. 

 

www.youtube.com/watch?v=umCX1-Tq25k

* 아이콘 색 변경시 android가 아닌 app:tint="@android:color/white"를 쓰자

 

- to_bottom_anim.xml에서 scale(from,to)을 잡아주지 않으면 접힐때 아이콘 크기가 1로 다시 설정 됨

 

- 다이나믹하게 생성되는 버튼의 clickable을 설정 해주지 않으면 visibility가 false여도 클릭이 된다.

 

- BindingAdapter를 추가하여 isclick 변수에 따라 visibility와 clickable 설정하도록 했다.

 

Activity 등에 클래스 데이터를 전달하기위해 Serialization, Deserialization하는 코드로 화면 간 데이터는 최소화하여 전달하도록 권장하고 있으므로 그냥 방법만 알아두자

 

@Entity(tableName = "card_table")
data class Card(
        @PrimaryKey(autoGenerate = true) val id: Long?,
        @ColumnInfo(name = "card_name") val cardName: String?,
        @ColumnInfo(name = "card_number") val cardNumber: String?,
        @ColumnInfo(name = "limit_amount") val limitAmount: Long = 0,
        @ColumnInfo(name = "description") val description: String?
): Parcelable {
    constructor(name: String, number: String, limit: Long, desc: String): this(null, name, number, limit, desc)

    constructor(parcel: Parcel) : this(null, parcel.readString(), parcel.readString(), parcel.readLong(), parcel.readString())

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(cardName)
        parcel.writeString(cardNumber)
        parcel.writeLong(limitAmount)
        parcel.writeString(description)
    }

    companion object CREATOR : Parcelable.Creator<Card> {
        override fun createFromParcel(parcel: Parcel): Card {
            return Card(parcel)
        }

        override fun newArray(size: Int): Array<Card?> {
            return arrayOfNulls(size)
        }
    }
}

 

위와 같이 boilerplate 코드와 override 함수들로인해 data class의 코드가 많이 복잡해지고 attribute의 non-null 속성도 보장하지 못하게 된다.

 

 

PanResponder API를 통해 사용자의 이벤트(스와이프, 탭, 핀치, 스크롤링 등)에 따라 앱 상태를 조작할 수 있습니다. 

 

요번에는 panresponder를 이용하여 사용자의 드래그 앤 드랍 이벤트를 처리할 수 있는 예제를 만들어 보겠습니다. 

 

panresponder.js 생성

1. 우선 여느 component와 같이 'react-native'에서 Dimensions, PanResponder을 import 합니다. 

 

2. Dimensions를 통해 화면의 너비, 높이 값을 가져옵니다. 
const { width, height } = Dimensions.get('window')

 

3. 사용자의 이벤트를 받기 전 view의 위치를 저장하는 oPosition 객체를 생성하고 화면의 중앙에 위치할 수 있도록 초기 값을 셋팅해줍니다. oPosition 객체는 사용자의 release 이벤트가 발생하면 해당 위치의 값으로 설정 됩니다.

* 이벤트 받을 객체(크기 200)의 왼쪽 윗 부분을 기준 점으로 지정

oPosition: {
        x: (width / 2) - 100,
        y: (height / 2) - 100,
      }

4. 사용자의 move 이벤트가 발생 시 현재 위치를 저장하는 position 객체를 생성하고 3과 같이 화면 중앙 값으로 초기 값을 저장합니다.

 

5. 내가 정의한 onPanResponderMove와 onPanResponderRelease 메서드를 PandResponder의 move, release 이벤트 함수로 사용할 수 있도록 정의하고 PanResponder.create에서 PandResponder의 이벤트 함수들과 사용자 정의 함수를 연결해줍니다.

* PanResponder를 생성 시 onStartShouldSetPanResponder에 true 값은 요소를 터치 할 때 지정한 move, release 함수가 활성화 됨을 의미 합니다.

 

6. _handlePanResponderMove (onPanResponderMove)의 로직을 만들어 줍니다.

객체가 사용자의 이동 이벤트를 받으면 evt와 gesture 파라미터를 받게 되는데 evt의 경우 객체내 터치 좌표, 연속된 이벤트의 배열 등 사용자 이벤트 자체 정보를 포함하는 반면 gesture의 경우 이벤트의 움직임과 관련 정보를 포함하고 있어 요번 예제에서는 gesture 정보를 사용합니다. 

move 이벤트의 원점 - 이동된 점으로 이동한 거리를 계산하고 

let ydiff = gestureState.y0 - gestureState.moveY 

position의 y 값을 이동전 y 값 - 이동 값을 통해 move 이벤트의 이동 위치로 저장합니다. 

y: this.state.oPosition.y - ydiff
   

7, _handlePanResponderRelease (onPanResponderRelease)에 release 이벤트가 발생 시 oPosition을 사용자가 객체를 드랍 했을 때의 위치로 저장하고 새로 이벤트를 받을 수 있도록 합니다. 

<View {...this._panResponder.panHandlers}
	style={[styles.box, { marginLeft: this.state.position.x, marginTop: this.state.position.y }
    ]} />

panResponder의 panHandlers를 지정하여 사용자 이벤트를 받을 수 있는 객체로 지정하고 객체의 왼쪽 위 좌표를 기준으로 margin 값을 주어 이벤트 대상 객체의 위치를 지정합니다.

 

빨간 박스의 View를 눌러 위치를 이동시키면 좌표 정보가 상단에 표시되고 마우스를 떼면 해당 위치에 박스가 위치하는 것을 볼 수 있음

 

이렇게 panresponder를 이용하여 사용자 이벤트를 재정의해서 등록하여 이벤트를 활성화 시키고 특정 view에 연결하는 방법을 알아 보았습니다. 

'React native' 카테고리의 다른 글

크로스 플렛폼 - NetInfo API  (0) 2020.01.19
크로스 플렛폼 - Geolocation  (0) 2020.01.19
크로스 플랫폼 - Clipboard API  (0) 2020.01.19
크로스 플랫폼 - AsyncStorage  (0) 2020.01.12
크로스 플랫폼 - AppState API  (0) 2020.01.12

+ Recent posts