AndroidX 에서 Activity 와 Fragment 를 사용 하 는 변화 에 대한 상세 한 설명

안 드 로 이 드 X 패키지 에 포 함 된 액 티 비 티/프 라 그 멧 의 API 에 많은 변화 가 있 었 다.안 드 로 이 드 의 개발 효율 을 어떻게 향상 시 키 고 현재 유행 하 는 프로 그래 밍 규칙 과 모델 에 어떻게 적응 하 는 지 살 펴 보 자.
본 논문 에서 묘사 한 모든 기능 은 현재 안정 적 인 AndroidX 패키지 에서 사용 할 수 있 으 며,이들 은 작년 에 모두 안정 적 인 버 전 으로 발표 되 거나 이전 되 었 다.
구조 기 에 레이아웃 ID 입력
AndroidX 에서  AppCompat 1.1.0 과 Fragment 1.1.0(번역자 주:AppCompat 는 Fragment 를 포함 하고 Fragment 는 Activity 를 포함 합 니 다.자세 한 내용 은 Jetpack 주요 구성 요소 의 의존 및 전달 관계 참조)부터 layoutId 를 매개 변수 로 하 는 구조 함 수 를 사용 할 수 있 습 니 다.

class MyActivity : AppCompatActivity(R.layout.my_activity)
class MyFragmentActivity: FragmentActivity(R.layout.my_fragment_activity)
class MyFragment : Fragment(R.layout.my_fragment)
이 방법 은 Activity/Fragment 에서 재 작성 하 는 방법 을 줄 이 고 클래스 를 더욱 가 독성 있 게 할 수 있다.Activity 에 onCreate()를 다시 쓰 지 않 아 도 setContentView()방법 을 호출 할 수 있 습 니 다.또한 Fragment 에 onCreate View 를 수 동 으로 다시 쓰 지 않 아 도 Inflater 를 수 동 으로 호출 하여 보 기 를 확장 할 수 있 습 니 다.
Activity/Fragment 의 유연성 확장
AndroidX 의 새로운 API 를 빌려 Activity/Fragment 에서 일부 기능 을 처리 하 는 경 우 를 줄 일 수 있 습 니 다.보통 Activity/Fragment 를 다시 쓰 는 방법 이 아니 라 일부 기능 을 제공 하 는 대상 을 가 져 와 서 처리 논 리 를 등록 할 수 있 습 니 다.이렇게 하면 귀 하 는 현재 화면 에서 몇 개의 독립 된 유형 을 구성 하여 더욱 높 은 유연성,재 활용 코드 를 얻 을 수 있 고 자신의 추상 적 인 상황 에서 코드 구조 에 대해 더 많은 통 제 를 가 집 니 다.이것 이 두 가지 예시 에서 어떻게 일 하 는 지 봅 시다.
OnBackPressedDispatcher
때때로 사용자 가 이전 단계 로 돌아 가 는 것 을 막 아야 합 니 다.이 경우 Activity 에서 onBackPressed()방법 을 다시 써 야 합 니 다.단,Fragment 를 사용 할 때 되 돌아 오 는 것 을 차단 하 는 직접적인 방법 이 없습니다.Fragment 클래스 에 사용 할 수 있 는 onBackPressed()방법 이 없습니다.여러 개의 Fragment 가 동시에 존재 할 때 의외 의 행동 이 발생 하 는 것 을 방지 하기 위해 서 입 니 다.
단,AndroidX Activity 1.0.0 부터 OnBackPressed Dispatcher 를 사용 하면 이 Activity 코드 의 모든 위치(예 를 들 어 Fragment 에서)에 OnBackPressed Callback 을 등록 할 수 있 습 니 다.

