bottom_navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/page_game"
android:enabled="true"
android:icon="@android:drawable/ic_menu_slideshow"
android:title="홈"/>
<item
android:id="@+id/page_setting"
android:enabled="true"
android:icon="@android:drawable/ic_menu_manage"
android:title="설정"/>
</menu>
GameFragment.kt
class GameFragment: Fragment(){
private var binding: GameFragmentBinding?=null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = GameFragmentBinding.inflate(inflater, container, false)
return binding!!.root
}
}
GameFragment.kt
class GameFragment: Fragment(){
private var binding: GameFragmentBinding?=null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = GameFragmentBinding.inflate(inflater, container, false)
return binding!!.root
}
}
SettingFragment.kt(viewbinding 이용)
class SettingFragment:Fragment(){
private var binding:SettingFragmentBinding?=null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = SettingFragmentBinding.inflate(inflater, container, false)
return binding!!.root
}
}
game_activity.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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/fragment_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bnv_main"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bnv_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_navigation_menu" />
</androidx.constraintlayout.widget.ConstraintLayout>
GameActivity.kt
class GameActivity : AppCompatActivity() {
private var binding: GameActivityBinding?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 바인딩 초기화
binding=GameActivityBinding.inflate(layoutInflater)
// 레이아웃(root뷰) 표시
setContentView(binding!!.root)
supportFragmentManager.beginTransaction().add(R.id.fragment_container, SettingFragment()).commit()
binding!!.bnvMain.selectedItemId = R.id.page_setting
binding!!.bnvMain.setOnItemSelectedListener{
replaceFragment(
when(it.itemId){
R.id.page_game->GameFragment()
else-> SettingFragment()
}
)
true
}
}
private fun replaceFragment(fragment: Fragment) {
supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit()
}
}
추가로 앱을 처음 열때 원하는 메뉴를 지정하고 싶을때는 밑의 코드를 추가해준다.
bnv_main.selectedItemId = R.id.first
bottom navigation
bottom navigation
binding!!.btHelp.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://boostcamp.connect.or.kr"))
startActivity(intent)
}
binding!!.btInit.setOnClickListener {
val builder = AlertDialog.Builder(this.context)
builder
.setTitle("게임 초기화")
.setMessage(
"모든 설정을 지우려고 합니다.\n" +
"지금 지우면 점수를 잃어버릴 수 있습니다. " +
"다시 한 번 생각해보세요.\n" +
"별거 아니니까 지울까요?"
)
.setNegativeButton("CANCEL",object :DialogInterface.OnClickListener{
override fun onClick(p0: DialogInterface?, p1: Int) {
Log.d("SettingFragment","CANCEL")
}
})
.setPositiveButton("RESET",object :DialogInterface.OnClickListener{
override fun onClick(p0: DialogInterface?, p1: Int) {
Log.d("SettingFragment","RESET")
}
})
.create()
.show()
}

주의할 점은 다이얼로그를 띄워서 액티비티가 최상단이 아닌 상황에는 onPause()가 호출되어야 할 것 같지만 실제로는 그렇지 않다. 다이얼로그가 액티비티의 일부이기 때문이다. 즉, 새로운 액티비티가 최상단으로 온 상황이 아니기 때문이다.
따라서 아무런 함수가 호출되지 않는다.

화면의 기본적인 컴포넌트이다. TextView, ImageView, EditText, ... 등 자주 쓰는 모든 UI 관련된 컴포넌트는 View라는 클래스를 상속 받는다.

ViewGroup은 n개의 View를 포함할 수 있는 Container이다. 우리가 자주 쓰는 레이아웃이 ViewGroup에 해당한다.
View를 상속받아 만들어진 클래스이다. ex) LinearLayout, ConstraintLayout ...

ViewGroup에는 View, ViewGroup이 포함될 수 있으며, ViewGroup은 결국 View를 포함한다. 모든 UI는 결국 View이다.
textview는 textview를 담을 수 없다.
하지만 constraint layout은 textview를 담을 수 있다.
textview는 view고, constraint layout도 view인데 왜 안될까?
[ViewGroup.class]
public abstract class ViewGroup extends android.view.View implements android.view.ViewParent, android.view.ViewManager { ... }
[View.class]
public class View implements android.graphics.drawable.Drawable.Callback, android.view.KeyEvent.Callback, android.view.accessibility.AccessibilityEventSource { ... }
상속 받는 클래스의 종류가 서로 다르다.