Skip to content

Files

Latest commit

author
SieunSong
Sep 7, 2018
2c178c5 ยท Sep 7, 2018

History

History
383 lines (280 loc) ยท 17.1 KB

FlexibleUI.md

File metadata and controls

383 lines (280 loc) ยท 17.1 KB

flexible UI

๋ฐœํ‘œ์ž : ์†ก์‹œ์€

๋ฐœํ‘œ์ฃผ์ œ : ๋ ˆ์ด์•„์›ƒ ๋ถ„๊ธฐ

๋ฐœํ‘œ์ผ์ž : 2018-09-07

[TOC]

0. ์ฐธ๊ณ ๋ฌธ์„œ

1. ๋ฆฌ์†Œ์Šค ๋ถ„๊ธฐ

์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ์—์„œ ์•„์ด์ฝ˜์ด ์žˆ๋Š” mipmap ๋””๋ ‰ํ„ฐ๋ฆฌ๋Š” ๊ธฐ๊ธฐ์˜ ๋ฐ€๋„(density)์— ๋”ฐ๋ผ ๋ถ„๊ธฐํ•˜๋„๋ก ๋˜์–ด์žˆ๋‹ค. ์•ฑ์ด ์‹คํ–‰๋  ๋•Œ ๊ธฐ๊ธฐ์˜ ๋ฐ€๋„์— ๋”ฐ๋ผ ํ•ด๋‹น ํด๋”์˜ ์•„์ด์ฝ˜์ด ์„ ํƒ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๋ ˆ์ด์•„์›ƒ๋„ ์ด๋Ÿฐ์‹์œผ๋กœ ๋ถ„๊ธฐํ•˜๋„๋ก ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ๋ ˆ์ด์•„์›ƒ ๋ถ„๊ธฐ

2.1. ์‹ค์Šต

  1. ๋ ˆ์ด์•„์›ƒ ๋ถ„๊ธฐ๋ฅผ ์œ„ํ•ด res ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ์„ ๋ˆ„๋ฅด๊ณ  [New -> Android resource directory]๋ฅผ ํด๋ฆญํ•˜์—ฌ ๋ฆฌ์†Œ์Šค ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค
  2. New Resource Directory ์ฐฝ์—์„œ Resource type:์€ 'layout'์„ ์„ ํƒํ•˜๊ณ , ์™ผ์ชฝ ํ•˜๋‹จ์— Available qualifiers ์ƒ์ž์—์„œ 'Orientation'์„ ์„ ํƒํ•œ ๋‹ค์Œ, ๊ฐ€์šด๋ฐ์— ์žˆ๋Š” >> ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ๋‹ค.
  3. Screen orientation: ํ•ญ๋ชฉ์—์„œ 'Landscape'๋ฅผ ์„ ํƒํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด Directory name:์ด layout-land๋กœ ์„ค์ •๋˜๋ฉฐ, ์ด ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ XML์€ ๊ฐ€๋กœ ๋ชจ๋“œ์— ์šฐ์„ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ๋ ˆ์ด์•„์›ƒ์ด ๋œ๋‹ค.
  4. layout/activity_main.xml ํŒŒ์ผ์„ layout-land ๋””๋ ‰ํ„ฐ๋ฆฌ์— ๋ณต์‚ฌํ•ด์„œ ๋ถ™์—ฌ๋„ฃ๋Š”๋‹ค.
  5. ๊ฐ€๋กœ ๋ชจ๋“œ์™€ ์„ธ๋กœ ๋ชจ๋“œ์˜ ๋ ˆ์ด์•„์›ƒ์„ ์„ค์ •ํ•œ๋‹ค.

๋ ˆ์ด์•„์›ƒ ๋ถ„๊ธฐ๋ฅผ ํ”„๋ž˜๊ทธ ๋จผํŠธ์™€ ์กฐํ•ฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ํ™”๋ฉด ๊ตฌ์„ฑ์„ ๋ณด๋‹ค ์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

