<액션바>

액션바는 앱의 제목(Title)이 보이는 위쪽 부분이다.

옵션 메뉴는 액션바에 포함되어 보이도록 만들어짐

 

<메뉴의 종류>

  • 옵션 메뉴 : 시스템 [메뉴] 버튼을 눌렀을 때 나타나는 메뉴. 각 화면마다 설정할 수 있음
  • 컨텍스트 메뉴 : 화면을 길게 누르면 나타나는 메뉴. 텍스트뷰의 편집을 바꾸거나 할 때 사용됨 (ex. 복사, 붙여넣기)

. 메뉴는 각각의 액티비티마다 설정할 수 있다.

<메뉴를 추가하기 위한 메서드>

  • onCreateOptionMenu(Menu menu)
  • onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)

Menu나 ContextMenu 객체의 add 메서드를 사용해서 메뉴 아이템을 추가할 수 있다.

(그렇지만 add로 메뉴를 추가하는 것보다는 XML에서 메뉴를 추가한 뒤 객체로 로딩해오는 게 더 간단하니까.. 그냥 알고만 넘어가자.)

  • MenuItem add(int groupId, int itemId, int order, @@ title) // @@는 CharSequence 또는 int
  • SubMenu addSubMenu(int titleRes) // 아이템이 많아서 서브 메뉴로 추가하고 싶을 때 사용

groupId : 아이템을 하나의 그룹으로 묶을 때 사용함.

itmeId : 아이템이 갖는 고유 ID 값 (아이템이 선택되었을 때 각각의 아이템을 구분할 수 있음)

 

<액션바 - 상단에 메뉴기능 넣기>

1. 새 프로젝트를 만든 후, res에 menu 폴더를 추가한다.

폴더 이름은 반드시 menu여야 한다. 그래야 메뉴를 위한 XML 파일이 만들어진다.

menu 폴더에 menu_main.xml 이라는 이름의 파일을 추가한다.

 

메뉴 파일을 만들면 아래와 같이 Palette의 내용이 바뀐 것을 확인할 수 있다.

 

2. <menu_main.xml>

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

    <item android:id="@+id/menu_refresh"
        android:title="새로고침"
        android:icon="@android:drawable/ic_popup_sync"
        app:showAsAction="always"/>

    <item android:id="@+id/menu_search"
        android:title="검색"
        android:icon = "@android:drawable/ic_menu_search"
        app:showAsAction="always"/>

    <item android:id="@+id/menu_settings"
        android:title="설정"
        android:icon="@android:drawable/ic_menu_manage"
        app:showAsAction="always"/>

</menu>

xmlns:app을 추가해준다. 그래야 item 태그 안의 showAsAction이 실행되기 때문이다.

 

<showAsAction 속성 값>

  • always : 항상 표시
  • never : 표시 X (디폴트값)
  • ifRoom : 여유 공간이 있을 때만 표시
  • withText : title 속성으로 설정된 제목을 같이 표시
  • collapseActioinView : 아이템에 설정한 뷰(actionViewLayout으로 설정한 뷰)의 아이콘만 표시

3. <MainActivity.java>

package com.example.chapter5_3;

public class MainActivity extends AppCompatActivity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        //Toast.makeText(this, "되냐?",Toast.LENGTH_LONG).show();
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        //int curId = item.getItemId();
        String curTitle = item.getTitle().toString();
        Toast.makeText(this, curTitle+" 메뉴가 선택되었습니다.", Toast.LENGTH_LONG).show();
        return super.onOptionsItemSelected(item);
    }

}

 

3 - (1) onCreateOptionsMenu

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

이 메서드는 액티비티가 만들어질 때 미리 자동 호출되어, 화면에 메뉴 기능을 추가한다.

 

문제 발생 : 메뉴바가 만들어지지 않음. onCreateOptionsMenu()가 호출되지 않는 문제가 생김.

원인 : res > values > themes.xml 파일의 style 기본 디폴트값이 NoActionBar라서 그럼. (빡치네)

해결 : Theme.Design.Light로 바꿔주면 해결. (걍 디폴트값을 이걸로 하지.. 궁시렁궁시렁)

 

onCreateOptionsMenu() 호출이 안될때

앱 화면에 메뉴바를 만들때 사용하는 방법 중 하나가 Android Resource Directory/menu에 관련 xml을 만들고 그것을 Activity의 onCreateOptionsMenu()에서 inflate하는 방법이다.코드는 이런식일 것이다.res/menu/o

velog.io

(+참고로 소스코드에서 액션바를 보이게 만들고 싶으면 show()를, 감추고 싶다면 hide()를 사용하면 된다고 한다.

Theme.Design.Light 인 경우엔 액션바가 기본적으로 보이기 때문에 없애고 싶으면 hide()를 사용하면 되겠다.)

ActionBar abar = getActionBar();
abar.show();
abar.hide();

 

3 - (2) onOptionsItemSelected

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    String curTitle = item.getTitle().toString();
    Toast.makeText(this, curTitle+" 메뉴가 선택되었습니다.", Toast.LENGTH_LONG).show();
    return super.onOptionsItemSelected(item);
}

메뉴의 item이 선택되었을 경우, getTitle이나 getId 등의 메서드를 사용하여 값을 가져온 뒤 토스트로 값을 띄운다.

 

