이전 API로 구현 만들기

이 과정에서는 최신 API를 반영하지만 이전 기기도 지원하는 구현을 만드는 방법을 설명합니다.

대체 솔루션 파악

이전 버전과 호환되는 방식으로 최신 UI 기능을 사용하는 데 있어 가장 어려운 작업은 이전 플랫폼 버전을 위한 이전(대체) 솔루션을 파악하고 구현하는 것입니다. 대부분의 경우 이전 UI 프레임워크 기능을 사용하여 이러한 최신 UI 구성요소의 목적을 달성할 수 있습니다. 예:

  • 작업 모음은 이미지 버튼이 포함된 수평 LinearLayout을 사용하여 맞춤 제목 표시줄 또는 활동 레이아웃의 뷰로 구현할 수 있습니다. 오버플로 작업은 기기 메뉴 버튼 아래에 표시될 수 있습니다.

  • 작업 모음 탭은 버튼이 포함된 수평 LinearLayout을 사용하거나 TabWidget UI 요소를 사용하여 구현할 수 있습니다.

  • NumberPickerSwitch 위젯은 각각 SpinnerToggleButton 위젯을 사용하여 구현할 수 있습니다.

  • ListPopupWindowPopupMenu 위젯은 PopupWindow 위젯을 사용하여 구현할 수 있습니다.

일반적으로 최신 UI 구성요소를 이전 기기에 백포트하는 데 있어 만능 솔루션은 없습니다. 사용자 환경에 주의하세요. 이전 기기에서는 사용자가 최신 디자인 패턴과 UI 구성요소에 익숙하지 않을 수 있습니다. 익숙한 요소를 사용하여 동일한 기능을 제공하는 방법을 생각해보세요. 최신 UI 구성요소가 애플리케이션 생태계(예: 작업 모음)에서 눈에 잘 띄는 경우 또는 상호작용 모델이 매우 단순하고 직관적(예: ViewPager를 사용한 스와이프 뷰)일 때 등 대부분의 경우 이 문제는 별로 중요하지 않습니다.

이전 API를 사용하여 탭 구현

작업 모음 탭의 이전 구현을 만들려면 TabWidgetTabHost를 사용하면 됩니다. 그러나 수평으로 배치된 Button 위젯을 사용할 수도 있습니다. TabHelperEclairCompatTabEclair라는 클래스에서 구현하세요. 이 구현이 Android 2.0(Eclair) 이전에 도입된 API를 사용하기 때문입니다.

탭의 Eclair 구현 클래스 다이어그램

그림 1. 탭의 Eclair 구현 클래스 다이어그램

CompatTabEclair 구현은 탭 텍스트 및 아이콘과 같은 탭 속성을 인스턴스 변수에 저장합니다. 이 저장소 처리에 사용할 수 있는 ActionBar.Tab 객체가 없기 때문입니다.

Kotlin

class CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :
        CompatTab(tag) {

    // Store these properties in the instance,
    // as there is no ActionBar.Tab object.
    private var text: CharSequence? = null
    ...

    override fun setText(resId: Int): CompatTab {
        // Our older implementation simply stores this
        // information in the object instance.
        text = activity.resources.getText(resId)
        return this
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

Java

public class CompatTabEclair extends CompatTab {
    // Store these properties in the instance,
    // as there is no ActionBar.Tab object.
    private CharSequence text;
    ...

    public CompatTab setText(int resId) {
        // Our older implementation simply stores this
        // information in the object instance.
        text = activity.getResources().getText(resId);
        return this;
    }

    ...
    // Do the same for other properties (icon, callback, etc.)
}

TabHelperEclair 구현은 TabHost 위젯의 메서드를 사용하여 TabHost.TabSpec 객체와 탭 표시기를 만듭니다.

Kotlin

class TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) {

    private var tabHost: TabHost? = null
    ...

    override fun setUp() {
        // Our activity layout for pre-Honeycomb devices
        // must contain a TabHost.
        tabHost = tabHost ?: mActivity.findViewById<TabHost>(android.R.id.tabhost).apply {
            setup()
        }
    }

    override fun addTab(tab: CompatTab) {
        ...
        tabHost?.newTabSpec(tab.tag)?.run {
            setIndicator(tab.getText()) // And optional icon
            ...
            tabHost?.addTab(this)
        }
    }
    // The other important method, newTab() is part of
    // the base implementation.
}

Java

public class TabHelperEclair extends TabHelper {
    private TabHost tabHost;
    ...

    protected void setUp() {
        if (tabHost == null) {
            // Our activity layout for pre-Honeycomb devices
            // must contain a TabHost.
            tabHost = (TabHost) mActivity.findViewById(
                    android.R.id.tabhost);
            tabHost.setup();
        }
    }

    public void addTab(CompatTab tab) {
        ...
        TabSpec spec = tabHost
                .newTabSpec(tag)
                .setIndicator(tab.getText()); // And optional icon
        ...
        tabHost.addTab(spec);
    }

    // The other important method, newTab() is part of
    // the base implementation.
}

이제 CompatTabTabHelper가 두 가지 구현되었습니다. 하나는 Android 3.0 이상을 실행하는 기기에서 작동하고 새로운 API를 사용하는 것이고 다른 하나는 Android 2.0 이상을 실행하는 기기에서 작동하고 이전 API를 사용하는 것입니다. 다음 과정에서는 애플리케이션에서 이러한 구현을 사용하는 방법을 설명합니다.