본문 바로가기
개발 공부 기록하기/- Android

안드로이드 DialogFragment Title(Actionbar) 이 없어지지 않을때 방법

by soulduse 2017. 9. 24.
반응형

커스텀 DialogFragment를 만들고 간단한 Alert 창을 띄울 일이 있었는데 내가 원하지 않는 액션바 타이틀이 계속 나오게되었다.

상위 버전에서는 (마시멜로우, 누가 버전)출력되지 않는 것을 확인 했으나 롤리팝(5.0) 버전 이하에서는 해당 증상이 확인되었다.

우선 상황을 보자.


DialogFragment 창을 띄우면 다음과 같이 뜬다. 위와 같이 빈 타이틀바 영역이 표시되는데 이를 없애려고 

오만가지를 시도 해보았으나 생각보다 되지 않았다.

간단한 코드와 함께 어떻게 없앨 수 있는지 코드를 통해 확인해보자


MainActivity.kt

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val openDialog = findViewById(R.id.tv_open_dialog) as TextView
openDialog.setOnClickListener {
showDialog()
}
}

private fun showDialog() {
val newFragment = MyDialogFragment.newInstance()
newFragment.show(supportFragmentManager, "dialog")
}
}

우선 간단하게 MainActivity 에서 DialogFragment를 상속받는 MyDialogFragment 클래스를 생성하고, 

TextView를 클릭 할 때 show()를 하는 코드이다.

Kotlin으로 작성하였지만 간단한 코드라 읽기 어렵진 않을 것이라 생각된다.


activity_main.xml

<android.support.constraint.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="match_parent"
tools:context="com.dave.dialogfragment.MainActivity">

<TextView
android:id="@+id/tv_open_dialog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:text="Open - DialogFragment"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:padding="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

ConstrantLayout안에 TextView를 하나 추가하였다.



MyDialogFragment.kt

class MyDialogFragment : DialogFragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.hello_world, container, false)
}

companion object {
fun newInstance(): MyDialogFragment = MyDialogFragment()
}
}

DialogFragment를 상속받는 MyDialogFragment를 만들었다.

onCreateView에서 프래그먼트가 하나의 뷰처럼 동작할 수 있도록 레이아웃을 설정 및 초기화를 해주었다. 


추가적으로 inflater, container, savedInstanceState가 항상 궁금했는데, 대충 아래의 이미를 가진다.


inflater :  Fragment안에서 뷰들을 확장하는데 사용

container : null가 아닌 경우, 프래그먼트의 UI가 첨부되어야하는 부모뷰의 LayoutParams를 생성하는 데 사용

savedInstanceState : null가 아닌 경우, 이전에 저장된 상태에서 다시 구성

공식홈페이지 참조


hello_world.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<TextView
android:id="@+id/tv_hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#FFFFF0"
android:padding="20dp"
android:text="Hello_World!"
android:textSize="40dp"
android:textStyle="bold" />

</LinearLayout>

특별한 내용은 없다. 리니어 레이아웃 안에 텍스트뷰 하나 추가 ( 다이얼로그가 보여질때 나올 화면 )

이렇게 앱을 실행하면 위에서 말한 하위 버전(롤리팝 5.0 이하)에서는 빈 액션바(Title)이 표시된다


#1 해결하기 위해 해본방법  - 스타일 값 조정 해보기 (안된다)

<style name="NoTitle" parent="AppTheme">
<item name="windowNoTitle">true</item>
</style>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:theme="@style/NoTitle">

#2 해결하기 위해 해본방법  - DialogFragment 내부 actionbar hide() 하기 (안된다)

private fun showDialog() {
val newFragment = MyDialogFragment.newInstance()
newFragment.activity.actionBar.hide() // 이부분 추가 해봤으나...
newFragment.show(supportFragmentManager, "dialog")
}


찾아본 결과 


DialogFragment에 테마 설정은 할 수 있어도, ActionBar를 DialogFragment에 붙힐수 있는 방법은 없다고 한다.

DialogFragment에 ActionBar 등록 자체가 되지 않고, Dialog.getActionBar()호출하면 항상 리턴값이 null을 가진다.

대안으로 액션바를 사용하기 위해서 menu를 사용하는 방법이 있다고 한다


간단한 문제인것 같은데 나안테 왜이래??


자 이제 해결 방법을 보자

Kotlin Code

class MyDialogFragment : DialogFragment() {

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.hello_world, container, false)
}

    // 타이틀을 없애기위해 이 부분 추가됨
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window.requestFeature(Window.FEATURE_NO_TITLE)
return dialog
}

companion object {
fun newInstance(): MyDialogFragment = MyDialogFragment()

}
}

Java code

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return dialog;
}

onCreateDialog에서Dialog가 생성될때 Dialog window값을 가져와서 requestFeature(Window.FEATURE_NO_TITLE ) 

메서드를 호출하면 화면에 추가적으로 내용을 확장(추가)시킨다. 

파라메터 값으로 Window.FEATRURE_NO_TITLE 을 넣었으므로 타이틀이 없는 창으로 확장되었으므로, 타이틀바가 더이상 보이지 않는다.


What is feature mean?

to have or include (someone or something) as an important part


결과화면





이상으로 안드로이드 DialogFragment에서 Dialog창에서 불필요한 액션바를 없애는 포스팅 이었습니다.!



반응형