안녕하세요~ 두결입니다.
지난시간에는 랜덤숫자를 로그창에 출력하고, 타이머에서 이미지를 랜덤으로 보여주었습니다.
그리고, 터치이벤트에 대해서 알아보고, ImageView의 터치이벤트를 작성해보았고,
마지막으로 터치이벤트로 이미지 랜덤으로 보여주기 ON / OFF 기능까지 해보았습니다.
이번시간부터는 조금 다른것을 해보겠습니다.
바로 대화상자와 팝업화면입니다.
▣ 새프로젝트 생성하여 Toast로 팝업메세지 띄우기
먼저, 새프로젝트를 생성해보겠습니다.
새프로젝트 생성하는 과정은 많이 했으니까 이제부터는 그냥넘어가겠습니다.
PoupTest라는 프로젝트를 생성하였습니다.
저희는 이미 간단한 팝업창을 띄우는 것을 배웠었습니다.
바로 Toast였죠?
앱이 시작되자마자 Toast로 팝업메세지를 하나 띄워보겠습니다.
setContentView(R.layout.activity_main);
Toast.makeText(getApplicationContext(), "팝업메세지 잘뜨나?",Toast.LENGTH_SHORT).show();
네, 위와같이
Toast.makeText().show()로 팝업메세지를 띄울수 있습니다.

네, "Hello World!"가 보이고 화면 아래쪽에
"팝업메세지 잘뜨나?"라는 팝업메세지창이 보이네요 ^^
▣ 종료버튼으로 앱 종료하기, finish()와 finishAndRemoveTask() 함수 사용하기
이제 버튼을 하나 만들고 그 버튼을 누르면 앱을 종료시켜보도록 하겠습니다.

위와같이 버튼을 하나 갖다놓구요~
<Button
android:id="@+id/btnExit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="앱종료"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5" />
XML코드에서
ID는 btnExit라고 하고
text는 "앱종료"라고 하겠습니다.
그리고, 화면의 정중앙에 위치하게 하였습니다.
이제 이 버튼을 터치하면 앱이 종료되게 해보겠습니다.
button click이벤트에서 처리하면 되겠죠?
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
위와같이 btn_Exit라는 객체를 생성하고
setOnClickListener를 등록한 후에
onClick()함수안에서 앱을 종료시키면 됩니다.
앱을 종료시키는 명령어는
finish()입니다.
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
위와같이 onClick()함수안에서 finish()로 앱을 종료시켰습니다.
하지만, 이 finish()함수는 현재 Activity를 종료하는것이라 백그라운드에는 계속 남아있습니다.
따라서, 앱을 완전히 종료하고 싶다면
finishAndRemoveTask() 함수를 써야합니다.
finish()함수가 액티비티를 종료하고 백그라운드로 보내는 함수라서 앱은 보이지만 않을뿐 목록에 계속 남아있고 해당 리소스도 완전히 회수되지 않습니다.
반면에
finishAndRemoveTask()함수는 액티비티를 종료하고 백그라운드에서도 제거하는 함수라서 목록에서도 지워지고 리소스도 완전히 회수하게 됩니다.
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finishAndRemoveTask(); // 앱 완전 종료!!
}
});
위와같이
finishAndRemoveTask()함수를 사용해서 앱을 완전히 종료하였습니다.
▣ 종료시, 종료확인 다이얼로그 띄우기
자, 이제 종료버튼을 누를때 바로 종료하지 않고
확인메세지를 띄워보도록 하겠습니다.
보통 앱에서도 종료버튼 누른다고 바로 종료되지 않는 경우가 있죠?

위 사진은 직방앱인데요..
종료버튼 (뒤로가기) 눌렀을때
종료하시겠습니까?를 물어보고 예, 아니오로 선택하게 합니다.
위와같이 사용자의 입력을 기다리는 간단한 창을 다이얼로그라고 합니다.
팝업창은 다이얼로그보다 훨씬 많은 작업을 할수 있죠~
암튼, 이번시간에 해볼내용이 바로 저 종료확인 다이얼로그창입니다.
다이얼로그창은 AlertDialog.Builder를 사용해서 띄울수 있습니다.
그럼, 지금부터
AlertDialog.Builder를 사용해보도록 하겠습니다.
AlertDialog.Builder는 사용자의 응답을 요청하거나 추가정보를 입력받기 위해 표시되는 작은 창(AlertDialog)을 생성하고 설정하는데 사용되는 클래스입니다.
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("앱을 종료하시겠습니까?");
builder.show();
// finishAndRemoveTask(); // 앱 완전 종료!!
}
});
onClick()함수 안에서
AlertDialog.Builder 객체를 생성하였는데요~
여기에서보면 AlertDialog.Builder(MainActivity.tihs); 라고 되어있습니다.
보통 Java에서 this라고 하면 현재 자신의 객체를 이야기하는데요~
버튼의 onClick()함수에서 this라고 하면 Main이 아닌 버튼을 가리키게됩니다.
그래서, 명시적으로 MainActivity.this라고 써주었습니다.
그리고, builder.setMessage()로 다이얼로그에 띄울 메세지를 설정해주고요
builder.show()로 다이얼로그를 띄웠습니다.
한번 실행해보겠습니다.

