휴,, 내 생각
에바 삽질을 너무 해버렸어 좀 배운 것들은 확실히 있는데 간단하게 만드려는 의도와 다르게 인터넷에서 배우다보니 나도 모르게 왜 안되지? 하면 데이터베이스 뿐 만아니라 mvmm 패턴도 같이 막 적용하려고 하다보니 걍 머리가 팡 터질 뻔 했다.
이제 Adapter 개념은 확실히 알 것 같다.
lifecycle 주기도 제대로 모르는데 이 곳 저 곳에서 배운 내 잘못이다. 휴
머리도 식힐겸 정리도 할 겸 글 쓴다.
circular view 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 override fun onCreateViewHolder (parent: ViewGroup , viewType: Int ) : PlanAdapter.CustomViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.[xml 파일 이름], parent, false ) return CustomViewHolder(view) } override fun getItemCount () : Int { return [모델 또는 객체].size } override fun onBindViewHolder (holder: PlanAdapter .CustomViewHolder , position: Int ) { } class CustomViewHolder (itemView: View) : RecyclerView.ViewHolder(itemView) { var name = itemView.tv_name } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class MainActivity : AppCompatActivity () { private val newPlanActivityRequestCode = 1 private lateinit var planViewModel: PlanViewModel override fun onCreate (savedInstanceState: Bundle ?) { super .onCreate(savedInstanceState) setContentView(R.layout.activity_main) val adapter = CustomAdapter(this ) rv_planlist.adapter =adapter rv_planlist.layoutManager = LinearLayoutManager(this ) planViewModel = ViewModelProvider(this ,PlanViewModel.Factory(application)).get (PlanViewModel::class .java) } }
메인 액티비티에서는 만들어진 어댑터를 메인 엑티비티의 xml의 listview에 연결한다
왜냐면 커스텀 어댑터는 3단계를 거친다.
mainActivity xml – mainActivity 내 circularview - circular view에 들어갈 객체
저 객체를 자기 맘대로 재정의 하기 때문에 커스텀 어댑터라고한다
LayoutManger를 세팅하면 끝!
상황에 따라서 어댑터에 배열 넣어서 뷰 구현하는 예제들 있는데 DB가 없어서 예제를 따라하는 건 간단하다
LayoutManager는 3개 있다.
Adapter 또는 MainActivity가 아닌 곳에서 DB 접근
fragment 쓰면 이럴 일은 없을 거 같은데? 공부가 좀 모자라다
interface를 이용하는 방법
난 Delete를 구현하기 위해 이 방법을 사용했다. adapter에 delete 버튼 리스너를 넣을 생각이었기 때문이다.
DeleteBtnListener 1 2 3 interface DeleteBtnListener { fun deleteBtnClicked (plan:Plan ) }
인터페이스를 선언하고 인터페이스 내에 사용할 메소드를 선언한다
MainActivity 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class MainActivity : AppCompatActivity (), DeleteBtnListener { private lateinit var planViewModel: PlanViewModel override fun onCreate (savedInstanceState: Bundle ?) { adapter = PlanAdapter(this , this ) planViewModel = ViewModelProvider(this ).get (PlanViewModel::class .java) planViewModel.allPlan.observe(this , Observer { plan -> plan?.let { adapter.setPlans(it) } }) } override fun deleteBtnClicked (plan: Plan ) { planViewModel.delete(plan) } }
메인 액티비티에서는 인터페이스를 받은 후 인터페이스 메소드를 재정의 한다.
메소드 deleteBtnClicked를 보면 planViewModel 있음을 알 수 있다.
이 viewModel은 메인 액티비티에서 정의해서 쭉 사용할 viewModel이다
1 2 3 override fun onCreate (savedInstanceState: Bundle ?) { adapter = PlanAdapter(this , this ) }
onCreate 같은 경우 액티비티가 생성될 때 처음 실행되는 메소드이다
아래에서 말하겠지만 PlanAdapter에서도 deleBtnListener를 상속받는데 메인 액티비티에서 재정의 된 리스너를 연결하는 것이다.
Plan Adapter 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class PlanAdapter (val context: Context, deletelistener: DeleteBtnListener) :RecyclerView.Adapter<PlanAdapter.Holder>() { private var DeleteBtnListener: DeleteBtnListener = deletelistener inner class Holder (itemView: View) : RecyclerView.ViewHolder(itemView) { val content = itemView.tv_context val timeProgress = itemView.progress val start = itemView.bt_start val reset = itemView.bt_reset val delete = itemView.bt_delete fun bind (plan: Plan ) { content.text = plan.content timeProgress.setOnTouchListener(OnTouchListener { v, event -> true }) delete.setOnClickListener(View.OnClickListener { DeleteBtnListener.deleteBtnClicked(plan) notifyDataSetChanged() }) } } }
이너 클래스로 holer가 생성된 것을 볼 수 있는데 recyclerview에서는 viewholder에 담아서 뷰에 뿌리기 때문에 필요하다
bind() 메소드를 보면 deleteBtnClicked()를 사용하는 것을 볼 수 있다.