[Android Studio] 안드로이드 스튜디오를 이용한 UI/프론트 공부 #7

Neta·2023년 12월 3일

[AndroidStudio]

목록 보기
7/8

Main

안드로이드 어플리케이션을 만들 때 사용하는 Android Studio를 통해 UI 및 프론트에 대한 공부를 하며 그 내용들을 기록하고자 이렇게 글을 작성한다.

개발언어는 Java와 Kotlin 중 Java를 채택하여 학습하였다. Kotlin은 사용해 본 적이 없으나 Java의 경우 기본적인 기능들을 사용해 본 적이 있어 이를 선택하게 되었다.

UI 구조 확인

UI구조

이번에는 RadioButton 기능을 한 번 사용해 볼 것이다.
상단의 왼쪽,가운데,오른쪽 라디오 버튼은 그냥 끌어다 놓아 각자 개별적인 것으로 취급한다.
상단 우측의 색상 세 가지는 라디오 그룹으로 구성되어 셋 중 하나를 선택하면 나머지가 선택되어 있을 때 선택이 해제된다.
아래의 대학교, 학과도 마찬가지로 라디오 그룹으로 분류 해 두었다.

'라디오 버튼'이라는 이름이 익숙할 수 있다. 라디오 버튼이 어떤 것인지 한 번 알아보고 코드를 작성 해 보도록 하자.

라디오 버튼(RadioButton) 이 무엇일까?

라디오 버튼(RadioButton) 은 사용자가 여러 옵션 중 하나를 선택할 수 있도록 하는 UI 구성요소이다.

라디오 버튼은 일반적으로 라디오 그룹(RadioGroup) 내에 배치되는 요소이다.
그룹 내의 라디오 버튼 중 하나만 선택할 수 있도록 하나의 라디오 버튼이 선택되면, 다른 라디오 버튼은 자동으로 선택 해제된다.

라디오 버튼의 개념은 위와 같다. 이제 라디오 버튼을 활용하는 방법을 알아보도록 하겠다.

라디오 버튼만 활용 해 보기

이번에는 별도의 시나리오는 정해져있지 않고, 개별 라디오 버튼으로 놔뒀을 때와 라디오 그룹으로 라디오 버튼들을 묶었을 때의 차이를 한 번 알아볼 것이다.

라디오 버튼만 사용하는 코드 작성하기

  1. 객체참조변수를 먼저 생성
public class MainActivity extends AppCompatActivity {
    TextView txtMessage;
    // 라디오버튼의 동작을 확인할 텍스트 뷰
    RadioButton rdoLeft, rdoCenter, rdoRight; // 왼쪽 중간 오른쪽은 각각 별개의 버튼이므로 따로 정의함.
    ... 
    }
  • 매 번 코드를 작성할 때는 무조건 객체참조변수를 먼저 생성한다.
  1. 생성한 객체참조변수에 각 버튼의 ID를 할당
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    txtMessage = (TextView) findViewById(R.id.textView1); //txtMessage변수에 textView1의 id를 할당해 수정 가능하게 만듬
  1. 라디오 버튼 테스트를 위한 정렬 버튼 세팅 메소드 작성
public void settingGravity() { //정렬 버튼 세팅 메소드
    rdoLeft = (RadioButton) findViewById(R.id.radioButton1);
    rdoCenter = (RadioButton) findViewById(R.id.radioButton2);
    rdoRight = (RadioButton) findViewById(R.id.radioButton3);
    // 일반 버튼이나 라디오버튼이나 기본적으로 클릭 기능이 주가 됨.
    // 다만 각각 무명클래스로 다 만들려고 하면 힘들기 때문에 이벤트를 사용해 간소화함

    // 라디오 버튼 초기화, 최초에는 가운데에 존재하기 때문에 가운데 정렬 라디오 버튼은 클릭된 상태로 시작되야 함.
   rdoCenter.setChecked(true);

   rdoLeft.setOnClickListener(new SettingGravityListener());
   rdoCenter.setOnClickListener(new SettingGravityListener());
   rdoRight.setOnClickListener(new SettingGravityListener());
}
  • 버튼은 일반 버튼이나 라디오 버튼이나 기본적으로 클릭 기능이 존재함
    • 다만 각 라디오 버튼들을 모두 무명 클래스로 만드려면 라인이 너무 길어지기 때문에 이벤트를 사용해 간소화함
  • 정렬을 시키는 라디오 버튼이므로 기본 정렬 조건에 맞는 라디오 버튼이 최초에 체크되어 있도록 선택해야 함
  • 다만 각 라디오 버튼은 별도이기 때문에 버튼 클릭 이벤트를 처리하는 리스너 클래스를 만들어 주어야 함

