짱짱해커가 되고 싶은 나

07-1. 메뉴 본문

모바일

07-1. 메뉴

동로시 2021. 2. 20. 11:11

메뉴

: 사용자가 여러 개 중 하나를 선택하도록 하여 사용자의 명령을 받아들이는 명령식

- 옵션 메뉴(option menu) : 흔히 알고 있는 옵션들이 있고 선택하는 형식(키패드의 메뉴버튼)

- 컨텍스트 메뉴(context menu) : 일정 추가 버튼을 눌렀을 때 생기는 그런 형식(위젯 롱클릭, 화면 중앙)

 

메뉴를 사용하기 위해서는 res에 menu resource directory를 생성하고 menu resource file을 생성해서 작업한다.

 

* 옵선 메뉴

<menu1.xml>

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/itemRed"
        android:title="배경색(빨강)">
    </item>
    <item
        android:id="@+id/itemGreen"
        android:title="배경색(초록)">
    </item>
    <item
        android:id="@+id/itemBlue"
        android:title="배경색(파랑)">
    </item>

    <item android:title="버튼 변경 >> ">
        <menu>
            <item
                android:id="@+id/subRotate"
                android:title="버튼 45도 회전"/>
            <item
                android:id="@+id/subSize"
                android:title="버튼 2배 확대"/>
        </menu>
    </item>

</menu>

메뉴는 아이템 안에 서브 메뉴를 만들어서 사용할 수 있다.

 

<MainActivity.java>

package com.example.menu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
    LinearLayout baseLayout;
    Button btn1;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater mInflater = getMenuInflater();
        mInflater.inflate(R.menu.menu1, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case R.id.itemRed:
                baseLayout.setBackgroundColor(Color.RED);
                return true;
            case R.id.itemGreen:
                baseLayout.setBackgroundColor(Color.GREEN);
                return true;
            case R.id.itemBlue:
                baseLayout.setBackgroundColor(Color.BLUE);
                return true;
            case R.id.subRotate:
                btn1.setRotation(45);
                return true;
            case R.id.subSize:
                btn1.setScaleX(2);
                return true;
        }
        return false;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("배경색 바꾸기");

        baseLayout = (LinearLayout)findViewById(R.id.baseLayout);
        btn1 = (Button)findViewById(R.id.btn1);


    }
}

 

- onCreateOptionMenu() : 앱이 실행되면 메뉴의 내용을 xml파일에서 자동으로 읽어온다.

MenuInflater를 생성하고 inflate()를 통해 앞에서 만들었던 메뉴 xml 파일을 등록한다.

- onOptionsItemSelected() : 메뉴를 선택했을 때 어떤 동작을 할 것인지 저장한다.

 

 

옵션 메뉴 java 로만 구성하기

package com.example.menu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
    LinearLayout baseLayout;
    Button btn1;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(0,1,0, "배경색(빨강)");
        menu.add(0,2,0,"배경색(초록)");
        menu.add(0,3,0,"배경색(파랑)");

        SubMenu sMenu = menu.addSubMenu("버튼 변경 >>");
        sMenu.add(0,4,0,"버튼 45도 회전");
        sMenu.add(0,5,0,"버튼 2배 확대");

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case 1:
                baseLayout.setBackgroundColor(Color.RED);
                return true;
            case 2:
                baseLayout.setBackgroundColor(Color.GREEN);
                return true;
            case 3:
                baseLayout.setBackgroundColor(Color.BLUE);
                return true;
            case 4:
                btn1.setRotation(45);
                return true;
            case 5:
                btn1.setScaleX(2);
                return true;
        }
        return false;
    }

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

        baseLayout = (LinearLayout)findViewById(R.id.baseLayout);
        btn1 = (Button)findViewById(R.id.btn1);

    }
}

- add() :메뉴에 아이템을 더한다.

4개의 인자를 받는데 그룹 아이디, 아이템 아이디, order, title 의 순서다.

- addSubMenu(title) : 메뉴에 서브메뉴를 더한다.

    <group
        android:checkableBehavior="single">
        <item
            android:id="@+id/item2"
            android:title="한라산"
            android:checked="true"/>
        <item
            android:id="@+id/item3"
            android:title="추자도"/>
        <item
            android:id="@+id/item4"
            android:title="범섬"/>

    </group>

옵션 메뉴는 <group> 이 있어서 아래 사진처럼 여러 항목을 묶어서 사용할 수 있다.

옵션메뉴 - 그룹 아이템

* 컨텍스트 메뉴