3. ์œ ์—ฐํ•œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์ถ•

ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ํ™”๋ฉด ํฌ๊ธฐ๋ฅผ ์ง€์›ํ•˜๋Š” ์•ฑ์„ ๋งŒ๋“ค ๋•Œ, ํ™”๋ฉด ํฌ๊ธฐ๋‚˜ ๋ฐฉํ–ฅ์— ๋”ฐ๋ผ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์žฌํ™œ์šฉํ•˜์—ฌ ๋ ˆ์ด์•„์›ƒ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํƒœํ”Œ๋ฆฟ๊ณผ ํ•ธ๋“œํฐ์„ ๋™์‹œ์— ์ง€์›ํ•˜๋Š” ์•ฑ์„ ๊ฐœ๋ฐœํ•  ๋•Œ ์œ ์šฉํ•˜๋‹ค.

์˜ˆ์‹œ)

FragmentManager ํด๋ž˜์Šค ๋Ÿฐํƒ€์ž„์— ๋™์ ์œผ๋กœ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์ถ”๊ฐ€๋‚˜ ์‚ญ์ œ, ๋˜๋Š” ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณต

3.1. ์‹ค์Šต

์ž‘์„ฑํ•  ์˜ˆ์ œ์˜ ๋™์ž‘์„ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์‹œ์ž‘ํ•˜๋ฉด HeadlinesFragment๋ฅผ ๋™์  ์ถ”๊ฐ€ํ•œ๋‹ค.
  2. HeadlinesFragment์—์„œ ์•„์ดํ…œ์ด ์„ ํƒ๋˜๋ฉด onHeadlineSelected ์ฝœ๋ฐฑ์ด ํ˜ธ์ถœ๋œ๋‹ค.
  3. ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ArticleFragment๋กœ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ๊ต์ฒดํ•œ๋‹ค.
  4. ํ”„๋ž˜๊ทธ๋จผํŠธ๊ฐ€ ๊ต์ฒด๋˜๊ธฐ ์ „์— ๋ฐฑ์Šคํƒ์— ์ €์žฅํ•จ์œผ๋กœ์จ ๋’ค๋กœ ๊ฐ€๊ธฐ๋กœ HeadlinesFragment๋กœ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋‹ค.

์ œ๋ชฉ์„ ๋ˆ„๋ฅด๋ฉด ๋‚ด์šฉ์„ ํ‘œ์‹œํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์•ฑ์˜ ์ƒ˜ํ”Œ์„ ์ž‘์„ฑํ•  ๊ฒƒ์ด๋‹ค.

ํ”„๋ž˜๊ทธ๋จผํŠธ A์— ์ œ๋ชฉ ๋ฆฌ์ŠคํŠธ๊ฐ€ ํ‘œ์‹œ๋˜๊ฒŒ ํ•˜๊ณ , ์ œ๋ชฉ์„ ํด๋ฆญํ•˜๋ฉด ํ”„๋ž˜๊ทธ๋จผํŠธ B์— ๋‚ด์šฉ์ด ๋ณด์ด๊ฒŒ ํ•  ๊ฒƒ์ด๋‹ค.

์ด๋ฅผ ์œ„ํ•ด Article ํด๋ž˜์Šค๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

public class Articles {
    // ์ œ๋ชฉ
    static String[] Headlines = {
            "์ œ๋ชฉ 1", "์ œ๋ชฉ 2"
    };
    // ๋‚ด์šฉ
    static String[] Articles = {
            "์ด๊ฒƒ์€ ์ œ๋ชฉ1์˜ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.",
            "์ด๊ฒƒ์€ ์ œ๋ชฉ2์˜ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค."
    };
}

3.1.1. ํ™”๋ฉด์ด ์ž‘์€ ๊ธฐ๊ธฐ์—์„œ์˜ ๋™์ž‘