라디오 버튼 클릭 이벤트 처리 리스너 클래스 만들기

위의 별도 라디오 버튼들에 대해서 한 번에 묶어서 처리할 수 있는 리스너 클래스를 만들 필요가 있어 onClickListener을 가지는 SettingGravityListener 클래스를 만든다.

public class SettingGravityListener implements View.OnClickListener {
    @Override
    public void onClick(View view) {
        // 어떤 라디오버튼을 클릭한건지 getID를 통해 구분하고자 함
        if(view.getId() == R.id.radioButton1) {
            // 왼쪽 정렬(단순히 왼쪽으로 이동하라고 했기 때문에 좌측 상단으로 이동됨, 세로축 중앙에서만 이동하려면 CENTER_VERTICAL 추가해야)
            txtMessage.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
            //문제점 해결방안
            rdoCenter.setChecked(false);
            rdoRight.setChecked(false);
        }
        else if(view.getId() == R.id.radioButton2) {
            // 중앙 정렬
            txtMessage.setGravity(Gravity.CENTER | Gravity.CENTER_VERTICAL);

            rdoLeft.setChecked(false);
            rdoRight.setChecked(false);
        }
        else if(view.getId() == R.id.radioButton3) {
            // 오른쪽 정렬
            txtMessage.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);

            rdoLeft.setChecked(false);
            rdoCenter.setChecked(false);
        }
        // 문제점: 버튼 체크시 다른 버튼 체크가 해제되는 기능은 그룹화가 안 되어 있기 때문에 이 코드처럼 별도로 구현해야 함
        // 그룹으로 생성하게 되면 이러한 문제점을 별도로 코드를 작성해 해결할 필요가 없어짐.
    }
}
  • 개별적인 라디오 버튼들의 하나의 요소를 제어하기 때문에 하나의 리스너 클래스에 통합하여 이벤트 처리를 수행한다.
  • if문의 조건문에 view.getId()를 넣어 어떤 라디오 버튼이 클릭되었는지 확인한 후 라디오 버튼의 동작을 정의한다.

정리

라디오 버튼만 사용하게 되면 각 라디오 버튼들이 그룹 처리가 되어있지 않기 때문에 여러 라디오 버튼이 한 요소에 대해서만 제어를 하려고 하면 하나가 클릭될 때 나머지 라디오 버튼들이 해제되는 기능이 힐요하다.

그러나 이런 기능은 라디오 버튼들이 묶여있지 않기 때문에 코드를 별도로 작성하여 지금 위에서 작성한 것과 같이 버튼 클릭 이벤트에 맞추어 체크 여부를 제어하게 만들 필요성이 생긴다.

이런 단점을 해결하기 위해서 라디오 그룹을 사용한다

라디오 그룹을 활용 해 보기

라디오 버튼만 사용하게 되었을 시의 단점을 해결할 수 있는 것이 라디오 그룹을 활용하는 것이다.
라디오 그룹을 활용하면 코드 자체를 줄일 수 있다.

  1. 객체참조변수 생성
public class MainActivity extends AppCompatActivity {
    RadioGroup rgpColor;
    RadioGroup rgpUniversity, rgpDepart;
    String msgUniv, msgDepart;
    Button btnOutput;
    RadioButton rdoSelect; // 어떤 라디오 버튼 선택되었는지 받아줄 객체참조변수(하단의 두 라디오 그룹에 존재하는 6개 라디오 버튼이 대상)
    ...
  1. 생성한 객체참조변수에 각 그룹의 ID를 할당 등..
// 학교, 학과 라디오 그룹 처리
rgpUniversity = (RadioGroup) findViewById(R.id.group_univ);
rgpDepart = (RadioGroup) findViewById(R.id.group_depart);
// 기본으로 선택되는 버튼 설정
rgpUniversity.check(R.id.radioButton7);
rgpDepart.check(R.id.radioButton10);
// 두 라디오 그룹에 이벤트 리스너 장착
rgpUniversity.setOnCheckedChangeListener(new UnivChangeListener1());
rgpDepart.setOnCheckedChangeListener(new UnivChangeListener1());
  • 앞에서 말한 것 처럼 기본으로 선택되는 버튼을 설정 해 두어야 한다.

라디오 그룹에 대한 기본 설정이 완료되었다. 이제 아까 작성하지 않은 색상 변경 버튼을 한 번 구현하도록 하겠다.

