Android Advanced UI Components


7. 고급 UI 구성 요소

이 장에서는 안드로이드 애플리케이션에서 사용되는 다양한 고급 UI 구성 요소에 대해 예제와 함께 자세히 다룹니다.

7.1 메뉴 (Menus)

메뉴는 애플리케이션의 주요 기능을 사용자에게 제공하는 방법으로, 옵션 메뉴와 팝업 메뉴로 구분됩니다.

옵션 메뉴 예제
  1. res/menu/menu_main.xml 파일을 생성합니다.
<!-- res/menu/menu_main.xml -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_settings"
        android:title="Settings"
        android:icon="@drawable/ic_settings"
        android:showAsAction="ifRoom"/>
    <item
        android:id="@+id/action_refresh"
        android:title="Refresh"
        android:icon="@drawable/ic_refresh"
        android:showAsAction="ifRoom"/>
</menu>
  1. MainActivity.java에서 메뉴를 처리합니다.
public class MainActivity extends AppCompatActivity {

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            // 설정 메뉴 선택 시 동작
            return true;
        } else if (id == R.id.action_refresh) {
            // 새로고침 메뉴 선택 시 동작
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
팝업 메뉴 예제
public class MainActivity extends AppCompatActivity {

    private Button popupButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        popupButton = findViewById(R.id.popupButton);
        popupButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showPopupMenu();
            }
        });
    }

    private void showPopupMenu() {
        PopupMenu popupMenu = new PopupMenu(this, popupButton);
        popupMenu.getMenuInflater().inflate(R.menu.popup_menu, popupMenu.getMenu());

        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.menu_item1:
                        // 팝업 메뉴 아이템 1 선택 시 동작
                        return true;
                    case R.id.menu_item2:
                        // 팝업 메뉴 아이템 2 선택 시 동작
                        return true;
                    default:
                        return false;
                }
            }
        });

        popupMenu.show();
    }
}

7.2 대화 상자 (Dialogs)

대화 상자는 사용자에게 정보를 제공하거나 사용자 입력을 받기 위한 팝업 창입니다.

AlertDialog 예제
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Confirmation");
        builder.setMessage("Are you sure you want to delete this item?");
        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 사용자가 Yes를 선택했을 때의 동작
            }
        });
        builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 사용자가 No를 선택했을 때의 동작
                dialog.dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.show();
    }
}

7.3 토스트 (Toasts)

토스트는 잠시 동안 화면에 메시지를 표시하는 간단한 알림창입니다.

Toast 예제
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button showToastButton = findViewById(R.id.showToastButton);
        showToastButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "This is a Toast message", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

7.4 툴바와 액션바 (Toolbars, ActionBars)

툴바와 액션바는 화면 상단에 위치하여 주요 작업을 위한 단추와 기능을 제공하는 UI 요소입니다.

Toolbar 예제
  1. res/layout/activity_main.xml 파일에서 Toolbar를 추가합니다.
<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
  1. MainActivity.java에서 Toolbar를 설정합니다.
public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }
}

7.5 탭 (Tabs)

탭은 여러 섹션을 표시하고 사용자가 탭을 선택하여 이동할 수 있는 인터페이스 요소입니다.

TabLayout 및 ViewPager 예제
  1. res/layout/activity_main.xml 파일에서 TabLayout과 ViewPager를 추가합니다.
<com.google.android.material.tabs.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabMode="fixed"
    app:tabGravity="fill"/>

<androidx.viewpager.widget.ViewPager
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
  1. MainActivity.java에서 TabLayout과 ViewPager를 설정합니다.
public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout = findViewById(R.id.tabLayout);
        viewPager = findViewById(R.id.viewPager);

        setupViewPager(viewPager);
        tabLayout.setupWithViewPager(viewPager);
    }

    private void setupViewPager(ViewPager viewPager) {
        MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new Fragment1(), "Tab 1");
        adapter.addFragment(new Fragment2(), "Tab 2");
        viewPager.setAdapter(adapter);
    }

    private static class MyPagerAdapter extends FragmentPagerAdapter {

        private final List<Fragment> fragmentList = new ArrayList<>();
        private final List<String> fragmentTitleList = new ArrayList<>();

        public MyPagerAdapter(@NonNull FragmentManager fm) {
            super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        }

        public void addFragment(Fragment fragment, String title) {
            fragmentList.add(fragment);
            fragmentTitleList.add(title);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }

        @Override
        public int getCount() {
            return fragmentList.size();
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return fragmentTitleList.get(position);
        }
    }
}

