Android

핵심만 골라 배우는 젯팩 컴포즈 Study 5주차

가짜 개발자 2023. 2. 12. 22:28


Chapter 45~49, 52, 53

Chapter 45

내비게이션

  • NavHostController
    • 백 스택을 관리하고 현재 목적지가 어떤 컴포저블인지 추적하는 인스턴스.
    val navController = rememberNavController()
    
  • NavHost는 액티비티의 사용자 레이아웃에 추가되는 컴포넌트. 사용자가 이동할 목적지의 플레이스 홀더 역할.
    • NavHostController 인스턴스를 전달해야 함.
    • 목적지는 route 형태로 선언됨.
    • 목적지 경로에 인수 전달 가능.
NavHost(navController = navController, graph = <시작 경로>) {
        // 내비게이션 그래프 목적지
			composable(route + "/{name}") { backStackEntry ->
				val name = backStackEntry.arguments?.getString("name")
				Purchases(name)
    }
  • navigate() 메서드를 호출해 목적지로 이동.
    • popUpTo() : 뒤로 가기 클릭 시 시작 목적지로 이동.
    • inclusive : 대상도 포함.
    • launchSingleTop : 화면 인스턴스 하나만 생성.
Button(onClick = { navController.navigate(Routes.Customers.route) }) {
        Text(text = "Navigate to Customers")
    }
  • BottomNavigation
    • findStartDestination() 메서드로 시작 목적지 식별 가능.
    • lauchSingleTop, saveState, restoreState 활성화 해야 함.
    • selected로 현재 선택되어 있는 아이템인지 전달해야 함.
    • currentBackStackEntryAsState()로 백스택에 접근해 목적지 경로 프로퍼티에 접근 가능.
navController.graph.findStartDestination()

BottomNavigation {
	val backStackEntry by navController.currentBackStackEntryAsState()
	val currentRoute = backStackEntry?.destination?.route

	<아이템 목록>.BarItems.forEach { navItem ->
		BottomNavigationItem(selected = currentRoute == navItem.route
	}
}

Chapter 46, 47 실습

Chapter 48

제스처

  • 컴포즈에서는 여러 인스턴스를 통해 두 가지 제스처 감지 방법 제공.
    • 제스처 감지 모디파이어 - 내장 시작 효과를 이용한 제스처 식별 기능 제공.
      • 탭, 프레스, 롱 프레스, 더블 탭 등을 구분 못함.
    SomeComposable(modifier = Modifier.clickable {})
    
    • PointerInputScope 인터페이스가 제공하는 함수 이용.
      • detectTapGestures()
    SomeComposable(modifier = Modifier.pointerInput(Unit) {
            detectTapGestures(onPress = {}, onDoubleTap = {}, onLongPress = {}, onTap = {})
        })
    
  • 드레그 제스처 감지.
    • draggable() 호출할 때는 수직, 수평 제스처 감지 여부를 전달.
    • 움직임이 시작된 위치로부터의 오프셋을 상태로 저장.
    • 이 인스턴스는 rememberDraggableState() 함수 호출해 만듬.
    var xOffSet by remember { mutableStateOf(0f) }
    
        Box(modifier = Modifier
            .offset { IntOffset(xOffSet.roundToInt(), 0) }
            .draggable(
                orientation = Orientation.Horizontal,
                state = rememberDraggableState { distance -> xOffSet += distance }
            ))
    
    • PointerInputScope를 이용해 드래그 제스처 감지.
      • detectDragGestures 함수로 수직 및 수평 동시 조작 가능.
      .pointerInput(Unit) {
                  detectDragGestures { _, distance -> 
                      xOffSet += distance.x
                      yOffSet += distance.y
                  }
              })
      
    • scrollable() 모디파이어를 이용해 스크롤 제스처 적용.
      • scrollable 상태는 rememberScrollableState() 함수로 관리.
    .scrollable(
                orientation = Orientation.Vertical,
                state = rememberScrollableState { distance ->
                    offset += distance
                    distance
                }
            )
    
    • 확대, 축소, 회전, 변환 제스처 감지.
      • transformable() 모디파이어 통해 감지.
      • 이 상태 인스턴스는 rememberTransfromableState() 함수를 호출해 만들 수 있음.
        • scaleCahnge, offsetChange, rotationChange 파라미터를 전달해야 함.
        • 그래픽 레이어에 접근해 sacle 상태를 업데이트 함.
      		var scale by remember { mutableStateOf(1f) }
      		var angle by remember { mutableStateOf(0f) }
      		var offset by remember { mutableStateOf(Offset.Zero)}
      
          val state = rememberTransformableState { scaleChange, offsetChange, rotationChange ->
              scale += scaleChange
      				angle += rotationChange
      				offset += offsetChange
          }
      
      		SomeComposable(modifier = Modifier
      		.graphicLayer(scaleX = scale, scaleY = scale, rotationZ = angle, translationX = offset.x, translationY = offset.y)
      		.transformable(state = state) { }
      
    Chapter 49
    • 한 앵커에서 다른 앵커로 옮김.
      • 앵커 : 스와이프 축을 따라 화면에 존재하는 고정된 위치.
      • swappable() 모디파이어 호출 시 지정할 수 있는 주요 파라미터
        • state
        • anchors
        • orientation
        • enabled
        • reverseDirection
        • thresholds
        • resistance
        • velocityThreshold
      Box(modifier = Modifier
              .swipeable(state = 상태, anchors = 앵커, thresholds = {_,_->FractionalThreshold(값)}, orientation = 수평,수직))
      
      val swipeableState = remeberSwipeableState("On")
      val anchors = mapOf(0f to "On", 150f to "Off", 300f to "Locked")
      Text(swipeableState.currentValue)
      
    • offset() 모디파이어로 swappable 상태의 오프셋값을 이용해 제스처에 따라 컴포넌트 이동.
    • 임계점 선언 방법
      • FractionalThreshold()
      • FixedThreshold()
    { _, _ -> FractionalThreshold(0.5f) }
    { _, _ -> FixedThreshold(20.dp) }
    
    val swipeableState = rememberSwipeableState(initialValue = "On")
        val anchors = mapOf(0f to "On", 150f to "Off", 300f to "Locked")
    
        Text(swipeableState.currentValue, modifier = Modifier.offset {
            IntOffset(swipeableState.offset.value.roundToInt(), 0)
        })
    
  • 스와이프 제스처

Chapter 52, Chapter 53

컴포즈 테마 적용

  • M2와 M3의 차이
    • 색상 시스템.
      • 색상 매개변수의 수가 많아지고 이름도 다르며 M3 구성요소에 다른 방식으로 매핑됨.
      • M2는 Colors 클래스, M3는 ColorScheme 클래스.
    • isLight
      • M3 ColorScheme 클래스에는 isLight 매개변수가 없음.
      • 테마 수준에서 모델링 해야 함.
    • 동적 색상 지원.
      • Android 12 이상에서 dynamicDarkColorScheme(), dynamicLightColorScheme() 함수 호출해 기기 배경화면 색상을 활용 가능.
      • 현재의 로컬 컨텍스트를 파라미터로 전달.
    • 팔레트를 대신한 색싱 스킴 이용 지원. lightColorScheme(), darkColorScheme() 빌더 함수 호출.
    • 타이포그래피와 테마 색상 선언은 거의 비슷.
    • 색상 슬롯과 타이포그래피 타입은 그 이름이 상당히 다름.
반응형