여러 개의 위젯에 메뉴를 설정할 수 있기 때문에 위젯마다 별도의 메뉴 xml 파일을 생성한다.

 

<menu1.xml>

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/red"
        android:title="배경색(빨강)">
    </item>
    <item
        android:id="@+id/green"
        android:title="배경색(초록)">
    </item>
    <item
        android:id="@+id/blue"
        android:title="배경색(파랑)">
    </item>

</menu>

<menu2.xml>

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/subRotate"
        android:title="버튼 45도 회전"/>
    <item
        android:id="@+id/subSize"
        android:title="버튼 2배 확대"/>

</menu>

<MainAcitivity.java>

package com.example.menu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {
    LinearLayout baseLayout;
    Button btn1, btn2;

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        MenuInflater inflater = getMenuInflater();
        if(v == btn1){
            menu.setHeaderTitle("배경색 변경");
            inflater.inflate(R.menu.menu1, menu);
        }
        if(v == btn2){
            menu.setHeaderTitle("버튼 변경");
            inflater.inflate(R.menu.menu2, menu);
        }
    }

    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        switch(item.getItemId()){
            case R.id.red:
                baseLayout.setBackgroundColor(Color.RED);
                return true;
            case R.id.green:
                baseLayout.setBackgroundColor(Color.GREEN);
                return true;
            case R.id.blue:
                baseLayout.setBackgroundColor(Color.BLUE);
                return true;
            case R.id.subRotate:
                btn2.setRotation(45);
                return true;
            case R.id.subSize:
                btn2.setScaleX(2);
                return true;
        }
        return false;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("배경색 바꾸기(컨텍스트 메뉴)");

        baseLayout = (LinearLayout)findViewById(R.id.baseLayout);
        btn1 = (Button)findViewById(R.id.btn1);
        btn2 = (Button)findViewById(R.id.btn2);

        registerForContextMenu(btn1);
        registerForContextMenu(btn2);

    }
}

위젯마다 메뉴를 등록할 수 있기 때문에 컨텍스트 메뉴를 나타낼 위젯을 registerForContextMenu()로 등록한다.

onCretaeContextMenu()에서는 각 위젯마다 해당하는 메뉴 xml파일을 inflate한다.

 

컨텍스트 메뉴 역시 xml 파일 없이 java 코드 만으로도 만들 수 있다.

package com.example.menu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends Activity {
    LinearLayout baseLayout;
    Button btn1, btn2;

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);

        MenuInflater inflater = getMenuInflater();
        if(v == btn1){
            menu.setHeaderTitle("배경색 변경");
            menu.add(0,1,0,"배경색(빨강)");
            menu.add(0,2,0,"배경색(초록)");
            menu.add(0,3,0,"배경색(파랑)");
        }
        if(v == btn2){
            menu.setHeaderTitle("버튼 변경");
            menu.add(1,1,0,"버튼 45도 회전");
            menu.add(1,2,0,"버튼 2배 확대");

        }
    }

    @Override
    public boolean onContextItemSelected(@NonNull MenuItem item) {
        switch(item.getGroupId()){
            case 0:
                switch(item.getItemId()){
                    case 1:
                        baseLayout.setBackgroundColor(Color.RED);
                        return true;
                    case 2:
                        baseLayout.setBackgroundColor(Color.GREEN);
                        return true;
                    case 3:
                        baseLayout.setBackgroundColor(Color.BLUE);
                        return true;
                }
            case 1:
                switch(item.getItemId()){
                    case 1:
                        btn2.setRotation(45);
                        return true;
                    case 2:
                        btn2.setScaleX(2);
                        return true;
                }
        }
        return false;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("배경색 바꾸기(컨텍스트 메뉴)");

        baseLayout = (LinearLayout)findViewById(R.id.baseLayout);
        btn1 = (Button)findViewById(R.id.btn1);
        btn2 = (Button)findViewById(R.id.btn2);

        registerForContextMenu(btn1);
        registerForContextMenu(btn2);

    }
}

 

나는 그룹 id를 썼는데 그냥 개인 id를 다 다르게 해서 구분해도 된다. 여기서는 메뉴가 워낙 적다보니 itemid를 다르게 하는게 더 효율적일 것 같다.

 

'모바일' 카테고리의 다른 글

07-3. 메뉴/토스트/다이얼로그 연습  (0) 2021.02.20
07-2. 토스트 & 대화상자  (0) 2021.02.20
06-4. 뷰 컨테이너 연습  (0) 2021.02.19
06-3. 뷰 컨테이너  (0) 2021.02.19
06-2. 기타 위젯  (0) 2021.02.17
Comments