-
[Android]Firebase로 채팅 앱 만들기(5)Andorid 2022. 3. 31. 14:58
이번에는 새로 채팅할 상대를 추가할 수 있는 검색창을 만들어보도록 하겠다.
class AddChatRoomActivity : AppCompatActivity() { lateinit var binding:ActivityAddChatroomBinding lateinit var btn_exit: ImageButton lateinit var edt_opponent:EditText lateinit var firebaseDatabase:DatabaseReference lateinit var recycler_people:RecyclerView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityAddChatroomBinding.inflate(layoutInflater) setContentView(binding.root) initializeView() initializeListener() setupRecycler() } fun initializeView() //뷰 초기화 { firebaseDatabase = FirebaseDatabase.getInstance().reference!! btn_exit = binding.imgbtnBack edt_opponent = binding.edtOpponentName recycler_people = binding.recyclerPeoples } fun initializeListener() //버튼 클릭 시 리스너 초기화 { btn_exit.setOnClickListener() { startActivity(Intent(this@AddChatRoomActivity, MainActivity::class.java)) } edt_opponent.addTextChangedListener(object :TextWatcher //검색 창에 입력된 글자가 변경될 때마다 검색 내용 업데이트 { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable?) { var adapter = recycler_people?.adapter as RecyclerUsersAdapter adapter.searchItem(s.toString()) //입력된 검색어로 검색 진행 및 업데이트 } }) } fun setupRecycler() //사용자 목록 초기화 및 업데이트 { recycler_people.layoutManager = LinearLayoutManager(this) recycler_people.adapter = RecyclerUsersAdapter(this) } }
새롭게 대화를 시작할 친구를 검색할 액티비티의 전체 코드이다.
해당 화면에 필요한 뷰들을 초기화한 후,
edt_opponent.addTextChangedListener(object :TextWatcher //검색 창에 입력된 글자가 변경될 때마다 검색 내용 업데이트 { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(s: Editable?) { var adapter = recycler_people?.adapter as RecyclerUsersAdapter adapter.searchItem(s.toString()) //입력된 검색어로 검색 진행 및 업데이트 } })
검색어 입력란에 단어와 일치하는 사용자를 바로 검색하게 하기 위해 리스너를 추가하였다.
다음으로 각 사용자들의 목록을 불러올 Recycler를 만들어야 한다.
class RecyclerUsersAdapter(val context: Context) : RecyclerView.Adapter<RecyclerUsersAdapter.ViewHolder>() { var users: ArrayList<User> =arrayListOf() //검색어로 일치한 사용자 목록 val allUsers: ArrayList<User> =arrayListOf() //전체 사용자 목록 lateinit var currnentUser: User init { setupAllUserList() } fun setupAllUserList() { //전체 사용자 목록 불러오기 val myUid = FirebaseAuth.getInstance().currentUser?.uid.toString() //현재 사용자 아이디 FirebaseDatabase.getInstance().getReference("User").child("users") //사용자 데이터 요청 .addValueEventListener(object : ValueEventListener { override fun onCancelled(error: DatabaseError) { } override fun onDataChange(snapshot: DataSnapshot) { users.clear() for (data in snapshot.children) { val item = data.getValue<User>() if (item?.uid.equals(myUid)) { currnentUser = item!! //전체 사용자 목록에서 현재 사용자는 제외 continue } allUsers.add(item!!) //전체 사용자 목록에 추가 } users = allUsers.clone() as ArrayList<User> notifyDataSetChanged() //화면 업데이트 } }) } fun searchItem(target: String) { //검색 if (target.equals("")) { //검색어 없는 경우 전체 목록 표시 users = allUsers.clone() as ArrayList<User> } else { var matchedList = allUsers.filter{ it.name!!.contains(target)}//검색어 포함된 항목 불러오기 users.clear() matchedList.forEach{users.add(it)} } notifyDataSetChanged() //화면 업데이트 } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val view = LayoutInflater.from(context).inflate(R.layout.list_person_item, parent, false) return ViewHolder(ListPersonItemBinding.bind(view)) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.txt_name.text= users[position].name holder.txt_email.text= users[position].email holder.background.setOnClickListener() { addChatRoom(position) //해당 사용자 선택 시 } } fun addChatRoom(position: Int) { //채팅방 추가 val opponent = users[position] //채팅할 상대방 정보 var database = FirebaseDatabase.getInstance().getReference("ChatRoom") //넣을 database reference 세팅 var chatRoom = ChatRoom( //추가할 채팅방 정보 세팅 mapOf(currnentUser.uid!!totrue, opponent.uid!!totrue), null ) var myUid = FirebaseAuth.getInstance().uid//내 Uid database.child("chatRooms") .orderByChild("users/${opponent.uid}").equalTo(true) //상대방 Uid가 포함된 채팅방이 있는 지 확인 .addListenerForSingleValueEvent(object : ValueEventListener { override fun onCancelled(error: DatabaseError) {} override fun onDataChange(snapshot: DataSnapshot) { if (snapshot.value== null) { //채팅방이 없는 경우 database.child("chatRooms").push().setValue(chatRoom).addOnSuccessListener{// 채팅방 새로 생성 후 이동 goToChatRoom(chatRoom, opponent) } } else { context.startActivity(Intent(context, MainActivity::class.java)) goToChatRoom(chatRoom, opponent) //해당 채팅방으로 이동 } } }) } fun goToChatRoom(chatRoom: ChatRoom, opponentUid: User) { //채팅방으로 이동 var intent = Intent(context, ChatRoomActivity::class.java) intent.putExtra("ChatRoom", chatRoom) //채팅방 정보 intent.putExtra("Opponent", opponentUid) //상대방 정보 intent.putExtra("ChatRoomKey", "") //채팅방 키 context.startActivity(intent) (context as AppCompatActivity).finish() } override fun getItemCount(): Int { return users.size } inner class ViewHolder(itemView: ListPersonItemBinding) : RecyclerView.ViewHolder(itemView.root) { var background = itemView.background var txt_name = itemView.txtName var txt_email = itemView.txtEmail } }
사용자 목록을 불러오는 Recycler의 전체 코드다.
fun setupAllUserList() { //전체 사용자 목록 불러오기 val myUid = FirebaseAuth.getInstance().currentUser?.uid.toString() //현재 사용자 아이디 FirebaseDatabase.getInstance().getReference("User").child("users") //사용자 데이터 요청 .addValueEventListener(object : ValueEventListener { override fun onCancelled(error: DatabaseError) { } override fun onDataChange(snapshot: DataSnapshot) { users.clear() for (data in snapshot.children) { val item = data.getValue<User>() if (item?.uid.equals(myUid)) { currnentUser = item!! //전체 사용자 목록에서 현재 사용자는 제외 continue } allUsers.add(item!!) //전체 사용자 목록에 추가 } users = allUsers.clone() as ArrayList<User> notifyDataSetChanged() //화면 업데이트 } }) }
사용자들의 정보가 포함된 데이터베이스인 User 데이터베이스에 접근하여 목록을 가져와 저장한 뒤,
현재 사용자의 uid와 비교하여 자신은 제외한다.
fun searchItem(target: String) { //검색 if (target.equals("")) { //검색어 없는 경우 전체 목록 표시 users = allUsers.clone() as ArrayList<User> } else { var matchedList = allUsers.filter{ it.name!!.contains(target)}//검색어 포함된 항목 불러오기 users.clear() matchedList.forEach{users.add(it)} } notifyDataSetChanged() //화면 업데이트 }
사용자가 입력란에 검색어를 넣는 경우 위 코드를 실행하여 불러온 전체 목록에서 검색어를 포함하는 목록만 남겨 리스트를 업데이트 한다.
override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.txt_name.text= users[position].name holder.txt_email.text= users[position].email holder.background.setOnClickListener() { addChatRoom(position) //해당 사용자 선택 시 } } fun addChatRoom(position: Int) { //채팅방 추가 val opponent = users[position] //채팅할 상대방 정보 var database = FirebaseDatabase.getInstance().getReference("ChatRoom") //넣을 database reference 세팅 var chatRoom = ChatRoom( //추가할 채팅방 정보 세팅 mapOf(currnentUser.uid!!totrue, opponent.uid!!totrue), null ) var myUid = FirebaseAuth.getInstance().uid//내 Uid database.child("chatRooms") .orderByChild("users/${opponent.uid}").equalTo(true) //상대방 Uid가 포함된 채팅방이 있는 지 확인 .addListenerForSingleValueEvent(object : ValueEventListener { override fun onCancelled(error: DatabaseError) {} override fun onDataChange(snapshot: DataSnapshot) { if (snapshot.value== null) { //채팅방이 없는 경우 database.child("chatRooms").push().setValue(chatRoom).addOnSuccessListener{// 채팅방 새로 생성 후 이동 goToChatRoom(chatRoom, opponent) } } else { context.startActivity(Intent(context, MainActivity::class.java)) goToChatRoom(chatRoom, opponent) //해당 채팅방으로 이동 } } }) }
항목을 선택 시 채팅방 목록 중에서 해당 사용자의 Uid가 포함된 채팅방을 찾아 해당 채팅방 화면으로 이동하고, 없으면 새로 데이터베이스에 채팅방을 삽입한다.
완성된 화면이다.
참조
https://m.blog.naver.com/zoown13/222094002924https://cionman.tistory.com/72https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=traeumen927&logNo=221493556497https://lasbe.tistory.com/19
'Andorid' 카테고리의 다른 글
MVVM 적용기(1) (0) 2022.04.02 [Android]Firebase로 채팅 앱 만들기(6) (0) 2022.03.31 [Android]Firebase로 채팅 앱 만들기(4) (2) 2022.03.31 [Android]Firebase로 채팅 앱 만들기(3) (0) 2022.03.31 [Android]Firebase로 채팅 앱 만들기(2) (0) 2022.03.31