콘텐츠로 건너뛰기

자주 방문한 페이지

최근 방문한 페이지

navigation

적응형 UI 흐름 구현

현재 애플리케이션이 표시하는 레이아웃에 따라 UI 흐름이 다를 수 있습니다. 예를 들어 애플리케이션이 이중 창 모드일 경우 왼쪽 창에서 항목을 클릭하면 오른쪽 창에 콘텐츠가 표시됩니다. 단일 창 모드일 경우, 콘텐츠는 (다른 액티비티로) 단독 표시됩니다.

현재 레이아웃 확인

각 레이아웃 구현이 약간 다르므로 처음 수행해야 하는 작업은 사용자가 현재 보고 있는 레이아웃을 확인하는 것입니다. 예를 들어 사용자가 "단일 창" 모드인지 "이중 창" 모드인지 알고 싶을 수 있습니다. 특정 뷰가 존재하고 보이는 상태라면 쿼리로 이 작업을 수행할 수 있습니다.

public class NewsReaderActivity extends FragmentActivity {
    boolean mIsDualPane;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_layout);

        View articleView = findViewById(R.id.article);
        mIsDualPane = articleView != null &&
                        articleView.getVisibility() == View.VISIBLE;
    }
}

이 코드가 "기사" 창을 이용할 수 있는지 여부에 대해 쿼리한다는 점에 유의하세요. 특정 레이아웃 쿼리를 하드코딩하는 것보다 더 유연합니다.

다양한 구성 요소의 존재에 적응할 수 있는 방법을 보여주는 다른 예시로는 구성 요소에서 작업을 수행하기 전에 이용 가능한지 확인하는 것이 있습니다. 예를 들어, News Reader 샘플 앱에는 메뉴를 여는 버튼이 있지만 이 버튼은 Android 3.0 이하 버전에서 실행될 때만 나타납니다(API 레벨 11 이상에서는 버튼 기능을 ActionBar가 대신하기 때문임). 이 버튼의 이벤트 리스너를 추가하려면 다음과 같이 수행할 수 있습니다.

Button catButton = (Button) findViewById(R.id.categorybutton);
OnClickListener listener = /* create your listener here */;
if (catButton != null) {
    catButton.setOnClickListener(listener);
}

현재 레이아웃에 따른 반응

현재 레이아웃에 따라 일부 동작은 다른 결과가 나올 수 있습니다. 예를 들어 News Reader 샘플에서 헤드라인 목록에서 헤드라인을 클릭하면 UI가 이중 창 모드일 경우 오른쪽에 기사가 열리고 UI가 단일 창 모드일 경우 별도 액티비티로 시작됩니다.

@Override
public void onHeadlineSelected(int index) {
    mArtIndex = index;
    if (mIsDualPane) {
        /* display article on the right pane */
        mArticleFragment.displayArticle(mCurrentCat.getArticle(index));
    } else {
        /* start a separate activity */
        Intent intent = new Intent(this, ArticleActivity.class);
        intent.putExtra("catIndex", mCatIndex);
        intent.putExtra("artIndex", index);
        startActivity(intent);
    }
}

마찬가지로 앱이 이중 창 모드일 경우 내비게이션에 탭이 있는 작업 모음을 설정해야 하지만 앱이 단일 차창 모드일 경우 스피너 위젯이 있는 내비게이션을 설정해야 합니다. 그러므로 코드에서도 어느 경우가 적절한지 확인해야 합니다.

final String CATEGORIES[] = { "Top Stories", "Politics", "Economy", "Technology" };

public void onCreate(Bundle savedInstanceState) {
    ....
    if (mIsDualPane) {
        /* use tabs for navigation */
        actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS);
        int i;
        for (i = 0; i < CATEGORIES.length; i++) {
            actionBar.addTab(actionBar.newTab().setText(
                CATEGORIES[i]).setTabListener(handler));
        }
        actionBar.setSelectedNavigationItem(selTab);
    }
    else {
        /* use list navigation (spinner) */
        actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST);
        SpinnerAdapter adap = new ArrayAdapter(this,
                R.layout.headline_item, CATEGORIES);
        actionBar.setListNavigationCallbacks(adap, handler);
    }
}

다른 액티비티에서 프래그먼트 재사용

여러 화면 디자인에서 반복적으로 나타나는 패턴은 일부 화면 구성에서는 창으로 구현되고 다른 구성에서는 별도 액티비티로 구현되는 인터페이스의 일부가 포함됩니다. 예를 들어 News Reader 샘플에서 뉴스 기사 텍스트는 큰 화면에서 오른쪽에 표시되지만 작은 화면에서 별도 액티비티로 나타납니다.