class MyFragment : Fragment() {
 override fun onAttach(context: Context) {
  super.onAttach(context)
  val callback = object : OnBackPressedCallback(true) {
   override fun handleOnBackPressed() {
    // Do something
   }
  }
  requireActivity().onBackPressedDispatcher.addCallback(this, callback)
 }
}
여기에서 다른 두 가지 유용 한 기능 을 발견 할 수 있 습 니 다.
OnBackPressed Callback 의 구조 함수 에 있 는 불 형식의 매개 변 수 는 현재 상태 에 따라 누 른 행동 을 동적 으로 열 거나 닫 는 데 도움 이 됩 니 다.
addCallback()방법의 첫 번 째 매개 변 수 는 LifecycleOwner 입 니 다.수명 주기 감지 대상(예 를 들 어 Fragment)이 적어도 STARTED 상태 에 있 을 때 만 리 셋 을 사용 할 수 있 도록 합 니 다.
OnBackPressed Dispatcher 를 사용 하면 Activity 외 에 리 턴 키 를 처리 하 는 편리 한 방식 을 얻 을 수 있 습 니 다.필요 에 따라 OnBackPressed Callback 을 임의의 위치 에서 정의 하여 재 활용 하거나 응용 프로그램의 구조 에 따라 모든 작업 을 할 수 있 습 니 다.Activity 의 onBackPressed 방법 을 다시 쓸 필요 도 없고 추상 적 인 코드 를 제공 할 필요 도 없습니다.
SavedStateRegistry
Activity 가 종료 되 고 다시 시작 한 후에 이전 상태 로 돌아 가 기 를 원한 다 면 saved state 기능 을 사용 해 야 할 수도 있 습 니 다.과거 에는 Activity 에서 두 가지 방법 을 다시 써 야 했 습 니 다:onSave InstanceState 와 onRestore InstanceState.onCreate 방법 에서 복 구 된 상태 에 접근 할 수 있 습 니 다.마찬가지 로 Fragment 에 서 는 onSave InstanceState 방법 을 사용 할 수 있 습 니 다(또한 onCreate,onCreate View,onActivity Created 방법 에서 상 태 를 회복 할 수 있 습 니 다).
AndroidX 에서  Saved State 1.0.0(AndroidX Activity 와 AndroidX 입 니 다.  Fragment 내부 의존.번역자 주:단독으로 설명 할 필요 가 없습니다)시작 하면 SavedState Registry 에 접근 할 수 있 습 니 다.앞에서 설명 한 OnBackPressed Dispatcher 와 유사 한 메커니즘 을 사용 합 니 다.Activity/Fragment 에서 SavedState Registry 를 가 져 온 다음 SavedState Provider 를 등록 할 수 있 습 니 다.

class MyActivity : AppCompatActivity() {

 companion object {
  private const val MY_SAVED_STATE_KEY = "my_saved_state"
  private const val SOME_VALUE_KEY = "some_value"
 }

 private lateinit var someValue: String

 private val savedStateProvider = SavedStateRegistry.SavedStateProvider {
  Bundle().apply {
   putString(SOME_VALUE_KEY, someValue)
  }
 }

 override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  savedStateRegistry
   .registerSavedStateProvider(MY_SAVED_STATE_KEY, savedStateProvider)
 }

 fun someMethod() {
  someValue = savedStateRegistry
   .consumeRestoredStateForKey(MY_SAVED_STATE_KEY)
   ?.getString(SOME_VALUE_KEY)
   ?: ""
 }
}

