-
TECHIT 앱 스쿨 2기: Android 32일차 (23.06.13)[THEC!T] 앱 스쿨2기 : Android 2023. 6. 14. 01:23728x90
자료 출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 내용
오늘은 어제 내주신 문제에 대한 설명을 해주시는 것으로 시작하였습니다.
제가 작성한 코드와 강사님께서 작성하신 코드의 차이점 위주로 설명하자면
첫 번째
관란등급을 선택하는 Chip의 사용방법
저의 경우 색을 변화 시키면서 하였으나, 강사님의 경우는 Filter 스타일로 작성하셨습니다.
그리고 강사님께서 말씀해주셔서 알게 된건데 Chip 한 라인에 균등하게 하려고 맞추려고 할 경우 저처럼 구현해서 사용해야 한다고 알려주셨습니다. 그래서 제가 어제 작성한 코드 이전 코드들에서 원하는 대로 안되는 것이였습니다.
두 번째
ratingBar 의 값 가져와서 사용하는 방법
강사님의 경우 Float 형식으로 사용하셨지만 저의 경우는 그냥 String로 받아버린 차이 점이 있었습니다.
아마 강사님의 경우 ratingBar의 형식을 별도로 화면에 나오도록 하신게 아니라서 나온 차이점이라고 생각이 듭니다.
이 외의는 큰 차이 없는 점을 확인 하였습니다.
문제 설명 이후에는 CardView와 FloatingActiomButton 에 대해서 간단하게 설명해주셨습니다.
CardView
View를 그룹으로 묶어 관리하면서 공중에 떠있는 듯한 모습을 보여줄 수 있는 뷰
주요속성
contentPadding : CardView 내부의 여백을 설정
cardCornerRadius : CardView 꼭지점 둥글기 정도
cardElevation : CarView에 그림자를 주는 정도
FloatingActionButton
이미지 버튼과 비슷하며, 공중에 띄워져 있는 버튼 용토로 사용한다.
주요속성
scrCompat : FloatingActionButton에 표시할 이미지를 설정한다.
다음으로는 어댑터 뷰, 리스트 뷰, 커스텀 리스트 뷰, ArrayAdapter, simpleAdapter 에 대해서 설명해주셨습니다.
리스트 뷰의 경우는 이제 구글에서 권장하지는 않지만 Adapter 의 원리를 이해하기 좋기에 알려주셨습니다.
개인적으로 안드로이드 ui 중에서는 어댑터와 리사이클러뷰가 가장 어렵다고 생각하기에 해당 부분에 대해서는 평소 보다 좀 더 집중해서 들었던 것 같습니다.
AdapterView
개발자가 View를 구성하기 위해 필요한 데이터를 정해줘야 하는 View 구성이 가능한 View들을
Adapter View 라고 부릅니다.
Adapter
Adapter View 들을 구성할 때 개발자가 다양한 데이터를 설정해줘야 하는데 이러한 데이터를 관리하는게 adapter 이며, 사용 목적이나 적용할 View에 따라 다양하게 제공되고 있으며, 직접 생성해서 사용할 수 도 있습니다.
ListView
여러 항목을 리스트로 보여줄 수 있는 AdapterView 입니다.
setOnItemClickListener : 리스트 뷰 내 아이템을 터치하였을 때 실행되는 리스너
Context : 어떠한 작업을 위한 정보를 관리하는 요소를 통칭하며, 안드로이드에서는 시스템이나 애플리케이션과
관련된 정보를 가지고 있습니다.
ArrayAdapter : 칸 하나에 문자열 하나만 사용하는 경우에 사용
android.R.layout.simple_list_item1 : 안드로이드에서 리스트뷰의 항목 하나를 구성할 때 사용할 수 있도록 제공하는 layout 이며, TextView 하나만 있습니다.
package com.test.android28_listview import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.ArrayAdapter import android.widget.Button import com.test.android28_listview.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { lateinit var activityMainBinding: ActivityMainBinding // ListView를 구성하기 위해 필요한 데이터 val data1 = arrayOf( "문자열1", "문자열2", "문자열3", "문자열4", "문자열5", "문자열6", "문자열7", "문자열8", "문자열9", "문자열10", "문자열11", "문자열12", "문자열13", "문자열14", "문자열15", "문자열16", "문자열17", "문자열18", "문자열19", "문자열20", "문자열21", "문자열22", "문자열23", "문자열24", "문자열25" ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activityMainBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(activityMainBinding.root) val adapter = ArrayAdapter<String>( this, android.R.layout.simple_list_item_1, data1 ) activityMainBinding.run{ listView.run{ // ListView에 어뎁터를 설정한다. setAdapter(adapter) // ListView의 항목 하나를 선택하면 동작하는 리스너 // position : 사용자가 터치한 항목의 순서값(0부터 1씩 증가) setOnItemClickListener { parent, view, position, id -> textView.text = "${data1[position]}를 눌렀습니다" } } } } }
추가 내용은 내일 작성하도록 하겠습니다.
제가 아직 깃허브 사용이 미흡한데 날라갔습니다 .....
----------------------------내용 추가----------------------------
일단 어제 깃허브에 백업을 했었지만 날라갔던 이유에 대해 결론만 말하자면 제가 커밋을 하면 안되는 파일과 롤백을 하는 과정에서 marge 이것을 잘못 설정 혹은 삭제를 하여 제가 원하는 시점으로 롤백이 되지 않았고 롤백 시점 이전 파일들도 모두 제대로 열리지 않는 증상이여서 복구하는데 어려움이 있었습니다. 그 과정에서 정확히는 아니지만 브랜치에 대해서 알게 되었습니다. 제가 해당 과정을 겪으면서 알게 된 것 이기에 정확하지는 않을 수 있습니다.
브랜치는 특정시점에 파이프를 연결하여 해당 시점의 파일들을 확인하는 것이라고 이해하였습니다.
왜냐하면 브랜치를 통해 해당파일을 불러오더라도 안드로이드 스튜디오에서 프로그램이 제대로 열리지 않았기 때문에 그렇게 생각을 하게 되었습니다. 그리고 특정 시점에 있는 파일들을 클론 레포지토리 하려고 하는데 분명 아이디와 패스워드를 맞게 넣은 것 같은데 진행이 되지 않는 문제 발생하였는데 해당 문제에 경우 해결을 하지 못하여 기존 다른 폴더에 있던 로컬 데이터와 강사님이 올려주셨었던 예제 프로그램들을 가져와 복구를 진행하였습니다. 그래서 중간에 제가 공부하면 작성했던 일부 파일들은 복구를 하지 못하였습니다.
해당 증상을 겪고나서 기운이 빠져 당일 배운 내용을 당일에 바로 작성하지 못하였습니다.
지금 생각해보면 나중에 몰라서 겪었을 수 도 있는 문제들을 미리 겪어 큰 문제들을 피해갈 수 있는 값진 경험이였다고 생각하며, 깃허브에 저장하는 것으로 만족하는 것이 아니라 로컬에도 별도로 저장을 하며, 파일 관리 및 저장에 대한 중요성을 뼈져리게 알게 되었다고 생각합니다. 마지막으로는 제가 헛짓거리(?) 만 안했다면 깃허브를 통해 원하는 시점으로 정상적으로 복구 할 수 있었을 텐데 라는 아쉬움과 함께 깃허브에 대해서 공부를 제대로 해야겠다라고 다짐하는 계기가 되었습니다.
하기 부터는 다시 배운 내용을 작성하였습니다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
다음으로는 리스트 뷰에 있는 정보를 추가하거나 삭제하는 방법을 학습하였습니다.
해당 기능을 구현하기 위해서는 adapter 클래스의 notifyDataSetChanged 메서드를 이용하여 리스트에 들어가는 데이터가 변경 될 때 마다 리스트 뷰에 변경된 데이터를 갱신하면 됩니다.
notifyDataSetChanged() : Adapter에 등록된 데이터의 변경을 알려주어 해당 변경사항을 반영하여 UI를 업데이트합니다. 예를 들어, 데이터 리스트에 새로운 아이템이 추가되거나 아이템이 삭제되었을 때, 또는 아이템의 속성이 변경되었을 때 notifyDataSetChanged()를 호출하면 UI는 새로운 데이터로 업데이트됩니다.
상기 이미지 프로그램의 코드 입니다.
package com.test.android29_addadapterviewitem import android.R import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.ArrayAdapter import com.test.android29_addadapterviewitem.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { lateinit var activityMainBinding: ActivityMainBinding // 데이터가 없는 리스트를 만든다. val rowList = mutableListOf<String>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activityMainBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(activityMainBinding.root) activityMainBinding.run{ listView.run{ adapter = ArrayAdapter<String>( this@MainActivity, R.layout.simple_list_item_1, rowList ) } button.run{ setOnClickListener { // Aapter를 구성하기 위해 사용한 list에 데이터를 추가한다. val str1 = "row : ${System.currentTimeMillis()}" rowList.add(str1) textView.text = "항목 개수 : ${rowList.size}개" // ListView의 adapter를 통해 갱신을 요청한다. val adapter = listView.adapter as ArrayAdapter<String> adapter.notifyDataSetChanged() } } button2.run{ setOnClickListener { // 제일 마지막 값을 제거한다. rowList.removeLast() textView.text = "항목 개수 : ${rowList.size}개" val adapter = listView.adapter as ArrayAdapter<String> adapter.notifyDataSetChanged() } } } } }
다음으로는 안드로이드 스튜디오에서 제공하는 레이아웃이 아닌 개발자가 작성한 레이아웃으로 리스트뷰를 구성하는 방법을 배웠습니다.
상기 코드와 큰 차이는 없으며 리스트뷰에 들어갈 레이아웃 파일을 개발자가 디자인을 하고 adapter을 설정할 때 해당
레이아웃을 전달해주면 됩니다.
package com.test.android30_customitemview1 import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.ArrayAdapter import com.test.android30_customitemview1.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { lateinit var activityMainBinding: ActivityMainBinding val stringData1 = arrayOf( "문자열1", "문자열2", "문자열3", "문자열4", "문자열5", "문자열6", "문자열7", "문자열8", "문자열9", "문자열10", "문자열11", "문자열12", "문자열13", "문자열14", "문자열15", ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) activityMainBinding = ActivityMainBinding.inflate(layoutInflater) setContentView(activityMainBinding.root) activityMainBinding.run { listView.run{ adapter = ArrayAdapter<String>( this@MainActivity, R.layout.row, R.id.textView2, stringData1 ) setOnItemClickListener { parent, view, position, id -> textView.text = stringData1[position] } } } } }
마지막으로 simpleAdapter 에 대해서 학습하였습니다.
simpleAdapter : simpleAdapter 가 listView 항목 하나를 정의하는 원리는 simpleAdapter 에 설정하는List 내의 map의 개수 만큼 항목이 만들어 지며, 각 항목을 개별적으로 구성하여 보여줍니다. 항목 하나를 구성하기 위해 List 의 i번째 map을 추출하며 map에 이쓰는 데이터를 from 배열에 들어있는 이름의 순서대로 추출하며 IdRes 배열에 설정되어 있는 View의 ID 순서대로 데이터를 설정한다.
코드 작성시
adapter = SimpleAdapter( this@MainActivity, dataList, R.layout.row, keys, ids )
simpleAdapter 구현 내용.
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data, @LayoutRes int resource, String[] from, @IdRes int[] to) { mData = data; mResource = mDropDownResource = resource; mFrom = from; mTo = to; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); }
마무리
원래 이후에 강사님께서 내주신 문제가 있는데 해당 파일이 손상되어 열리지 않아 작성하지 못하였습니다.
오늘의 마음가짐 : 모르면 공부하고 알아가면서 발전하는 사람이 되자.
'[THEC!T] 앱 스쿨2기 : Android' 카테고리의 다른 글
TECHIT 앱 스쿨 2기: Android 34일차 (23.06.15) (0) 2023.06.16 TECHIT 앱 스쿨 2기: Android 33일차 (23.06.14) (0) 2023.06.15 TECHIT 앱 스쿨 2기: Android 31일차 (23.06.12) (1) 2023.06.12 TECHIT 앱 스쿨 2기: Android 30일차 (23.06.09) (1) 2023.06.10 TECHIT 앱 스쿨 2기: Android 29일차 (23.06.08) (1) 2023.06.08