ํ™”๋ฉด์ด ์ž‘์€ ๊ธฐ๊ธฐ์™€ ํฐ ๊ธฐ๊ธฐ(7์ธ์น˜ ์ด์ƒ ํƒœ๋ธ”๋ฆฟ)์—์„œ ๋ ˆ์ด์•„์›ƒ๊ณผ ์•ฑ์˜ ๋™์ž‘์ด ๋‹ค๋ฅด๊ฒŒ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

ํ•ธ๋“œํฐ์ฒ˜๋Ÿผ ํ™”๋ฉด ํฌ๊ธฐ๊ฐ€ 7์ธ์น˜ ๋ฏธ๋งŒ์ธ ๊ธฐ๊ธฐ์—์„œ๋Š” ํ”„๋ž˜๊ทธ๋จผํŠธ A์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ํด๋ฆญํ•˜๋ฉด ํ”„๋ž˜๊ทธ๋จผํŠธ B์˜ ๋‚ด์šฉ์ด ํ‘œ์‹œ๋˜๊ฒŒ ํ•˜๊ณ , ํƒœ๋ธ”๋ฆฟ์ฒ˜๋Ÿผ ํฐ ๊ธฐ๊ธฐ์—์„œ๋Š” ํ•œ ํ™”๋ฉด์— ํ”„๋ž˜๊ทธ๋จผํŠธ A์™€ B๊ฐ€ ๊ฒฐํ•ฉ๋˜์–ด ๋ฆฌ์ŠคํŠธ์™€ ๋‚ด์šฉ์ด ๋ชจ๋‘ ํ‘œ์‹œ๋˜๊ฒŒ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

  1. ํ”„๋ž˜๊ทธ๋จผํŠธ A์— ํ•ด๋‹นํ•˜๋Š” HeadlinesFragment๋ฅผ ์ž‘์„ฑํ•œ๋‹ค - ์ œ๋ชฉ์„ ํ‘œ์‹œํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ํ‘œ์‹œ

    /**
     * ์ œ๋ชฉ์„ ํ‘œ์‹œํ•  ๋ฆฌ์ŠคํŠธ ํ”„๋ž˜๊ทธ๋จผํŠธ
     */
    public class HeadlinesFragment extends ListFragment {
        // ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ๋Š” ๋ฐ˜๋“œ์‹œ ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•จ
        interface OnHeadlineSelectedListener {
            // ์ œ๋ชฉ์ด ์„ ํƒ๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ๋จ
            void onHeadlineSelected(int position);
        }
        private OnHeadlineSelectedListener mListener;
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState){
            super.onCreate(savedInstanceState);
            // Articles ์˜ Headlines ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์ŠคํŠธ ๋ทฐ๋ฅผ ์œ„ํ•œ ArrayAdapter ๋ฅผ ์ƒ์„ฑ
            setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, Articles.Headlines));
        }
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            // ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ํฌํ•จํ•˜๋Š” Context ๋Š” ๋ฐ˜๋“œ์‹œ OnHeadlineSelectedListener ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
            // ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ClassCastException ์ด ๋ฐœ์ƒํ•˜๊ณ  ์•ฑ์„ ์ข…๋ฃŒํ•œ๋‹ค.
            try {
                mListener = (OnHeadlineSelectedListener) context;
            }catch (ClassCastException e){
                throw new ClassCastException(context.toString() + " must implement OnHeadlineSelectedListener");
            }
        }
        @Override
        public void onListItemClick(ListView l, View v, int position, long id){
            super.onListItemClick(l, v, position, id);
            // ์„ ํƒ๋œ ์œ„์น˜๋ฅผ ์•กํ‹ฐ๋น„ํ‹ฐ์— ์•Œ๋ ค ์คŒ
            if (mListener != null) {
                mListener.onHeadlineSelected(position);
            }
        }
    }

    ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ๋Š” ListFragment๋ฅผ ์ƒ์†ํ•˜๋ฉฐ ์ œ๋ชฉ์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์ œ๋ชฉ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ์— ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•˜๋„๋ก ๋˜์–ด์žˆ๋‹ค. ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ํฌํ•จํ•  ์•กํ‹ฐ๋น„ํ‹ฐ๋Š” ๋ฐ˜๋“œ์‹œ OnHeadlineSelectedListener ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก onAttach() ๋ฉ”์„œ๋“œ์—์„œ ๊ฐ•์ œ๋กœ ์•กํ‹ฐ๋น„ํ‹ฐ์™€ ์—ฐ๊ฒฐํ•˜๊ณ  ์žˆ๋‹ค.

  2. ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์„ ์ค€๋น„ fragment_article

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <TextView
        android:id="@+id/article_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    </LinearLayout>
  3. ํ”„๋ž˜๊ทธ๋จผํŠธ B์— ํ•ด๋‹นํ•˜๋Š” ArticleFragment ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค - ๋‚ด์šฉ์„ ํ…์ŠคํŠธ๋ทฐ์— ํ‘œ์‹œ

    /**
     * HeadlinesFragment ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ์ œ๋ชฉ๋ฅผ ํ‘œ์‹œํ•  ํ”„๋ž˜๊ทธ๋จผํŠธ
     */
    
    public class ArticleFragment extends Fragment {
        public static final String ARG_POSITION = "position";
        private int mCurrentPosition = -1;
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            // ํ™”๋ฉด์ด ํšŒ์ „๋˜๋ฉด ์ด์ „์— ์„ ํƒ๋œ ์œ„์น˜๋ฅผ ๋ณต์›
            if (savedInstanceState != null) {
                mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
            }
            // ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ์€ TextView ํ•˜๋‚˜๋งŒ ์žˆ๋Š” ๋ ˆ์ด์•„์›ƒ์„ ์‚ฌ์šฉ
            return inflater.inflate(R.layout.fragment_articles, container, false);
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            Bundle args = getArguments();
            if (args != null) {
                // ํ”„๋ž˜๊ทธ๋จผํŠธ๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„ ๊ฒฝ์šฐ
                updateArticleView(args.getInt(ARG_POSITION));
            } else if (mCurrentPosition != -1) {
                // ํ™”๋ฉด ํšŒ์ „ ๋“ฑ์˜ ๊ฒฝ์šฐ
                updateArticleView(mCurrentPosition);
            }
        }
    
        // ์„ ํƒ๋œ ์ œ๋ชฉ์˜ ๋‚ด์šฉ์„ ํ‘œ์‹œ
        public void updateArticleView(int position) {
            TextView article = (TextView) getView().findViewById(R.id.article_text);
            article.setText(Articles.Articles[position]);
            mCurrentPosition = position;
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            // ํ™”๋ฉด์ด ํšŒ์ „๋  ๋•Œ, ์„ ํƒ๋œ ์œ„์น˜๋ฅผ ์ €์žฅ
            outState.putInt(ARG_POSITION, mCurrentPosition);
        }
    }

    ์ด ํ”„๋ž˜๊ทธ๋จผํŠธ๋Š” ๋ช‡ ๋ฒˆ์งธ ์ œ๋ชฉ์ด ์„ ํƒ๋˜์—ˆ๋Š”์ง€์— ๋”ฐ๋ผ์„œ ํ•ด๋‹น ์ œ๋ชฉ์˜ ๋‚ด์šฉ์„ Articles.Articles ๋ฐฐ์—ด์—์„œ ๊ฐ€์ ธ์™€์„œ ํ…์ŠคํŠธ๋ทฐ์— ํ‘œ์‹œํ•œ๋‹ค.

    ํ”„๋ž˜๊ทธ๋จผํŠธ๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ ์ƒ๋ช…์ฃผ๊ธฐ์™€ ์—ฐ๊ด€๋œ ๋ณต์žกํ•œ ์‚ฌ์ •์œผ๋กœ ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ์ด ๊ธˆ์ง€๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋Š” ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค๋ฉด ์•ˆ๋“œ๋กœ์ด๋“œ ์ŠคํŠœ๋””์˜ค๊ฐ€ ๋นจ๊ฐ„ ์ค„๋กœ ํ‘œ์‹œํ•  ๊ฒƒ์ด๋‹ค. ๋Œ€์‹  Bundle ๊ฐ์ฒด๋ฅผ Argument๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์ฒ˜์Œ ์ƒ์„ฑํ–ˆ์„ ๋•Œ๋Š” Argument๋กœ ์ œ๋ชฉ ๋ฒˆํ˜ธ๋ฅผ ์ „๋‹ฌ๋ฐ›์•„์„œ ์ œ๋ชฉ์„ ํ‘œ์‹œํ•˜๊ณ , ํ™”๋ฉด์ด ํšŒ์ „ํ•˜๋ฉด ๋งˆ์ง€๋ง‰์— ์„ ํƒ๋œ ๊ธฐ์‚ฌ ๋ฒˆํ˜ธ๋ฅผ onSavedInstanceState() ๋ฉ”์„œ๋“œ์—์„œ ์ €์žฅํ•˜๊ณ  onCreateView() ๋ฉ”์„œ๋“œ์—์„œ ๋ณต์›ํ•œ๋‹ค.

  4. ๋‘ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ํฌํ•จํ•  ์•กํ‹ฐ๋น„ํ‹ฐ์ธ MainActivity์ธ ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค.

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    </RelativeLayout>

    ๋ ˆ์ด์•„์›ƒ์˜ ๋‚ด๋ถ€์—๋Š” ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ํ‘œ์‹œํ•  ์˜์—ญ์ธ FrameLayout์„ ๋ฐฐ์น˜ํ•˜์˜€๊ณ  id๋ฅผ ๋ถ€์—ฌํ–ˆ๋‹ค.

    ์ด ์˜์—ญ์— ์ตœ์ดˆ์—๋Š” ํ”„๋ž˜๊ทธ๋จผํŠธ A๋ฅผ ํ‘œ์‹œํ•˜๊ณ , ์ œ๋ชฉ์„ ์„ ํƒํ•˜๋ฉด ํ”„๋ž˜๊ทธ๋จผํŠธ B๋กœ ๊ต์ฒดํ•  ๊ฒƒ์ด๋‹ค.

  5. MainActivity ์ž‘์„ฑ

    public class MainActivity extends AppCompatActivity implements HeadlinesFragment.OnHeadlineSelectedListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // ํ™”๋ฉด ํšŒ์ „ ์‹œ HeadlinesFragment ๊ฐ€ ์žฌ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ ๋ฐฉ์ง€
            if (savedInstanceState == null) {
                HeadlinesFragment headlinesFragment = new HeadlinesFragment();
                // headlinesFragment ๋ฅผ R.id.fragment_container ์˜์—ญ์— ์ถ”๊ฐ€
                getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, headlinesFragment)
                    .commit();
            }
        }
    
        // HeadlinesFragment ์˜ ์ œ๋ชฉ์ด ์„ ํƒ๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ
        @Override
        public void onHeadlineSelected(int position) {
            // ArticleFragment ํ”„๋ž˜๊ทธ๋จผํŠธ ์ƒ์„ฑ
            ArticleFragment newArticleFragment = new ArticleFragment();
            // Argument ๋กœ ์ œ๋ชฉ ๋ฒˆํ˜ธ ์ „๋‹ฌ
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newArticleFragment.setArguments(args);
            // R.id.fragment_container ์•„์ด๋””๋ฅผ ๊ฐ€์ง„ ์˜์—ญ์˜ 
            //ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ articleFragment ๋กœ ๊ต์ฒดํ•˜๊ณ 
            // ํ”„๋ž˜๊ทธ๋จผํŠธ ๋งค๋‹ˆ์ €์˜ BackStack ์— ์Œ“๋Š”๋‹ค
            getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_container, newArticleFragment)
                .addToBackStack(null)
                .commit();
        }
    }

    MainActivity๋ฅผ ์‹คํ–‰ ์‹œ HeadlinesFragment๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์ œ๋ชฉ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ onHeadlineSelected() ์ฝœ๋ฐฑ์ด ํ˜ธ์ถœ๋˜๋ฉฐ, ArticleFragment๋กœ ๊ต์ฒด๋œ๋‹ค.

    ์ฃผ์˜ํ•ด์„œ ๋ณผ ๋ถ€๋ถ„์€ onCreate() ๋ฉ”์„œ๋“œ์—์„œ savedInstanceState == null ์ผ ๋•Œ๋งŒ HeadlinesFragment๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ๋‹ค. ์ด ์กฐ๊ฑด์ด ์—†๋‹ค๋ฉด ํ™”๋ฉด์ด ํšŒ์ „๋  ๋•Œ๋งˆ๋‹ค ๊ธฐ์กด HeadlinesFragment๊ฐ€ ์œ ์ง€๋˜๋ฉฐ ์ƒˆ๋กœ์šด HeadlinsFragment๊ฐ€ ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ˜๋“œ์‹œ savedInstanceState๊ฐ€ null์ธ์ง€ ๊ฒ€์‚ฌํ•˜๋Š” ๋กœ์ง์„ ์žŠ์œผ๋ฉด ์•ˆ๋œ๋‹ค. ์ด์œ ๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ํšŒ์ „ํ•˜์—ฌ ๊ฐ•์ œ๋กœ ์žฌ์ƒ์„ฑํ•ด๋„ ํ”„๋ž˜๊ทธ๋จผํŠธ๋Š” ํ”„๋ž˜๊ทธ๋จผํŠธ ๋งค๋‹ˆ์ €๊ฐ€ ๋ณ„๋„๋กœ ๊ด€๋ฆฌํ•˜๋ฉฐ ์žฌ์ƒ์„ฑ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

    onHeadlineSelected() ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ์—์„œ ๊ธฐ์‚ฌ์˜ ๋‚ด์šฉ์„ ํ‘œ์‹œํ•˜๋Š” ArticleFragment๋กœ ๊ต์ฒดํ•  ๋•Œ addToBackStack(null) ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ ๋ฐฑ์Šคํƒ์— ์ถ”๊ฐ€ํ•œ๋‹ค. ๋ฐฑ์Šคํƒ(BackStack)์ด๋ž€, ํ”„๋ž˜๊ทธ๋จผํŠธ ๋งค๋‹ˆ์ €๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์Šคํƒ์ด๋‹ค.

