안녕하세요~ 두결입니다.
지난시간에는 화면을 새로 생성해서 버튼 클릭시 화면을 띄우기를 해보았고, Intent하고 startActivity()에 대해서 알아보았습니다.
또한, 화면의 테마설정 및 팝업화면의 크기와 배경색도 설정해보았습니다.
이번시간에는 팝업화면의 타이틀바 없애는 방법하고, 뒤로가기버튼 막는 방법, 뷰바깥영역 터치안되게 하는 방법에 대해서
알아보도록 하겠습니다.
▣ 팝업화면의 타이틀바 없애기
먼저, 화면의 타이틀바를 없애보도록 하겠습니다.

먼저, 실행화면을 보면
팝업화면에 "PopUpTest"라는 글씨가 써진 타이틀바가 보입니다.
이게 그닥 필요하진 않으니까 없애도록 하겠습니다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE); // 타이틀바 없애기
setContentView(R.layout.activity_popup);
findViewById(R.id.main).setBackgroundColor(Color.parseColor("#ABCDEF"));
타이틀바를 없애는 방법은 위와같이 한줄이면 됩니다.
supportRequestWindowFeature()함수를 이용하면 되는데요~
supportRequestWindowFeature는 앱의 타이틀바같은 창 기능을 활성화하거나 비활성화할때 사용되는 함수입니다.
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
이렇게 해주면 타이틀바가 없어지게 됩니다.
실행해보겠습니다.

네.. 위와같이 타이틀바가 없어졌네요..^^
▣ 뒤로가기 버튼 막기
다음으로 뒤로가기 버튼막기 기능입니다.
팝업화면이 뜬상태에서 뒤로가기 버튼을 누르면 팝업화면이 사라져 버립니다.
그래서, 바로 사라지지 않도록 뒤로가기 버튼을 막아보겠습니다.
supportRequestWindowFeature(Window.FEATURE_NO_TITLE); // 타이틀바 없애기
setContentView(R.layout.activity_popup);
findViewById(R.id.main).setBackgroundColor(Color.parseColor("#ABCDEF"));
// 뒤로가기 버튼 막기
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setEnabled(true); // 뒤로가기 막기
}
};
getOnBackPressedDispatcher().addCallback(this, callback);
코드로 하면 위와같습니다.
onBackPressedCallback은 "뒤로가기" 버튼을 눌렀을때 특정동작을 직접 구현하기 위해 사용되는 콜백 객체입니다.
handleOnBackPressed()함수를 재정의해서 setEnabled(true)를 해주면 뒤로가기 버튼이 동작안되도록 할수 있습니다.
마지막으로
getOnBackPressedDispatcher().addCallback()으로 해당 callback을 등록해주면 됩니다.
여기서 콜백이란 버튼클릭처럼 특정 이벤트가 발생했을때 특정코드를 실행하는 것을 이야기 하는데요
버튼 클릭에서도
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
});
위와같이OnClickListener()에서도 버튼이 클릭되면 리스너에 정의된 onClick() 함수가 호출되는데 이 onClick()함수도 콜백함수입니다.
좀 어렵긴한데...
지금은 그냥 그렇구나 하고 넘어가도록 하겠습니다.
어쨌든, 뒤로가기 버튼 방지 코드를 넣고 실행을 해보면 뒤로가기 버튼을 눌러도 팝업화면이 사라지지 않는 것을 확인할수 있습니다.
▣ 뷰 바깥영역 터치시 강제로 막기
다음으로 뷰 바깥영역 터치시 강제로 막기입니다.
팝업화면이 떠있을때 뒤로가기 버튼은 막았지만.
화면상에 팝업화면이 아닌 다른곳을 터치하면 이때도 팝업화면이 사라집니다.
그래서, 이것도 막아보도록 하겠습니다.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE); // 타이틀바 없애기
setContentView(R.layout.activity_popup);
findViewById(R.id.main).setBackgroundColor(Color.parseColor("#ABCDEF"));
// 뒤로가기 버튼 막기
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setEnabled(true); // 뒤로가기 막기
}
};
getOnBackPressedDispatcher().addCallback(this, callback);
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;
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 뷰 바깥영역 터치시 강제로 막음
if(event.getAction() == MotionEvent.ACTION_OUTSIDE)
{
return false;
}
return true;
}
Popup.java 전체 코드입니다.
제일 아래쪽에 보시면
onTouchEvent()라는 함수를 추가하였습니다.
이전에 ImageView의 터치이벤트를 한적이 있었는데요~
onTouchEvent()함수는 화면상의 터치 이벤트를 처리하는 함수입니다.
여기에서 if문으로
현재 화면 바깥쪽인 MotionEvent.ACTION_OUTSIDE라면 return false;로 주어서
터치이벤트가 동작하지 않도록 해준것입니다.
이번시간에 배운 3가지 기능인
타이틀바 없애기, 뒤로가기 버튼막기, 뷰 바깥영역 터치시 강제로 막기 기능은
당장 이해가 안되더라도 그냥 공식처럼 그때그때 필요할때 가져다 쓰시면 되겠습니다. ^^
그런데, 이렇게 하다보니까 팝업화면을 종료할수가 없게 되었습니다.
그래서, 팝업화면을 종료할수 있는 버튼이 필요합니다.
▣ 팝업화면 종료하기
이제부터는 팝업화면을 종료할수 있는 버튼을 만들어보겠습니다.

popup화면 레이아웃에서 버튼을 하나 갖다놓구요~
<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.8" />
XML코드에서
ID는 btnExit라고 하구요
text는 "닫기"라고 하고
위치는 가운데 아래쪽에 배치하였습니다.
실행해보겠습니다.

네 닫기 버튼이 잘 보이네요..^^
이제 이 닫기 버튼에 대한 클릭이벤트를 작성해보겠습니다.
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
네 위와같이 버튼 클릭이벤트를 작성하고
onClick()함수에서 finish()로 팝업화면을 종료시켰습니다.
전체 소스입니다. 참고하세요~
MainActivity.java
package com.example.popuptest;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
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();
}
});
Button btn_ShowPopup = findViewById(R.id.btnShowPopup);
btn_ShowPopup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), Popup.class);
startActivity(intent);
}
});
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;
});
}
}
Popup.java
package com.example.popuptest;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import androidx.activity.EdgeToEdge;
import androidx.activity.OnBackPressedCallback;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class Popup extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE); // 타이틀바 없애기
setContentView(R.layout.activity_popup);
findViewById(R.id.main).setBackgroundColor(Color.parseColor("#ABCDEF"));
Button btn_Exit = findViewById(R.id.btnExit);
btn_Exit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
// 뒤로가기 버튼 막기
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
setEnabled(true); // 뒤로가기 막기
}
};
getOnBackPressedDispatcher().addCallback(this, callback);
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;
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 뷰 바깥영역 터치시 강제로 막음
if(event.getAction() == MotionEvent.ACTION_OUTSIDE)
{
return false;
}
return true;
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PopUpTest">
<activity
android:name=".Popup"
android:exported="false"
android:theme="@style/Theme.AppCompat.Dialog" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
네, 이번시간은 여기까지만 하구요~
다음시간에는 팝업화면을 투명하게 하고 카운트다운 타이머를 사용해서
숫자 카운트 다운하는 것을 한번 해보도록 하겠습니다.
그럼, 이만 ~
감사합니다. ^^
