안드로이드 숙련주차 제공 강의 학습
find VIew By Id를 대체하는 코드
모듈에서 viewBinding을 설정하면 각 모듈에 있는 xml 레이아웃 파일의 결합 클래스를 생성함
binding 클래스의 인스턴스에는 상응하는 레이아웃에 ID가 있는 모든 뷰의 직접 참조가 포함된다.
findViewById와의 차이점
사용법
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
*주의사항
ViewBinding은 자동으로 결합 클래스를 생성하는데, 해당 객체의 이름은 레이아웃 이름에 Binding을 붙여서 만들어짐
Ex) activity_main.xml → ActivityMainBinding
fragment_home.xml → FragmentHomeBinding
궁금한 점
findViewById 보다 안정성이 높고 간단한 코드인데 처음부터 뷰바인딩을 안하고 처음에는 findViewById 방식을 먼저 배우는 이유?
그냥 원래 findViewById 방식이 원래 있던 방식이고ViewBinding이 비교적 최신? 기술이라서 그 .. 코딩 역사..?인 이유로 전부 이해해야하기때문인지?
아니면 findViewById 방식을 사용해보면서 먼저 내가 가져오려는 객체가 어떤타입인지 인지하고 가져다 쓰는 연습을 위한거였는지?
아니면 따로 내가 생각하지 못한 이유가 있는지!?
→ 튜터님 답변 : 뷰 바인딩이 최신 기술이라서 혼자서 구글링하면서 다른 사람 코드를 참고할 때findViewById를 사용한 방식의 코드를 봐야할 수 도 있는데, 그 때 이해를 할 수 있어야하기 때문에 그렇다!
둘 다 익숙하게 하기위해서 처음에는 옛날방식인 findViewById를 배워서 사용해봤고, 이제부터는 ViewBinding를 사용할것~
Type safety
이미지 뷰(ImageView)에 텍스트를 설정하려고 하면 오류가 발생할 텐데, 뷰 바인딩을 사용하면 이런 실수를 할 가능성이 없어집니다. 즉, 이미지 뷰는 이미지 뷰로, 텍스트 뷰는 텍스트 뷰로만 사용되게 하여, 잘못된 타입 사용으로 인한 오류가 발생하지 않도록 보장합니다.
이 부분이 이해가 안댄다!
어차피 findViewById를 사용해도 <>안에 타입 잘못 쓰면 오류로 안가져와지는게 아닌가!?
아니면 imageView에 . 찍고 텍스트뷰의 속성 적어도 안뜨지 않았나!?!?!?!
→ 튜터님 답변 : 안드로이드 스튜디오 업데이트로 이제는 타입 잘못적을 때 빨간줄이 뜨지만 옛날에는 안떴다!
그래도 코드가 복잡해지다보면 휴먼에러가 발생할수도 있기때문에 타입 세이프티는 뷰 바인딩의 장점이 될 수 있을듯!
ViewGroup을 상속하는 추상클래스.
여러개의 항목을 나열하고 선택할 수 있는 기능을 제공하는 뷰
대용량의 데이터 세트를 효율적으로 표시할 수 있게 하는 것이 주 목적
ListVIew(수직 나열)와 GridView(격자 형태 나열), Spinner(드롭다운리스트?) 등이있음
Adapter View를 사용하기 위해 필요한 요소 3가지
Adapter
어댑터 인터페이스를 상속하는 어댑터 클래스들.
Adapter 종류
ArrayAdapter 객체 생성하는 방법
ListView
GridView
궁금한점
ListView 만들어보니까 알아서 스크롤이 가능한데 스크롤뷰를 상속받고있는지 알아보기 , 스크롤외의 뭐 어떻게 구성되어있는데 이렇게 되는건지 궁금함
→ ListView는 AdapterView 의 하위클래스, ScrollView는 ViewGroup의 하위클래스. 따로 연관이 있지는 않은듯.
ListView는 LinearLayout 또는 다른 레이아웃의 자식뷰로 들어가야하는지
→ 꼭 그럴필요 없다.
ArrayAdapter 생성할 때 리소스 ID는 완전 정해져있는건지? 커스텀(가능한지)
android.R.layout.simple_list_item_3 하면 세개의 텍스트 뷰로 구성된 레이아웃 이 되는건지?
→ 얘네가 그 안드로이드 SDK에서 제공하는 기본적인 레이아웃리소스? 인데 얘네 종류가 얼마나되는지 뭐 어떤식으로 구성되어있는지를 문서에서 찾을 수가 없음 어떻게 찾아야될지 여쭤보기
→ 태영님이 찾아주셔서 공부완료
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects) 에서는 컨텍스트, 리소스, 텍스트뷰리소스아이디, 데이터배열 이렇게 4개 같은데 생성 예제보면 왜 컨텍스트, 리소스아이디, 데이터배열 세개만 들어가지?!
→ 공식문서 들어가서 확인해보니까 여러가지 생성자를 제공함
더 알아볼 부분
그리드 뷰 속성 각각 어떻게 적용하는지 다 이해하기
position의 정확한 정의?
→ item의 인덱스?
→ 그럼 왜 굳이 index라고 안하고 position이라고 부름?
→
layoutParams 가 뭔지 찾아보기
오늘 할일
코드카타
잘 풀었다
chunked라는 함수를 배웠당
액티비티 위에서 동작하는 모듈화된 UI
Framgment 생명주기
액티비티의 생명주기와 비슷한데 액티비티와 연결 관련된 생명주기가 더 추가된 느낌
Fragment를 액티비티에 추가하는 방법
supportFragmentManager.commit {
replace(R.id.frameLayout, frag)
setReorderingAllowed(true)
addToBackStack("")
}Fragment의 데이터전달
Activity 에서 Fragment로 데이터 전달
Fragment 에서 Fragment로 데이터 전달
Fragment 에서 Activity로 데이터 전달
꼭 인터페이스를 정의해서 전달해야함. 그냥은 안됨
알아볼 것 :
Bundle 이무엇인가
requireActivity()는 무엇인가
사용자에게 결정을 내리거나, 추가정보를 입력하라는 메세지를 띄우는 작은 창
화면을 가득 채우지 않음
보통 사용자가 다음으로 진행하기 전에 조치를 취해야하는 모달 이벤트에서 사용
Alert Dialog 다이얼로그 기본 구조
앱의UI와 별도로 사용자에게 앱과 관련한 정보를 보여주는 기능
알림을 터치하면 해당 앱을 열 수 있음
구현해야할 기능들
예제랑 최대한 비슷하게 만들기 위해서 일단 일러스트로 아이콘 하나 그려줌
xml에 플로팅액션버튼을 추가해주고 디자인을 비슷하게 만들어줌
drawable에 shape_floatbtn 이라는 파일 하나 만들어서 원 모양 xml을 하나 만들어줌
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
<solid android:color="@color/white"/>
</shape>
floatingButton의 background와 shapeAppearance에 1번에서 만든 xml파일을 적용해줌
둘 중 하나 속성을 없애면 바로 네모가 되어버림 ;; 테마에 기본 적용된 모양이 네모라서 그런 것 같은데 테마에서 스타일을 변경해주는게 더 좋은 방법일 수도 있을듯
android:background="@drawable/shape_floatbtn"
app:shapeAppearance="@drawable/shape_floatbtn"
res 폴더에 color 폴더 하나 만들어주고 selector로 android : state_pressed 에 true/false 값 줘서 만들어줌!
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/white" android:state_pressed="false"/> // 버튼 안누른 상태 일때 색 지정
<item android:color="#D3D3D3" android:state_pressed="true"/> //버튼 누른 상태 일 때 색 지정
</selector>
backgroundTint 속성에 정의해준 xml파일 넣어주기
android:backgroundTint="@color/selector_floating_btn_color"
app:rippleColor="@android:color/transparent"일단 사용하기 쉽게 플로팅 버튼을 변수에 담아주고,
fadeIn과 fadeOut효과는 AlphaAnimation을 사용해서 정의해 줌 (float 형식의 숫자를 넣어주면되고, 첫번째 인자로 시작시의 투명도 두번째 인자로 끝날때의 투명도)
val floatingBtn = binding.floatingBtn
val fadeIn = AlphaAnimation(0f, 1f).apply { duration = 300 }
val fadeOut = AlphaAnimation(1f, 0f).apply { duration = 300 }
var isTop = true
recyclerView에 addOnScrollListener를 달아줌
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener(){
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (!binding.recyclerView.canScrollVertically(-1)&& newState == RecyclerView.SCROLL_STATE_IDLE) {
binding.floatingBtn.startAnimation(fadeOut)
binding.floatingBtn.visibility = View.GONE
isTop = true
}else if(isTop){
floatingBtn.visibility = View.VISIBLE
floatingBtn.startAnimation(fadeIn)
isTop = false
}
}
})
ScrollListener로 스크롤이 변경되는 걸 감지?하게 만들어주고,
recyclerView가 -1방향 즉 위로 스크롤이 안되고, 현재 상태가 정지한 상태이면,
플로팅 버튼이 서서히 사라지게 만들어줌.
그렇지 않을 때에는 플로팅 버튼이 서서히 나타나게 만들어줌!
floatingBtn.setOnClickListener {
binding.recyclerView.smoothScrollToPosition(0)
} 플로팅 버튼을 클릭했을 때 smoothScrollToPosition 값을 0으로 줘서 최 상단으로 이동하게 해줌!recyclerView.scrollToPosition(position)recyclerView.scrollBy(x,y)recyclerView.smoothScollBy(dx,dy)val layoutManager = recyclerView.layoutManager as LinearLayoutManager
layoutManager.scrollToPositionWithOffset(position,offset)val layoutManager = recyclerView.layoutManager as LinearLayoutManager
val scroller = object : LinearSmoothScroller(recyclerView.context) {
override fun getVerticalSnapPreference() : Int {
return SNAP_TO_START
}
}
scroller.targetPosition = position
layoutManager.startSmoothScroll(scroller)