보다 시 피 Saved State Registry 는 키 를 데이터 에 사용 하도록 강제 합 니 다.이렇게 하면 데이터 가 같은 Activity/Fragment 의 다른 Saved State Provider 에 연결 되 는 것 을 방지 할 수 있 습 니 다.OnBackPressed Dispatcher 에서 처럼 Saved State Provider 를 다른 클래스 로 추출 하여 필요 한 모든 논 리 를 사용 하여 데이터 와 함께 사용 함으로써 응용 프로그램 에서 선명 한 저장 상태 행 위 를 실현 할 수 있 습 니 다.
또한 프로그램 에서 ViewModel 을 사용한다 면 AndroidX 사용 을 고려 하 십시오.  ViewModel-SavedState 는 ViewModel 의 상 태 를 저장 할 수 있 습 니 다.편 의 를 위해 AndroidX 에서  Activity 1.1.0 과 AndroidXFragment 1.2.0 을 시작 으로 SavedState 를 사용 하 는 SavedStateViewModelFactory 는 ViewModel 을 가 져 오 는 모든 방식 에서 사용 하 는 기본 공장 입 니 다.ViewModelProvider 구조 함수 와 ViewModelProviders.of()방법 을 의뢰 합 니 다.
FragmentFactory
Fragment 에서 가장 많이 언급 되 는 문제 중 하 나 는 매개 변수 가 있 는 구조 함 수 를 사용 할 수 없다 는 것 이다.예 를 들 어 Dagger 2 를 사용 하여 의존 항 주입 을 하면 Inject 주석 Fragment 구조 함 수 를 사용 하고 인 자 를 지정 할 수 없습니다.현재 Fragment Factory 클래스 를 지정 하여 Fragment 생 성 과정 에서 유사 한 문 제 를 줄 일 수 있 습 니 다.Fragment Manager 에 Fragment Factory 를 등록 하면 Fragment 의 기본 방법 을 다시 쓸 수 있 습 니 다.

class MyFragmentFactory : FragmentFactory() {

 override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
  // Call loadFragmentClass() to obtain the Class object
  val fragmentClass = loadFragmentClass(classLoader, className)

  // Now you can use className/fragmentClass to determine your prefered way
  // of instantiating the Fragment object and just do it here.

  // Or just call regular FragmentFactory to instantiate the Fragment using
  // no arguments constructor
  return super.instantiate(classLoader, className)
 }
}

보시 다시 피 이 API 는 매우 통용 되 기 때문에 Fragment 인 스 턴 스 를 만 들 려 는 모든 작업 을 수행 할 수 있 습 니 다.Dagger 2 예제 로 돌아 갑 니 다.예 를 들 어 Fragment Factory Provider를 주입 하고 Fragment 대상 을 가 져 올 수 있 습 니 다.
테스트 프 래 그 먼 트
AndroidX 에서  Fragment 1.1.0 부터 Fragment 테스트 구성 요 소 를 사용 하여 Fragment Scenario 류 를 제공 할 수 있 습 니 다.이 종 류 는 테스트 에서 Fragment 를 예화 하고 단독 테스트 를 할 수 있 습 니 다.

// To launch a Fragment with a user interface:
val scenario = launchFragmentInContainer<FirstFragment>()

// To launch a headless Fragment:
val scenario = launchFragment<FirstFragment>()

// To move the fragment to specific lifecycle state:
scenario.moveToState(CREATED)

// Now you can e.g. perform actions using Espresso:
onView(withId(R.id.refresh)).perform(click())

// To obtain a Fragment instance:
scenario.onFragment { fragment ->
More Kotlin!
반갑습니다.-ktx AndroidX 패키지 에 유용 한 Kotlin 확장 방법 을 많이 제공 하고 정기 적 으로 새로운 방법 을 추 가 했 습 니 다.예 를 들 어 AndroidX Fragment-KTX 1.2.0 에 서 는 세 션 형식의 확장 자 를 사용 하여 Fragment Transaction 의 replace()방법 에 사용 할 수 있 습 니 다.commt()확장 방법 과 결합 하여 사용 하면 다음 코드 를 얻 을 수 있 습 니 다.

// Before
supportFragmentManager
 .beginTransaction()
 .add(R.id.container, MyFragment::class.java, null)
 .commit()

// After
supportFragmentManager.commit {
 replace<MyFragment>(R.id.container)
}

FragmentContainerView
작고 중요 한 일.FrameLayout 를 Fragment 용기 로 사용 하려 면 Fragment Container View 로 바 꿔 야 합 니 다.그것 은 애니메이션 z 축 색인 순서 문제 와 창 삽입 스케줄 링 을 복원 했다.AndroidX Fragment 1.2.0 부터 Fragment Container View 를 사용 할 수 있다.
안 드 로 이 드 X 에서 Activity 와 Fragment 를 사용 하 는 변화 에 대한 자세 한 설명 은 여기까지 입 니 다.더 많은 안 드 로 이 드 X 에서 Activity 와 Fragment 를 사용 하 는 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기