  1. 색상 설정 버튼을 세팅하기 위한 메소드
public void settingColor() { //색상 설정 버튼 세팅 메소드
    rgpColor = (RadioGroup) findViewById(R.id.group_color);
    // 일그룹 내의 라디오 버튼 초기화, 최초 시작시 설정값이 초록
    // 라디오그룹은 알아서 하나 선택하면 원래 선택한 버튼 해제됨. 별도 구현 없이 하나만 선택 가능함
    rgpColor.check(R.id.radioButton5);
    txtMessage.setTextColor(Color.GREEN);

    rgpColor.setOnCheckedChangeListener(new SettingColorListener());
}
  • 여기까지는 정렬 버튼과 큰 차이는 나지 않는다.
  1. 라디오 그룹 선택 이벤트 처리 리스너 생성
  • 여기서는 이벤트 처리 리스너를 만들기 위해 CheckedChangeListener 을 사용한다.
public class SettingColorListener implements RadioGroup.OnCheckedChangeListener {
    // 색상 라디오 버튼 체크시마다 색상이 변화되어야 하므로 이를 수행하는 클래스
    // 컴파운드 버튼의 내부클래스로 정의되는 리스너도 있는데, 이는 체크박스의 성질을 가지는 버튼을 의미함
    @Override
	public void onCheckedChanged(RadioGroup radioGroup, int i) {
    	// 자동생성되는 콜백메소드
    	// 여기서 radioGroup은 내가 선택한 그룹의 정보를 매개변수로 넘겨받는 것을 의미함
    	// radioGroup: 사용자가 선택한 라디오 그룹 | i: 그룹에서 선택한 라디오 버튼의 id값
    	//eventTest1(i);
    	eventTest2();
	}
}

여기 주석처리한 eventTest1(i)eventTest2()로 두 개의 메소드 호출이 보이는데, 두 메소드는 동일한 기능을 하나 각자의 기능이 다르다. 이를 한 번 알아보도록 하자

  1. eventTest1(i)
//라디오 그룹 내의 라디오 버튼 처리 예시 1(색변환 예시, 두 가지의 처리방법을 알아보기 위해 사용)
public void eventTest1(int CheckedID) {
    if(CheckedID == R.id.radioButton4)
        txtMessage.setTextColor(Color.RED);
    else if(CheckedID == R.id.radioButton5)
        txtMessage.setTextColor(Color.GREEN);
    else if(CheckedID == R.id.radioButton6)
        txtMessage.setTextColor(Color.BLUE);
}
//여기까지가 첫 번째 방식
  1. eventTest2()
//라디오 그룹 내의 라디오 버튼 처리 예시 2
public void eventTest2() {
    // 1번과 같은 동작이지만 코드 형태를 변형하여 수행해 볼 것
    // 매개변수로 넘겨주지 않아도 어떤 버튼 선택된 것인지 알 수 있는 방법 존재
    // 선택한 라디오 버튼의 체크 정보를 넘겨받지 않음. 받는 정보 없이 구현 가능함 = 외부에서 선언한 rgpColor을 사용함
    if (rgpColor.getCheckedRadioButtonId() == R.id.radioButton4)
        txtMessage.setTextColor(Color.RED);
    else if (rgpColor.getCheckedRadioButtonId() == R.id.radioButton5)
        txtMessage.setTextColor(Color.GREEN);
    else
        txtMessage.setTextColor(Color.BLUE);

    // 해당 방법과 1번은 동일한 기능 구현임. 다만, 그룹을 통해 id정보를 받느냐 아니면 매개변수로 받느냐의 차이가 존재하는 것
}

둘은 코드의 구성이 다르다, 차이점이라고 하면 매개변수가 존재하는지 아닌지에서 차이가 존재한다.

정리

라디오 그룹은 개별 라디오 버튼으로 작업 등을 수행하고자 하면 코드의 길이가 길어지는 문제를 해결할 수 있는 방법이다. 다른 방향으로 활용하는 방향을 알아보도록 하자.

라디오 그룹 활용하기 (2)

위에서 선언해 둔 객체참조변수를 사용하도록 할 것이다. 선언한 객체참조변수들은 각 그룹별로 선택한 라디오 버튼 하나씩 총 두 개의 정보를 가지고 출력 버튼을 누를 시 텍스트 뷰에 띄우도록 만든다.

이를 위한 코드를 작성 해 보자.

