Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
效果图:

实现代码:
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/4/21 21:18 * Description : 根据账户搜索用户 */ class SearchFriendsFragment : BaseDataBindingFragment() { override fun getLayoutRes() = R.layout.wc_fragment_contacts_search private val xmppViewModel : XmppViewModel by viewModels() private val userViewModel : UserViewModel by viewModels() private val contactViewModel : ContactsViewModel by viewModels() private var adapter : SearchContactsAdapter? = null //好友列表 private var contactsList : MutableList ? = null private var navController : NavController? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) super.builder().setTitleContent("") navController = findNavController() contacts_search_cancel.setOnClickListener { Navigation.findNavController(it).popBackStack() } var account = DataStoreUtils.getAccount() contacts_search_result_layout.setOnClickListener { TagUtils.d("搜索查询:${contacts_search_phone.text.toString()}") //xmppViewModel.searchUserByName(contacts_search_phone.text.toString()) userViewModel.getUserLikeAccount(account, contacts_search_phone.text.toString()) } contacts_search_phone.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) { //TagUtils.d("onTextChanged ${s}, , count = ${count}, length = ${s?.length}") if(s?.length!! > 0){ var result = getString(R.string.wc_search_friend_tips, s) contacts_search_result_layout.visibility = View.VISIBLE contacts_search_result_txt.text = result } else { contacts_search_result_layout.visibility = View.GONE contacts_search_recycler_view.visibility = View.GONE } } override fun afterTextChanged(s: Editable?) { } }) userViewModel.getUserListLiveData.observe(viewLifecycleOwner){ if(it == null || it.size < 1){ ToastUtils.makeText(R.string.search_list_empty) } else { contacts_search_recycler_view.visibility = View.VISIBLE adapter?.refresh(it) } } contactViewModel.getContactsList(account) contactViewModel.contactsListLiveData.observe(viewLifecycleOwner){ contactsList = it } /*xmppViewModel.userListDataLiveData.observe(viewLifecycleOwner){ contacts_search_recycler_view.visibility = View.VISIBLE adapter?.refresh(it) }*/ adapter = SearchContactsAdapter() var linearLayoutManager = LinearLayoutManager(activity) linearLayoutManager.orientation = LinearLayoutManager.VERTICAL contacts_search_recycler_view.layoutManager = linearLayoutManager contacts_search_recycler_view.adapter = adapter adapter?.setOnItemClickInterface(object : SearchContactsAdapter.OnItemClickInterface{ override fun onItemClick(userBean: UserBean) { SoftInputUtils.hideSoftInput(contacts_search_result_layout) navController?.popBackStack(R.id.nav_contacts_add_friends, true) if(isFriend(userBean.account)) { //如果是好友,直接跳转到聊天页面 var bundle = bundleOf(ChatFragment.USER_ID to userBean.account) navController?.navigate(R.id.nav_chat, bundle) } else { val bundle = bundleOf("userbean" to userBean) navController?.navigate(R.id.action_contacts_search_friends_details, bundle) } } }) } private fun isFriend(searchAccount : String) : Boolean{ var resultList = contactsList?.filter { it.toAccount.equals(searchAccount) } return resultList?.size!! > 0 } }
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/4/22 17:51 * Description : */ class SearchContactsAdapter : RecyclerView.Adapter(){ private var userList = ArrayList () private var onItemClickInterface :OnItemClickInterface? = null fun setOnItemClickInterface(onItemClickInterface :OnItemClickInterface?){ this.onItemClickInterface = onItemClickInterface } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SearchViewHolder { var view = LayoutInflater.from(parent.context).inflate(R.layout.wc_fragment_contacts_search_item, parent, false) return SearchViewHolder(view) } override fun onBindViewHolder(holder: SearchViewHolder, position: Int) { var userBean = userList.get(position) holder.account.text = BaseUtils.getString(R.string.wc_search_friend_account, userBean.account) holder.account.setOnClickListener { onItemClickInterface?.onItemClick(userBean) } } fun refresh(userList : ArrayList ) { if(userList == null || userList.size == 0){ this.userList = ArrayList () } else { this.userList = userList } notifyDataSetChanged() } override fun getItemCount(): Int = userList?.size class SearchViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView) { var account = itemView.findViewById (R.id.contacts_search_item_account) } interface OnItemClickInterface{ abstract fun onItemClick(userBean: UserBean) } }