
material3의 가이드를 지키는 것이 어플 검수 조건은 아니지만
플레이스토어 노출 조건은 많은데 그 중 하나가 material3 가이드라고 함
material3 가이드를 잘 지키면 그만큼 가산점을 주기 때문에 스토어에 노출될 확률이 높음
예를 들어 앱 삭제 시 나오는 안내문구를 "삭제하시겠습니까?"가 아닌 "삭제 시 ~~ 복구할 수 없습니다~~" 와 같이 행위에 대해 어떤 결과가 나오게 될지를 안내하는 문구를 넣고 취소,삭제 버튼을 넣어줘야 함
BackStack에 쌓인 것들만 눈에 보임
그 중 가장 위에 있는 것이 눈에 보인다.
Activity는 무조건 BackStack에 들어감
사용자가 단말기의 Back button을 누르면, 또는 finish() 메서드가 호출되면 BackStack에 가장 위에 있는 Activity를 제거하고 제거된 Activity는 종료된다
뒤로 이동하는 개념이 아니라 BackStack에 쌓인 Activity 화면이 보이는 개념임
Fragment는 눈에 보이는 실행단위를 관리하는 Activity 안에서 영역별로 코드를 구현할 수 있도록 제공하는 개념임
따라서 Fragment는 Activity가 아니기 때문에 BackStack에 쌓이지 않음
Fragment끼리 BackStack에 쌓이면 같이 보이기 때문에 Activity가 Backstack에 이전 Fragment를 떼주고 새로운 Fragment를 쌓는 역할을 한다
첫 Fragment를 BackStack에 올리면 Back button을 눌러 첫 Fragment를 없앨 때 흰 화면이 나타나게 된다. 따라서 첫 Fragment는 BackStack에 올리지 않고 그 다음 Fragment부터 BackStack에 올린다.
Activity에서 Fragment를 BackStack에 직접 올려주는 작업(addToBackStack)과 BackStack에서 Fragment를 제거해주는 작업(popBackStack)을 해줘야 뒤로가기 기능을 구현할 수 있다.
Fragment의 onCreate는 단 한번만 실행되고, onCreateView 메서드는 Fragment가 보일때마다 계속 호출된다.
한 번만 실행이 필요한 코드는 onCreate에, Fragment가 보여질때마다 동작이 필요한 코드는 onCreateView에 작성해주면 된다.
Fragment에 다시 돌아온 경우 onResume을 사용할 수 있으나 onCreateView도 같이 실행되기때문에 onCreateView만 사용해도 상관없다.
구글은 Activity 사용을 최소화하고 Fragment 사용을 권장하고 있음
Activity의 역할 : Fragment 관리, 데이터 관리

화면전환에 애니메이션을 적용한 경우,
최상단 Layout에 transitionGroup 속성을 True로 해주면 전환 효과가 좀 더 자연스러워진다
이 속성 없이 그냥 애니메이션 효과를 주면 화면 전환이 어색해 보임
이전 과제와 동일하게 학생리스트를 컴패니언오브젝트 클래스로 만들었는데 강사님은 메인 액티비티에 직접 리스트를 생성했다.
Fragment는 Activity에 접근이 가능하기 때문에 굳이 컴패니언오브젝트를 만들필요없이 MainActivity에 리스트를 직접 만들어 Fragment에서 접근할 수 있게
InfoFragment를 보여줄 때에는 position만 전달
Fragment간에 데이터 전달은 bundle을 이용하면 된다.
스크롤 할때 보여주고 마지막 항목이 나타나면 숨겨줄 때
coordinatorlayout에 이벤트를 전달하면 해당 레이아웃이 관리하는 뷰에 특정한 동작을 하도록 해줌
NestedScrollView는 보통 CoordinatorLayout 안에 들어감
NestedScrollView에서 스크롤 이벤트가 발생하면 CoordinatorLayout에 전달이 되고 CoordinatorLayout에 있는 다른 뷰들에게 전달이 된다. 해당 이벤트가 발생했을 때 동작하는 기능을 넣은 뷰는 그 기능을 실행한다.
이전에는 해당 동작기능을 프로그래머가 직접 구현을 했다면 지금은 뷰에 그런 기능이 속성으로 구현되어있어서 이벤트만 전달받으면 바로 동작되게 할 수 있다.

처음 레이아웃을 CoordinatorLayout으로 변경


레이아웃 안에 뷰 배치


BottomAppBar에 구성할 메뉴 추가



FAB 버튼 추가 후


layout_anchor 속성에 bottomAppBar 아이디를 넣어준다.
디자인탭에서는 에러표시가 나지만 코드탭에서는 문제없이 설정할 수 있다.