  1. 객체참조변수는 전부 할당 해 두었으므로 각 라디오 그룹의 선택 이벤트를 처리하는 리스너를 생성
  • 여기서는 리스너를 생성하는 방법이 총 두가지가 존재한다.

선택 이벤트 처리 리스너 1.

// 학교, 학과 라디오 버튼 선택 이벤트 리스너 1
// 동일 동작에 대해 구현방법은 두 가지로 시도해 볼 것
public class UnivChangeListener1 implements RadioGroup.OnCheckedChangeListener {
    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int i) {
        // 선택한 라디오 그룹을 구분하여 구현
        if (radioGroup == rgpUniversity) {
            if (i ==R.id.radioButton7) {
                msgUniv = "한국대학교";
            }
            else if (i == R.id.radioButton8) {
                msgUniv = "서울대학교";
            }
            else if (i == R.id.radioButton9) {
                msgUniv = "경북대학교";
            }
            //Toast.makeText(MainActivity.this, msgUniv, Toast.LENGTH_SHORT).show();
        }
        else if (radioGroup == rgpDepart) {
            if (i ==R.id.radioButton10) {
                msgDepart = "전자공학과";
            }
            else if (i == R.id.radioButton11) {
                msgDepart = "컴퓨터공학과";
            }
            else if (i == R.id.radioButton12) {
                msgDepart = "모바일공학과";
            }
            //Toast.makeText(MainActivity.this, msgDepart, Toast.LENGTH_SHORT).show();
        }
        // 단순히 생각할 수 있는 일반적인 구현방법
    }
}

선택 이벤트 처리 리스너 2.

// 학교, 학과 라디오 버튼 선택 리스너 2 (간결한 구현방법(다양한 메소드, 함수 사용해 라인 줄이기))
public class UnivChangeListener2 implements RadioGroup.OnCheckedChangeListener {
    @Override
    public void onCheckedChanged(RadioGroup radioGroup, int i) {
        rdoSelect = (RadioButton) findViewById(radioGroup.getCheckedRadioButtonId());
        if (radioGroup == rgpUniversity)
            msgUniv = rdoSelect.getText().toString();
        else if (radioGroup == rgpDepart)
            msgDepart = rdoSelect.getText().toString();
    }
    // 1번 방식보다 훨씬 길이가 짧아짐
}

여기서 두 리스너 구현 결과는 동일하다. 동일한 기능을 구현하는데 있어 코드의 길이가 차이나는 이유는 다양한 메소드와 함수를 사용하였기 때문이다.

이러한 차이점을 보며 코드 작성을 간결하게 하는 것이 좋다는 점을 좀 느낄 수 있었다.

  1. 생성한 리스너를 통해 처리된 결과값을 출력하는 '출력'버튼을 구현
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

	기존 코드 생략..

    //출력버튼 정의
    btnOutput = (Button) findViewById(R.id.button1);
    btnOutput.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            txtMessage.setText(msgUniv + " " + msgDepart);
        }
});

이렇게 구현하면 최종적으로 원하는 기능이 수행된다.

마무리

이번에는 라디오 버튼 / 라디오 그룹을 한 번 만들어서 어떤 기능을 할 수 있는지, 어떻게 사용하는지를 알아보았다.
별도로 사용하는 것과 그룹으로 사용하는 것의 차이를 느껴보고 나니 확실히 그룹으로 묶는 것이 활용이 편한 것을 알 수 있었다.

지금까지 다양한 버튼들을 활용 해 보고, 점차 시나리오를 별도로 구상해서 그에 맞는 버튼 활용을 해 보고 있는 점에서 응용한다면 간단한 어플리케이션을 구현할 때 사용할 수 있을 것으로 보인다.

profile
Neta의 개발 공부 블로그

0개의 댓글