3 - (3) 추가내용

  • PrepareOptionMenu : 화면이 띄워진 후에 메뉴를 바꾸고 싶다면 이 메서드를 재정의하여 사용하면 된다.
  • registerForContextMenu : 컨텍스트 메뉴를 특정 뷰에 등록하고 싶을 때 사용하는 메서드
  • onContextItemSelected : 위 메서드로 컨텍스트 메뉴를 등록하면, 메뉴 아이템 선택 시 이 메서드가 호출된다.

 

4. 실행결과

아래 사진을 보면 메뉴바의 오른쪽 상단에 아이콘 3개가 추가된 것을 확인할 수 있다.

(아니 근데 설정에 톱니바퀴 아이콘 넣으려고 했는데, 기본 아이콘에 없었음. 이게 왜 없음?)

 

아이콘을 클릭하면 각각의 Title을 토스트 메시지로 띄우는 것을 확인할 수 있다.

 

<버튼을 눌러 액션바에 아이콘 표시하기>

위 프로젝트 이어서 사용한다.

1. activity_main.xml에 버튼을 추가한다.

2. <MainActivity.java>

public class MainActivity extends AppCompatActivity {
    ActionBar abar;

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

        abar = getSupportActionBar();

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                abar.setLogo(R.drawable.bone);
                abar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_USE_LOGO);
            }
        });
    }
    // ... 생략
}

 

2 - (1) getSupportActionBar로 ActionBar 객체를 참조한다.

abar = getSupportActionBar();

 

 

2 - (2) onClick : 버튼 클릭 시 로고 표시

public void onClick(View view) {
     abar.setLogo(R.drawable.bone);
     abar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_USE_LOGO);
}

setLogo로 이미지 파일을 로고로 세팅해준다.

 

<setDisplayOptions의 파라미터 값>

  • DISPLAY_USE_LOGO : 홈 아이콘 부분에 로고 아이콘 사용
  • DISPLAY_SHOW_HOME : 홈 아이콘 표시함
  • DISPLAY_HOME_AS_UP : 홈 아이콘에 뒤로 가기(<) 아이콘을 같이 표시함
  • DISPLAY_SHOW_TITLE : 타이틀을 표시함

3. 실행결과

'액션바 아이콘 바꾸기' 버튼 클릭 시 타이틀 부분에 로고 아이콘(bone 이미지)이 표시된다.

 

 

<액션바에 입력상자 넣기 - 검색어 입력>

위 프로젝트 이어서 사용한다.

1. layout 폴더에 새로운 파일을 만든다. (search_layout.xml)

대충 위와 같이 text와 editText를 배치한다. 자세한 설정은 코드로 작성한다.

<search_layout.xml>

<?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="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="검색"
        android:textSize="16sp"
        android:typeface="serif"
        android:textColor="#ffad8745"/>

    <EditText
        android:id="@+id/editTextText"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="4dp"
        android:inputType="text"
        android:typeface="serif"
        android:imeActionId="1337"
        android:imeOptions="actionDone"/>
</LinearLayout>

 

최상위 레이아웃의 height은 wrap_content로 설정한다.

 

IME는 텍스트 입력기를 의미한다.

imeActionId로 액션버튼이 눌렸을 때의 이벤트 ID를 지정한다. (왜 1337로 지정했는지는 모르겠다. 그리고 이 예제에서 필요한 코드인가? 그것도 모르겠다.)

imeOptions로 키보드에 입력을 마치는 버튼(액션버튼)의 디자인을 바꿀 수 있다.

 

안드로이드 에디트텍스트 속성 4. [imeActionId, imeActionLabel, imeOptions, privateImeOptions] (Android EditText Attr

1. EditText 속성 (4) EditText 속성 리스트 및 요약 설명을 확인하시려면 [안드로이드 에디트텍스트 속성] 페이지를 참고하시기 바랍니다. EditText 속성에 대한 자세한 설명 및 예제를 확인하시려면, 아

recipes4dev.tistory.com

 

2. <menu_main.xml> 수정

<item android:id="@+id/menu_search"
    android:title="검색"
    android:orderInCategory="103"
    app:showAsAction="always"
    app:actionLayout="@layout/search_layout"/>

주의할 점 : title과 orderInCategory는 android:(기본 API 속성), showAsAction과 actionLayout은 app:로 참조하여 추가한다.

 

3. <MainActivity.java> : onCreateOptionsMenu 수정

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

        View v = menu.findItem(R.id.menu_search).getActionView();
        if(v != null){
            EditText editText = v.findViewById(R.id.editTextText);

            if(editText!=null){
                editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                    @Override
                    public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
                        Toast.makeText(getApplicationContext(), "입력됨", Toast.LENGTH_LONG).show();
                        return true;
                    }
                });
            }
        }

 

3 - (1) menu_search 가져오기

View v = menu.findItem(R.id.menu_search).getActionView();

 

3 - (2) menu_search가 존재한다면 수행.

if(v != null){
     EditText editText = v.findViewById(R.id.editTextText);
     //....
}

주의 : findViewById 앞에 v를 붙이지 않는 실수를 했다.

 

3 - (3) editText에 값이 들어온 경우

if(editText!=null){
    editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
            Toast.makeText(getApplicationContext(), "입력됨", Toast.LENGTH_LONG).show();
            return true;
        }
    });
}

setOnEditorListner로 editText 리스너 설정.

 

4. 실행결과

오른쪽 상단에 검색 공간이 생긴다. 입력 후 키보드의 액션버튼을 누르면 "입력됨"이라는 토스트 메시지가 뜬다.