3.1.2. ํ™”๋ฉด์ด ํฐ ๊ธฐ๊ธฐ๋ฅผ ์œ„ํ•œ ๊ตฌํ˜„ ์ถ”๊ฐ€

์•ˆ๋“œ๋กœ์ด๋“œ์˜ ๋ ˆ์ด์•„์›ƒ์€ ํ™”๋ฉด ํฌ๊ธฐ์— ๋”ฐ๋ผ ๋ถ„๊ธฐํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ์˜ ๊ฒฝ๋กœ๋Š” layout/activity_main.xml์ด์ง€๋งŒ, layout-large.activity_main.xml์„ ์ถ”๊ฐ€ํ•˜๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” layout ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ XML ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜๊ณ , ํ™”๋ฉด์ด 7์ธ์น˜ ์ด์ƒ์œผ๋กœ ํฐ ๊ธฐ๊ธฐ์—์„œ๋Š” layout_large ๋””๋ ‰ํ„ฐ๋ฆฌ์˜ XML ํŒŒ์ผ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. 7์ธ์น˜ ์ด์ƒ์˜ ๋ ˆ์ด์•„์›ƒ์„ ์œ„ํ•œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

  2. layout-large ์— activity_main.xml์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment
            android:id="@+id/headlines_fragment"
            android:name="com.example.user.dynamicuiexam.HeadlinesFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            tools:layout="@android:layout/simple_list_item_1" />
    
        <fragment
            android:id="@+id/article_fragment"
            android:name="com.example.user.dynamicuiexam.ArticleFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            tools:layout="@layout/fragment_articles" />
    </LinearLayout>
  3. MainActivity ์ฝ”๋“œ ์ˆ˜์ •

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // layout-large ์˜ ๋ ˆ์ด์•„์›ƒ์—๋Š” fragment_container ๊ฐ€ ์—†์Œ
            if (findViewById(R.id.fragment_container) != null) {
                // ํ™”๋ฉด ํšŒ์ „ ์‹œ HeadlinesFragment ๊ฐ€ ์žฌ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ ๋ฐฉ์ง€
                if (savedInstanceState == null) {
                    HeadlinesFragment headlinesFragment = new HeadlinesFragment();
                    // headlinesFragment ๋ฅผ R.id.fragment_container ์˜์—ญ์— ์ถ”๊ฐ€
                    getSupportFragmentManager().beginTransaction()
                            .add(R.id.fragment_container, headlinesFragment)
                            .commit();
                }
            }
        }

    onCreate() ์—์„œ layout-large์ธ์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ

    layout-large์˜ ๋ ˆ์ด์•„์›ƒ์€ ๋ฏธ๋ฆฌ ๋‘ ๊ฐœ์˜ ํ”„๋ž˜๊ทธ๋จผํŠธ๊ฐ€ ์œ„์น˜ ํ•ด ์žˆ์œผ๋ฏ€๋กœ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

    @Override
        public void onHeadlineSelected(int position) {
            ArticleFragment articleFragment = (ArticleFragment) getSupportFragmentManager().findFragmentById(R.id.article_fragment);
            // layout-large ์˜ ๊ฒฝ์šฐ null ์ด ์•„๋‹˜
            if (articleFragment == null) {
                // ArticleFragment ํ”„๋ž˜๊ทธ๋จผํŠธ ์ƒ์„ฑ
                ArticleFragment newArticleFragment = new ArticleFragment();
                // Argument ๋กœ ๊ธฐ์‚ฌ ๋ฒˆํ˜ธ ์ „๋‹ฌ
                Bundle args = new Bundle();
                args.putInt(ArticleFragment.ARG_POSITION, position);
                newArticleFragment.setArguments(args);
                // R.id.fragment_container ์•„์ด๋””๋ฅผ ๊ฐ€์ง„ ์˜์—ญ์˜ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ articleFragment ๋กœ ๊ต์ฒดํ•˜๊ณ 
                // ํ”„๋ž˜๊ทธ๋จผํŠธ ๋งค๋‹ˆ์ €์˜ BackStack ์— ์Œ“๋Š”๋‹ค
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fragment_container, newArticleFragment)
                        .addToBackStack(null)
                        .commit();
            } else {
                articleFragment.updateArticleView(position);
            }
        }
    }

    ๊ธฐ์กด์˜ articleFragment๋ผ๋Š” ๋ณ€์ˆ˜๋ช…์„ newArticleFragment๋กœ ์ˆ˜์ •ํ•˜์˜€๊ณ , layout-large์˜ ๊ฒฝ์šฐ์—๋Š” article_fragment ์•„์ด๋””๋กœ ์ด๋ฏธ ArticleFragment๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์ด๊ฒƒ์ด null์ธ์ง€ ์•„๋‹Œ์ง€์— ๋”ฐ๋ผ์„œ ์•„๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค. ๋งŒ์•ฝ layout-large์™€ ๊ฐ™์ด ArticleFragment๊ฐ€ ์ด๋ฏธ ์žˆ๋‹ค๋ฉด ๊ทธ ํ”„๋ž˜๊ทธ๋จผํŠธ์˜ ๊ธฐ์‚ฌ๋งŒ updateArticleView()๋ฅผ ํ†ตํ•ด ๊ฐฑ์‹ ํ•˜๋ฉด ๋œ๋‹ค.