이 경우, 일반적으로 여러 액티비티에서 같은 Fragment 서브클래스를 다시 사용하여 코드 중복을 피할 수 있습니다. 예를 들어 ArticleFragment는 이중 창 레이아웃에 사용합니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal">
    <fragment android:id="@+id/headlines"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.HeadlinesFragment"
              android:layout_width="400dp"
              android:layout_marginRight="10dp"/>
    <fragment android:id="@+id/article"
              android:layout_height="fill_parent"
              android:name="com.example.android.newsreader.ArticleFragment"
              android:layout_width="fill_parent" />
</LinearLayout>

작은 화면의 액티비티 레이아웃에서 (레이아웃 없이) 재사용됩니다(ArticleActivity).

ArticleFragment frag = new ArticleFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, frag).commit();

당연히 XML 레이아웃에서 프래그먼트를 선언하는 것과 같은 효과를 내지만, 이 경우 기사 프래그먼트가 이 액티비티의 유일한 구성 요소이므로 XML 레이아웃은 불필요한 작업입니다.

프래그먼트를 디자인할 때 유의해야 할 매우 중요한 한 가지는 특정 액티비티에 강한 커플링을 생성하지 않는 것입니다. 일반적으로 프래그먼트가 호스트 액티비티와 상호작용하는 데 필요한 모든 방법을 추상화하는 인터페이스를 정의하고 호스트 액티비티가 그 인터페이스를 구현함으로써 가능해집니다.

예를 들어, News Reader 앱의 HeadlinesFragment가 바로 그런 방식을 사용합니다.

public class HeadlinesFragment extends ListFragment {
    ...
    OnHeadlineSelectedListener mHeadlineSelectedListener = null;

    /* Must be implemented by host activity */
    public interface OnHeadlineSelectedListener {
        public void onHeadlineSelected(int index);
    }
    ...

    public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) {
        mHeadlineSelectedListener = listener;
    }
}

사용자가 헤드라인을 선택하면 프래그먼트가 호스트 액티비티에서 지정된 리스너에게 알립니다(특정 하드코딩된 액티비티를 알리지 않음).

public class HeadlinesFragment extends ListFragment {
    ...
    @Override
    public void onItemClick(AdapterView<?> parent,
                            View view, int position, long id) {
        if (null != mHeadlineSelectedListener) {
            mHeadlineSelectedListener.onHeadlineSelected(position);
        }
    }
    ...
}

이 기술은 태블릿 및 헤드셋 지원 가이드에서 자세히 설명합니다.

화면 구성 변경 처리

별도 액티비티를 사용하여 인터페이스의 별도 부분을 구현한다면 인터페이스의 일관성을 유지하기 위해 특정 구성 변화(예: 회전 변화)에 반응하게 해야 할 수도 있습니다.

예를 들어 Android 3.0 이상이 실행되는 일반적 7인치 태블릿에서 News Reader 샘플은 세로 모드로 실행될 때 별도 액티비티를 사용하여 뉴스 기사를 표시하지만 가로 모드일 때는 창 두 개 레이아웃을 사용합니다.

사용자가 세로 모드이고 기사를 보는 액티비티가 화면에 있을 때, 방향이 가로로 변경되었는지 확인한 뒤에 콘텐츠가 창 두 개 레이아웃으로 표시되도록 액티비티를 종료하고 메인 액티비티로 돌아오는 방식으로 적절히 반응해야 합니다.

public class ArticleActivity extends FragmentActivity {
    int mCatIndex, mArtIndex;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCatIndex = getIntent().getExtras().getInt("catIndex", 0);
        mArtIndex = getIntent().getExtras().getInt("artIndex", 0);

        // If should be in two-pane mode, finish to return to main activity
        if (getResources().getBoolean(R.bool.has_two_panes)) {
            finish();
            return;
        }
        ...
}
이 사이트는 쿠키를 사용하여 사이트별 언어 및 표시 옵션에 대한 환경설정을 저장합니다.

Google Play에서 성공을 거두는 데 도움이 되는 최신 Android 개발자 뉴스 및 도움말을 받아 보세요.

* 필수 입력란

완료되었습니다.

WeChat에서 Google Developers 팔로우하기

이 사이트를 (으)로 탐색할까요?

페이지를 요청했지만 이 사이트의 언어 환경설정은 입니다.

언어 환경설정을 변경하고 이 사이트를 (으)로 탐색할까요? 언어 환경설정을 나중에 변경하려면 각 페이지 하단의 언어 메뉴를 사용하세요.

이 클래스를 사용하려면 API 수준 이상이 필요합니다.

문서에 대해 선택한 API 수준이 이므로 이 문서가 표시되지 않습니다. 왼쪽 탐색 메뉴의 선택기로 문서 API 수준을 변경할 수 있습니다.

앱에 필요한 API 수준 지정에 관한 자세한 내용은 다양한 플랫폼 버전 지원을 참조하세요.

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)