| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- DiffUtil
- 리사이클러뷰
- flutter
- 내부 단편화
- appcompatacitivity
- appcompatactivity
- http발전과정
- http 역사
- 플로이드워셜
- 자이고트
- recyclerview
- 운영체제
- AAC
- 리사이클러뷰풀
- NestedScrollView
- 안드로이드
- 절대 주소
- 데코레이터 패턴
- GetX
- viewModelScope
- 뷰홀더
- 프로세스
- Dispatchers
- apk 빌드 과정
- Kotlin
- 상태관리
- 디자인 패턴
- AsyncListDiffer
- Android
- 물리 메모리
- Today
- Total
hong's android
[안드로이드] Appcompatactivity 본문
Support Library, Android x
두 라이브러리의 공통점은 하위 api 버전에 대해서도 호환성을 유지시켜준다.
Support Library는 v4, v7,v13 은 api 버전이 해당 숫자 이상이 되어야 한다는 의미이며, 대부분 min 19를 사용하면서 해당 버전을 명시하는 것은 의미가 없어졌다. 버전이 혼잡해질수록 호환성 문제가 발생했고 또한 Support library는 단일 라이브러리이므로 불 필요한 라이브러리도 포함되어 dex파일의 크기가 증가한다.
다양한 버전을 통합하고 자체적으로 관리하는 새로운 네임스페이스 Api 레벨 28부터 androidx를 구성.
Appacompatactivity 란?
특정 버전 이하 기기에서 뷰 호환성을 유지한다.
어떻게 Appcompatactivity는 뷰 호환성을 유지할까?
AppCompatDelegate의 구체 클래스에서 AppCompateViewInflater를 생성한다.
// AppCompatDelegateImpl.java
class AppCompatDelegateImpl extends AppCompatDelegate
implements MenuBuilder.Callback, LayoutInflater.Factory2 {
@Override
public View createView(View parent, final String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
if (mAppCompatViewInflater == null) {
TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
// ViewInflater를 사용할 Class명을 취득
String viewInflaterClassName =
a.getString(R.styleable.AppCompatTheme_viewInflaterClass);
// Theme에서 정의된 ViewInflater가 있다면 해당 View Inflater가 사용되며
// 미정의한 경우 기본으로 AppCompatViewInflater를 사용
if (viewInflaterClassName == null) {
mAppCompatViewInflater = new AppCompatViewInflater();
} else {
try {
Class<?> viewInflaterClass = Class.forName(viewInflaterClassName);
mAppCompatViewInflater =
(AppCompatViewInflater) viewInflaterClass.getDeclaredConstructor()
.newInstance();
} catch (Throwable t) {
Log.i(TAG, "Failed to instantiate custom view inflater "
+ viewInflaterClassName + ". Falling back to default.", t);
mAppCompatViewInflater = new AppCompatViewInflater();
}
}
}
...
return mAppCompatViewInflater.createView(parent, name, context, attrs, inheritContext,
IS_PRE_LOLLIPOP, /* Only read android:theme pre-L (L+ handles this anyway) */
true, /* Read read app:theme as a fallback at all times for legacy reasons */
VectorEnabledTintResources.shouldBeUsed() /* Only tint wrap the context if enabled */
);
}
}
AppCompateViewInflater 내부에선 뷰 호환성이 필요한 뷰들을 AppCompat View로 대체된다.
Theme에서 정의된 ViewInflater가 있다면 해당 View Inflater가 사용되며, 해당 인플레이터 없다면 appcompatinflater가 사용된다. AppCompateViewInflater는 뷰의 이름에 따라 appcompat view로 대체한다.
<resources>
<style name="Base.V14.Theme.MaterialComponents" parent="Base.V14.Theme.MaterialComponents.Bridge">
<item name="viewInflaterClass">com.google.android.material.theme.MaterialComponentsViewInflater</item>
...
</style>
<style name="Base.V14.Theme.MaterialComponents.Light" parent="Base.V14.Theme.MaterialComponents.Light.Bridge">
<item name="viewInflaterClass">com.google.android.material.theme.MaterialComponentsViewInflater</item>
...
</style>
</resources>
<resources>
<style name="Base.V14.Theme.MaterialComponents.Dialog" parent="Base.V14.Theme.MaterialComponents.Dialog.Bridge">
<item name="viewInflaterClass">com.google.android.material.theme.MaterialComponentsViewInflater</item>
...
</style>
<style name="Base.V14.Theme.MaterialComponents.Light.Dialog" parent="Base.V14.Theme.MaterialComponents.Light.Dialog.Bridge">
<item name="viewInflaterClass">com.google.android.material.theme.MaterialComponentsViewInflater</item>
...
</style>
</resources>
만약 material 테마를 사용할 경우는 Appcompatinflater를 상속한 MaterialComponentsViewInflater에서 뷰의 이름에 따라 해당 materal 테마의 뷰로 변경된다.
Custom LayoutInflater
기존 코드를 변경하지않고 커스텀 LayoutInflater를 이용해서 기존의 뷰들을 원하는 커스텀 뷰로 변경 가능
class CustomViewInflater: AppCompatViewInflater() {
override fun createView(context: Context?, name: String?, attrs: AttributeSet?): View? {
return when(name) {
"RecyclerView" -> CustomRecyclerView(context, attrs)
//...
else -> super.createView(context, name, attrs)
}
}
override fun createTextView(context: Context?, attrs: AttributeSet?): AppCompatTextView {
return CustomTextView(context, attrs)
}
}
<style name="AppTheme" parent="Base.AppTheme">
<item name="viewInflaterClass">my.app.package.CustomViewInflater</item>
</style>
Reference.
1. https://medium.com/@hxlich/when-to-use-appcompat-views-to-write-custom-views-f5ca00df8d82
2. https://pluu.github.io/blog/android/2021/02/27/compatibility-sdk-library/
'Android > Android' 카테고리의 다른 글
| [안드로이드] Lru Cache (0) | 2023.02.21 |
|---|---|
| [안드로이드] RecyclerView (0) | 2023.02.14 |
| [안드로이드] apk 빌드 과정 (+ DVM,ART) (0) | 2023.02.11 |
| [안드로이드] setcontentview(), Layoutinflater (0) | 2023.01.31 |
| [안드로이드] Pendingintent (0) | 2023.01.31 |