Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
效果图:
实现代码:
<?xml version="1.0" encoding="utf-8"?> <layout> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:focusable="true" android:background="@drawable/wc_base_bg"> <androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/search_details_toplayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/white" android:paddingVertical="50dp" android:layout_marginTop="20dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"> <androidx.appcompat.widget.AppCompatImageView android:id="@+id/search_details_icon" android:layout_width="80dp" android:layout_height="80dp" android:layout_marginStart="14dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:src="@drawable/contacts_default_icon"/> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/search_details_name" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toEndOf="@+id/search_details_icon" app:layout_constraintTop_toTopOf="@+id/search_details_icon" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:textColor="@color/black" android:textStyle="bold" android:textSize="26sp" android:text="顺宏"/> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/search_details_account" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toEndOf="@+id/search_details_icon" app:layout_constraintBottom_toBottomOf="@+id/search_details_icon" android:layout_marginLeft="10dp" android:layout_marginBottom="10dp" android:textColor="@color/gray" android:textSize="18sp" android:text="账号:"/> </androidx.constraintlayout.widget.ConstraintLayout> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/search_details_add" app:layout_constraintTop_toBottomOf="@+id/search_details_toplayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:paddingVertical="20dp" android:gravity="center" android:textColor="@color/blue" android:background="@color/white" android:textSize="20sp" android:text="添加到通讯录"/> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/4/22 20:01 * Description : 查询朋友详情-添加到通讯录 */ class SearchFriendsDetailsFragment : BaseDataBindingFragment<WcFragmentContactsSearchDetailsBinding>() { override fun getLayoutRes()= R.layout.wc_fragment_contacts_search_details override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) super.builder().setTitleContent(R.string.wc_base_top_add_friends) //var account = arguments?.getString("account")?:"默认值demo1" var userBean = arguments?.getSerializable("userbean") as UserBean TagUtils.d("接收的值:${userBean}") search_details_add.setOnClickListener { if(!NetWorkUtils.isNetworkConnected()){ ToastUtils.makeText(R.string.wc_base_network_error) } else { showLoadingDialog() addFriend(userBean?.account) } } userBean.let { search_details_account.text = "账号:${it.account}" search_details_name.text = "${it.nickName}" //var avatar = if(TextUtils.isEmpty(it.avatar)) "" else it.avatar var avatar = it.avatar ?:"" TagUtils.d("头像:${avatar}") GlideUtils.load(search_details_icon, CommonUtils.Base.getReallyImage(avatar)) } } //添加好友 fun addFriend(toAccount : String){ CoroutineScope(Dispatchers.IO).launch { var result = UserRepository.getUserServer(toAccount) if(result.isSuccess){ //插入朋友账户到用户表 UserRepository.insertUser(GsonUtils.getUserBean(result.data!!)) //插入朋友账户到通讯录表 var fromAccount = DataStoreUtils.getAccount() var contactsBean = ContactsBean(fromAccount, toAccount) ContactsRepository.insertContactsLocal(contactsBean) ContactsRepository.insertContactsServer(contactsBean) //先保证本地数据库有好友账户信息, 再关联xmpp账户,否则很容易出现xmpp成功了,本地数据库没数据。 var subscription = Presence(Presence.Type.subscribe) subscription.to = toAccount +"@" + BaseUtils.SERVER_NAME var connection = WcApp.getXmppConnection() var roster = connection.roster roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all) TagUtils.d("我的添加好友:${toAccount}") //添加好友 roster.createEntry(toAccount +"@" + BaseUtils.SERVER_NAME, toAccount, null) connection.sendPacket(subscription) //刷新好友列表 EventBus.getDefault().post(EventMsgBean(EventMsgBean.TYPE_REFRESH_CONTACTS)) CoroutineScope(Dispatchers.Main).launch { ToastUtils.makeText(requireActivity(), "添加好友:${toAccount}") Navigation.findNavController(search_details_add).popBackStack() } } else { CoroutineScope(Dispatchers.Main).launch { ToastUtils.makeText(R.string.wc_add_friend_failure) } } dismissLoadingDialog() } } private var loadingUtils : BaseDialogUtils? = null //显示加载对话框 private fun showLoadingDialog(){ loadingUtils = BaseDialogUtils(requireActivity()) loadingUtils!!.builder() .hideCancel() .hideConfirm() .setCancelable(true) .setOnLoadingClick(object : BaseDialogUtils.OnLoadingClick{ override fun onClickCancel() { ToastUtils.makeText(requireActivity(), "对话框取消按钮") } override fun onClickConfirm() { ToastUtils.makeText(requireActivity(), "对话框确定按钮") } }) loadingUtils?.show() } //隐藏加载对话框 private fun dismissLoadingDialog(){ loadingUtils?.dismiss() } }