class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
activityMainBinding.apply {
// BottomAppBar
bottomAppBar.apply {
// Navigation
setNavigationIcon(R.drawable.menu_24px)
setNavigationOnClickListener {
textView.text = "메뉴를 불렀습니다."
}
// Menu
inflateMenu(R.menu.main_menu)
setOnMenuItemClickListener {
textView.text = when(it.itemId){
R.id.item1 -> "메뉴1을 눌렀습니다"
R.id.item2 -> "메뉴2을 눌렀습니다"
R.id.item3 -> "메뉴3을 눌렀습니다"
else -> ""
}
true
}
// FAB
// layout 파일에서 layout_anchor 속성에 BottomAppBar의 id를 설정해줘야 한다.
floatingActionButton.setOnClickListener {
textView.text = "FloatActionButton을 눌렀습니다."
}
}
}
}
}

생략함
나중에 꼭 실습해보기
데이터 베이스 : 저장된 데이터의 집합 ( 엑셀 파일 )
DBMS : 데이터베이스를 관리하는 시스템 ( 엑셀 프로그램 )
테이블 : 데이터 베이스 내에서 데이터를 관리하는 묶음 ( 엑셀 시트 )
2가지 메서드가 있는데 하나는 최초에 어플을 열었을 때 단 한번만 호출되고 그 이후에는 절대로 호출되지 않는다.
1. onCreate : 앱을 처음 실행할 때 데이터 베이스 파일이 없을 경우 파일을 만들고 호출된다. 어플 설치 후 딱 한번만 호출된다. 데이터베이스가 관리할 테이블을 생성하는 작업
2. onUpgrade : 어플리케이션을 업데이트한 사람들을 위한 메서드. 기존에 있는 테이블을 최신 형태의 구조로 변경하는 작업
예를 들어 1.0 버전 앱에서는 테이블을 2개만 갖고있지만 앱이 2.0 버전으로 업데이트 되었을 때 테이블이 3개로 늘어난 경우, 새로 다운로드 받은 유저는 앱을 최초로 실행하면서 onCreate메서드가 호출되기 때문에 테이블이 바로 3개로 생성되지만 기존 유저는 테이블 onCreate가 이미 호출된 상태로 더이상 호출되지 않기 때문에 테이블이 그대로 2개인 상태가 되어 문제가 된다. 따라서 기존 유저들은 앱 업데이트 후 실행 시 테이블이 3개가 되도록 추가해주는 onUpgrade 메서드가 호출된다.
1.0 > 2.0 > 3.0 version으로 업데이트가 진행되었을때
이런 케이스가 있을 경우,
유저1의 케이스와 유저2의 케이스별로 onUpgrade를 처리해주는 대응을 해야 한다.
// DBHelper.kt
package kr.co.lion.android36_sqlitedatabase
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
class DBHelper(context: Context, dbName:String, version:Int) : SQLiteOpenHelper(context, dbName, null, version) {
override fun onCreate(db: SQLiteDatabase?) {
TODO("Not yet implemented")
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
TODO("Not yet implemented")
}
}
DBHelper.kt 파일을 직접 패키지 내에 생성해준다.
SQLiteOpenHelper를 상속받는 DBHelper 클래스를 작성해준다.
onCreate와 onUpgrade 메서드를 오버라이딩해준다.
// MainActivity.kt
package kr.co.lion.android36_sqlitedatabase
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kr.co.lion.android36_sqlitedatabase.databinding.ActivityMainBinding
// 데이터 베이스 : 데이터들을 저장하고 관리하는 데이터 집합
// SQLite : 데이터 베이스를 관리하는 관계형 데이터 베이스 시스템(RDBMS)의 한 종류
// 테이블 : 데이터베이스 내에서 데이터를 묶어서 관리하는 요소
// 컬럼 : 테이블 내의 데이터 항목(컬럼, 열)
// 로우 : 테이블에 저장되어 있는 개체 하나에 대한 컬럼의 묶음(로우, 행)
// 안드로이드에서 SQLite Database 사용
// 1. SQLiteOpenHelper 를 상속받은 클래스를 만들어준다(DBHelper.kt)
class MainActivity : AppCompatActivity() {
lateinit var activityMainBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(activityMainBinding.root)
// SQLiteOpenHelper 객체 생성
val dbHelper = DBHelper(this, "TEST.db", DBHelper.databaseVersion)
// 데이터 베이스에 접속
// 이때 데이터 베이스 파일을 찾게 된다. 파일이 있으면 데이터 베이스 파일을 열고
// 없으면 파일을 생성하고 데이터 베이스 파일을 열고 SQLiteOpenHelper 에 있는 onCreate 메서드를 호출한다.
// 만약 기존 데이터 베이스 파일 버전보다 더 높은 버전으로 설정하면 onUpgrade 가 호출된다.
val sqLiteDatabase = dbHelper.writableDatabase
// 데이터 베이스를 닫아준다.
sqLiteDatabase.close()
}
}
메인 액티비티에서 SQLiteOpenHelper를 상속한 DBHelper 클래스의 객체를 생성하면 데이터 베이스에 접근하고 사용할 수 있게 된다.
실제 DB 파일은 아래와 같이 안드로이드 스튜디오의 DeviceExplorer에서 찾아볼 수 있다.




※ 출처 : 멋쟁이사자 앱스쿨 2기, 소프트캠퍼스