네 위와같이
"앱을 종료하시겠습니까?"라는 다이얼로그 창이 잘 보이네요..^^
자, 이제 여기에 타이틀도 추가해보겠습니다.
타이틀은 setTitle()함수로 해주면 됩니다.
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("앱 종료!");
builder.setMessage("앱을 종료하시겠습니까?");
builder.show();
// finishAndRemoveTask(); // 앱 완전 종료!!
}
});
버튼의 onClick()함수에서
builder.setTitle("앱 종료!");라고 설정해 주었습니다.
실행해볼까요?

네. 다이얼로그에 타이틀이 잘 보이네요..^^
▣ 종료확인 다이얼로그에 예, 아니오 추가하기, 대화상자 뜬상태에서 외부터치 안되게 하기
마지막으로 예, 아니오를 추가해보도록 하겠습니다.
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("앱 종료!");
builder.setMessage("앱을 종료하시겠습니까?");
builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 예 버튼 클릭시 동작.
}
});
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 아니오 버튼 클릭시 동작.
}
});
builder.show();
// finishAndRemoveTask(); // 앱 완전 종료!!
}
예, 아니오 버튼을 넣는 방법은 위와같이
AlertDialog.Builder의 setPositiveButton(), setNegativeButton()함수로 할수 있습니다.
setPositiveButton()은 다이얼로그 창에서 "긍정적인" 동작을 하는 버튼을 추가할 때 사용하는 함수입니다.
DialogInterface.OnClickListener()를 등록해서 onClick()함수에서 실제 수행할 동작을 추가하면 됩니다.
반면에
setNegativeButton()은 다이얼로그 창에서 "부정적인" 동작을 하는 버튼을 추가할 때 사용하는 함수입니다.
DialogInterface.OnClickListener()를 등록해서 onClick()함수에서 실제 수행할 동작을 추가해주면 됩니다.
자, 이제 "예" 버튼을 누를때는 앱을 종료시키고
"아니오"일때는 별다른 코드를 추가할 필요는 없겠네요~
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("앱 종료!");
builder.setMessage("앱을 종료하시겠습니까?");
builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 예 버튼 클릭시 동작.
finishAndRemoveTask(); // 앱 완전 종료!!
}
});
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 아니오 버튼 클릭시 동작.
}
});
builder.show();
}
});
네, 위와같이 "예" 버튼 클릭시
finishAndRemoveTask()로 앱을 완전히 종료시켰습니다.
실행해볼까요?

네, 위와같이 "아니오", "예"버튼이 잘보이네요~
"예"를 누르면 앱이 종료되고, "아니오"를 누르면 원래화면으로 돌아갑니다.
아! 여기서 한가지 더 추가해보겠습니다.
종료확인 대화상자가 뜬 상태에서 화면의 다른곳을 터치한다면 어떻게 될까요?
네.. 대화상자는 사라지게됩니다.
그러면 안되겠죠?
그래서 이 종료확인 대화상자가 뜬 상태에서는 외부터치가 안되도록 해보겠습니다.
방법은 간단합니다.
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("앱 종료!");
builder.setMessage("앱을 종료하시겠습니까?");
builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 예 버튼 클릭시 동작.
finishAndRemoveTask(); // 앱 완전 종료!!
}
});
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 아니오 버튼 클릭시 동작.
}
});
builder.setCancelable(false); // 외부터치 안되게.. 다이얼로그 닫기방지
builder.show();
}
위와같이
setCancelable(false); 만 해주면 됩니다.
setCancelable()함수는 사용자가 다이얼로그 외부를 터치하거나 뒤로가기 버튼을 눌렀을때 다이얼로그가 자동으로 닫히는 것을 막아주는 함수입니다.
실행을 해보면
다이얼로그가 뜬상태에서는 외부터치도 안되고 뒤로가기버튼도 안먹는 것을 확인할 수 있습니다.
전체 소스입니다. 참고하세요~
MainActivity.java
package com.example.popuptest;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
Toast.makeText(getApplicationContext(), "팝업메세지 잘뜨나?",Toast.LENGTH_SHORT).show();
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("앱 종료!");
builder.setMessage("앱을 종료하시겠습니까?");
builder.setPositiveButton("예", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 예 버튼 클릭시 동작.
finishAndRemoveTask(); // 앱 완전 종료!!
}
});
builder.setNegativeButton("아니오", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 아니오 버튼 클릭시 동작.
}
});
builder.setCancelable(false); // 외부터치 안되게.. 다이얼로그 닫기방지
builder.show();
}
});
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
}
자, 이번시간은 여기까지만 하도록 하구요~
다음시간에는 팝업화면에 대해서 알아보도록 하겠습니다.
그럼, 이만~
감사합니다. ^^
