본문 바로가기
코딩일기/android studio

안드로이드 독학 15일차 : 컨텍스트 액션 모드(Context ActionMode)

by 욱파이어니어 2021. 3. 30.
728x90
반응형

콘텍스트 메뉴는 플로팅 콘텍스트 메뉴와 비슷하게 특정 뷰를 길게 누르면 나타나는 메뉴이다.

하지만 이건 프로팅과는 다르게 길게 누르면 상단에 있는 액션바에 표시가 된다.

위에 크게 동그라미 친 부분이 액션 바이고 그 안에 작은 동그라미들이 콘텍스트 액션 모드로 만든 메뉴들이다.

 

자 그럼 이것도 마찬가지로 어떻게 만들었는지 한번 xml로 보자.

이번에는 drawable 파일에서 아이콘을 만들기 위해서 Vectorn Asset를 활용했다 이 부분은 

핸드폰에 기본으로 저장되어 있는 아이콘들을 사용할수 있는 부분이다.

 

이렇게 해서 들어가면 

 

이런 화면이 나오는데 노란색 쳐진 부분을 클릭하면 다양한 아이콘들이 나와있는 것을 볼 수가 있다.

그러고 나서 ok 누르고 만들면

아래와 같이 해당 아이콘의 설정을 할 수 있는 xml파일이 만들어진다.

하지만 일단은 기본 설정으로 해서 아이콘 두 개를 만들어주자.

 

아이콘 두개를 만들었다면 이제 해당 아이콘으로 메뉴 item 설정해줘야 한다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/refresh"
        android:title="새로고침"
        android:icon="@drawable/ic_refresh"/>
    <item
        android:id="@+id/error"
        android:title="오류발생"
        android:icon="@drawable/ic_error"/>
</menu>

이렇게 설정을 하고 나면 옆에 화면은 이렇게 나올 것이다.

하지만 걱정하지 말아라 우리는 이미 이전에도 했듯이 다른 데다가 붙일 거기 때문에 붙이면은 

우리가 설정해놓은 아이콘들이 설정돼서 나온다.

 

자그럼 이제 xml을 완료했으니 

자바 소스를 보자.

public class MainActivity extends AppCompatActivity {

    //actionMode로 하면 기존에 액션모드 콜백 메소드에서의 actionMode와 겹쳐서 다른 이름 해야함
    private ActionMode mactionMode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView t1 = (TextView) findViewById(R.id.contextMenu);
        //해당 뷰에 context menu를 붙여두는것
        t1.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                Log.v("롱터치", "호호");
                if (mactionMode != null) {
                    //actionMode가 이미 발생되어 있다면 다시 actionMode를 발생시키고 싶지 않기때문에
                    return false;
                }
                //위에서 만든 mactionMode에서 아래에서 설정한 actionModeCallBack으로 액션모드를 시작한다.
                mactionMode = startActionMode(actionModeCallBack);
                
                return true; //다른 클릭 리스너 발생시키지 않게 하기 위해서 true로 함
            }
        });
    }
    //컨텍스트 액션모드를 생성,선택,준비 파괴됐을때를 정의해주는 actionModeCallBack를 생성한다.
    private ActionMode.Callback actionModeCallBack = new ActionMode.Callback() {
        @Override
        //메뉴의 생성시 들어가는곳
        public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
            //getMenuInflator 가져와서 만든 xml로 inflate 시켜준다.
            Log.v("액션빔!", "으악");
            actionMode.getMenuInflater().inflate(R.menu.context_actionmode, menu);
            actionMode.setTitle("옵션을 선택하세요");
            return true; //다른 이벤트들을 받기 위해서 true 반환
        }

        @Override
        //메뉴의 준비시 호출
        public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
            return false;
        }

        @Override
        //메뉴안에 아이템 선택시 호출
        public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
            switch (menuItem.getItemId()) {
                case R.id.refresh:
                    Toast.makeText(getApplicationContext(), "새로고침 완료", Toast.LENGTH_SHORT).show();
                    actionMode.finish(); //액션모드를 끝냄
                    return true; //true를 줌으로써 다른 이벤트도 받을수 있게 함
                case R.id.error:
                    Toast.makeText(getApplicationContext(), "에러발생", Toast.LENGTH_SHORT).show();
                    actionMode.finish();
                    return true;
                default:
                    return false;

            }
        }

        @Override
        //메뉴 파괴시 호출
        public void onDestroyActionMode(ActionMode actionMode) {
            //파괴되면 mactionMode를 다시 null로 바꿔서 또다시 컨텍스트 액션모드를 받을수 있게 함
            mactionMode = null;
        }
    };
}

뭐 일단 순서를 얘기하자면 

onCreate에서 텍스트뷰에다가 콘텍스트 액션 모드를 연결시켜준다.

그러고 나서 해당 텍스트 뷰가 오랫동안 클릭이 되면 액션 모드를 실행시키는 것이다.

그러고 나서 액션 모드가 끝나면 mactionMode를 null로 바꿔서 다시 받을 수 있게 한다.

 

자세한 설명은 주석을 달아놨으니 확인해보면 될 것 같다.

 

반응형