7.6 네비게이션 드로어 (Navigation Drawer)

네비게이션 드로어는 화면 좌측에서 나오는 슬라이드 메뉴입니다.

Navigation Drawer 예제
  1. res/layout/activity_main.xml 파일에서 DrawerLayout과 NavigationView를 추가합니다.
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/contentFrame"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/navigationView"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>
  1. MainActivity.java에서 Navigation Drawer를 설정합니다.
public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;

    @Override
    protected void onCreate(Bundle

 savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        drawerLayout = findViewById(R.id.drawerLayout);
        navigationView = findViewById(R.id.navigationView);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                // 네비게이션 메뉴 아이템 선택 시 동작
                return true;
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // 툴바의 Navigation Drawer 토글 버튼 클릭 처리
        if (toggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

7.7 ViewPager

ViewPager는 여러 페이지를 스와이프하여 전환할 수 있는 컨테이너입니다.

ViewPager 예제
public class MainActivity extends AppCompatActivity {

    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager = findViewById(R.id.viewPager);
        MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(adapter);
    }

    private static class MyPagerAdapter extends FragmentPagerAdapter {

        private static final int NUM_PAGES = 3;

        public MyPagerAdapter(@NonNull FragmentManager fm) {
            super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return PageFragment.newInstance(position);
        }

        @Override
        public int getCount() {
            return NUM_PAGES;
        }
    }

    public static class PageFragment extends Fragment {

        private static final String ARG_PAGE = "ARG_PAGE";

        public static PageFragment newInstance(int page) {
            Bundle args = new Bundle();
            args.putInt(ARG_PAGE, page);
            PageFragment fragment = new PageFragment();
            fragment.setArguments(args);
            return fragment;
        }

        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_page, container, false);
            // 페이지별로 다른 레이아웃 구성 가능
            return view;
        }
    }
}

7.8 TabLayout

TabLayout은 탭을 사용하여 다른 콘텐츠 화면을 전환하는 인디케이터입니다.

TabLayout 예제
public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tabLayout = findViewById(R.id.tabLayout);
        viewPager = findViewById(R.id.viewPager);

        setupViewPager(viewPager);
        tabLayout.setupWithViewPager(viewPager);
    }

    private void setupViewPager(ViewPager viewPager) {
        MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new Tab1Fragment(), "Tab 1");
        adapter.addFragment(new Tab2Fragment(), "Tab 2");
        viewPager.setAdapter(adapter);
    }

    private static class MyPagerAdapter extends FragmentPagerAdapter {

        private final List<Fragment> fragmentList = new ArrayList<>();
        private final List<String> fragmentTitleList = new ArrayList<>();

        public MyPagerAdapter(@NonNull FragmentManager fm) {
            super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        }

        public void addFragment(Fragment fragment, String title) {
            fragmentList.add(fragment);
            fragmentTitleList.add(title);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }

        @Override
        public int getCount() {
            return fragmentList.size();
        }

        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return fragmentTitleList.get(position);
        }
    }
}

7.9 커스텀 뷰 (Custom Views)

커스텀 뷰는 개발자가 직접 만든 UI 요소로, 특정한 동작이나 모양을 가질 수 있습니다.

Custom View 예제
public class CustomView extends View {

    private Paint paint;
    private Path path;

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStrokeWidth(5);
        paint.setStyle(Paint.Style.STROKE);

        path = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        int width = getWidth();
        int height = getHeight();

        path.moveTo(0, height / 2);
        path.lineTo(width, height / 2);

        canvas.drawPath(path, paint);
    }
}

7.10 캔버스 (Canvas)

캔버스는 2D 그래픽을 그리기 위한 그래픽 객체입니다.

Canvas 예제
public class CanvasActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new CustomCanvasView(this));
    }

    private static class CustomCanvasView extends View {

        private Paint paint;

        public CustomCanvasView(Context context) {
            super(context);
            init();
        }

        private void init() {
            paint = new Paint();
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(10);
            paint.setStyle(Paint.Style.STROKE);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            int width = getWidth();
            int height = getHeight();

            canvas.drawLine(0, 0, width, height, paint);
            canvas.drawLine(0, height, width, 0, paint);
        }
    }
}

이 장에서 다루는 예제들은 각 UI 구성 요소를 구현하고 사용하는 방법을 보여줍니다. 안드로이드 애플리케이션에서 이러한 고급 UI 요소를 통해 사용자 경험을 향상시키고, 다양한 기능을 제공할 수 있습니다.


Leave a Reply

Your email address will not be published. Required fields are marked *