<액션바>
액션바는 앱의 제목(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로 바꿔주면 해결. (걍 디폴트값을 이걸로 하지.. 궁시렁궁시렁)
(+참고로 소스코드에서 액션바를 보이게 만들고 싶으면 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로 키보드에 입력을 마치는 버튼(액션버튼)의 디자인을 바꿀 수 있다.
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. 실행결과
오른쪽 상단에 검색 공간이 생긴다. 입력 후 키보드의 액션버튼을 누르면 "입력됨"이라는 토스트 메시지가 뜬다.
'TIL > 안드로이드 스튜디오' 카테고리의 다른 글
5장 - 뷰페이저 만들기 (ViewPager2) (0) | 2024.12.22 |
---|---|
5장 상단 탭과 하단 탭 만들기 (0) | 2024.12.20 |
5장 - 프래그먼트 수명주기 & 분할화면 만들기 (0) | 2024.12.16 |
5장 - 프래그먼트 기초1 : 2개의 화면전환 (0) | 2024.12.16 |
5장 - Fragment : 액티비티에 프래그먼트 추가하기 (0) | 2024.12.16 |