안녕하세요. 이번 포스팅에서는 특정 이벤트를 발생시켰을 때 앱 하단에서 커스텀 다이얼로그가 올라오는 기능을 구현해 보도록 하겠습니다.
이번에도 코드부터 보여드려야죠😃
+ 참고로 다이얼로그의 모서리를 둥글게 만드는 코드는 아래 설명부분에 있습니다!
결과 GIF🎬
결과코드👀
BottomSheetFragmentDialog는 material 라이브러리에서 제공하므로 implement 해줍니다.
프로젝트를 생성하면 기본으로 되어있으니 없는분들만 추가해주시면 될 것 같습니다.
implementation 'com.google.android.material:material:1.7.0'
MainActivity의 xml에서는 이벤트를 발생시킬 버튼 한개를 생성해주시면 됩니다. 코드는 생략하겠습니다.
XML
<fragment_bottom_sheet.xml>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".BottomSheetFragment">
<ImageView
android:id="@+id/bottom_img"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_marginStart="15dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="10dp"
android:src="@drawable/image"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/bottom_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="10dp"
android:text="Title"
android:textAllCaps="false"
android:textColor="@color/black"
android:textSize="17sp"
app:layout_constraintStart_toEndOf="@+id/bottom_img"
app:layout_constraintTop_toTopOf="@+id/bottom_img" />
<TextView
android:id="@+id/bottom_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:ellipsize="end"
android:lines="1"
android:text="URL"
android:textSize="13sp"
app:layout_constraintStart_toStartOf="@+id/bottom_title"
app:layout_constraintTop_toBottomOf="@+id/bottom_title" />
<ImageView
android:id="@+id/bottom_right"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_marginEnd="20dp"
android:src="@drawable/right"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/black" />
</androidx.constraintlayout.widget.ConstraintLayout>
Kotlin
<BottomSheetFragment.kt>
package com.example.bottomsheetdialogeaxm
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
class BottomSheetFragment : BottomSheetDialogFragment() {
private val url: String = "https://tekken5953.tistory.com/" // 이동할 URL주소
private val title: String = "devJaeYL's Tistory blog" // 타이틀 메시지
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_bottom_sheet, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val link: TextView = view.findViewById(R.id.bottom_link)
val name: TextView = view.findViewById(R.id.bottom_title)
link.text = url
name.text = title
view.setOnClickListener {
dismiss()
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
val chooser = Intent.createChooser(intent, "Open With")
try {
startActivity(chooser)
} catch (e: ActivityNotFoundException) {
Log.e(javaClass.name, "Link error is $e")
Toast.makeText(context, "링크로 이동할 수 없습니다", Toast.LENGTH_SHORT).show()
}
}
}
}
<MainActivity.kt>
val btn: Button = findViewById(R.id.showDialogBtn)
btn.setOnClickListener{
val bottomSheet = BottomSheetFragment()
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
}
Java
<BottomSheetFragment.java>
package com.example.bottomsheetdialogeaxm;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
public class BottomSheetFragmentJava extends BottomSheetDialogFragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final String linkStr = "https://tekken5953.tistory.com/"; // 이동할 URL 주소
final String titleStr = "devJaeYL's Tistory blog"; // 타이틀 메시지
TextView linkText = view.findViewById(R.id.jbottom_link);
TextView titleText = view.findViewById(R.id.jbottom_title);
linkText.setText(linkStr);
titleText.setText(titleStr);
view.setOnClickListener(v -> {
dismiss();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkStr));
Intent chooser = Intent.createChooser(intent, "Open With");
try {
startActivity(chooser);
} catch (ActivityNotFoundException e) {
Log.e(getClass().getSimpleName(), "Link error is " + e);
Toast.makeText(getContext(), "링크로 이동할 수 없습니다", Toast.LENGTH_SHORT).show();
}
});
}
}
<MainActivity.java>
Button button = findViewById(R.id.showDialogBtn);
button.setOnClickListener(v -> {
BottomSheetFragmentJava bottomSheetFragment = new BottomSheetFragmentJava();
bottomSheetFragment.show(getSupportFragmentManager(), bottomSheetFragment.getTag());
});
그럼 코드에 대해 알아보겠습니다.
메인 엑티비티에서 버튼을 클릭하면 프래그먼트를 생성하고 다이얼로그를 보여주는 부분입니다.
bottomSheet.show 메서드에 프래그먼트 매니저와 태그를 입력하고 호출하면 다이얼로그가 생성됩니다.
val bottomSheet = BottomSheetFragment()
bottomSheet.show(supportFragmentManager, bottomSheet.tag)
프래그먼트의 onCreateView에서 view(다이얼로그)를 클릭 했을 때 이벤트를 처리하는 부분입니다.
view.setOnClickListener{
…
}
Intent.ACTION_VIEW를 사용하여 암시적 인텐트로 url 링크를 새창으로 띄웁니다.
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
createChooser는 링크를 열 앱이 2개이상일 경우 사용자가 선택하게 하는 메서드입니다.
현재 프래그먼트가 액티비티를 가지고 있다면 새 창을 열어 링크를 시작합니다.
val chooser = Intent.createChooser(intent, "Open With")
try {
startActivity(chooser)
} catch (e: ActivityNotFoundException) {
Log.e(javaClass.name, "Link error is $e")
Toast.makeText(context, "링크로 이동할 수 없습니다", Toast.LENGTH_SHORT).show()
}
추가로 다이얼로그의 모서리부분을 둥글게 만드는 radius설정에 대해 알아보겠습니다.
drawable 폴더에 아래 파일을 추가해줍니다. 저는 bottom_radius라고 만들었습니다.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
<solid android:color="@color/white"/>
</shape>
<themes.xml>
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.BottomSheetDialogEaxm" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
…
<item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
</style>
…
<style name="AppBottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/AppModalStyle</item>
</style>
<style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/bottom_radius</item>
</style>
</resources>
이상으로 BottomSheetFragmentDialog의 사용법에 대해 알아보았습니다.
이 예제 이외에도 본인이 필요한 방식으로 클래스에서 커스텀이 가능하니 유용할 듯 합니다.
감사합니다.

참고
https://youngest-programming.tistory.com/349
[안드로이드] 안드로이드 BottomSheetDialog 콜백 구현
[2021-04-14 업데이트] 가장 하단에 PS 부분에 변경 후 코드를 참고해주세요 :) 최신코드입니다. 본 프로젝트 전에 적용하기 전 샘플 프로젝트로 잘 되나 바텀시트다이얼로그를 테스트해봤습니다.
youngest-programming.tistory.com
예제 소스
https://github.com/tekken5953/BottomSheetDialogEaxm
GitHub - tekken5953/BottomSheetDialogEaxm
Contribute to tekken5953/BottomSheetDialogEaxm development by creating an account on GitHub.
github.com
'Android' 카테고리의 다른 글
[안드로이드] 웹뷰(WebView)(2) - 접근과 제어 (0) | 2023.01.03 |
---|---|
[안드로이드] 웹뷰(WebView)(1) - 앱 브라우저에서 호출 (0) | 2022.12.26 |
[안드로이드] Spannable로 글자마다 다른 설정! (0) | 2022.12.13 |
[안드로이드] 에러 'compileDebugJavaWithJavac' task and 'compileDebugKotlin' task jvm target compatibility should be set to the same Java version. 해결 (0) | 2022.12.07 |
[안드로이드] 네비게이션 바 없애기( + 몰입모드) (0) | 2022.12.02 |