Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
Kotlin高仿微信-项目实践58篇,点击查看详情
效果图:
实现代码:
<?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:background="@drawable/wc_base_bg"> <include layout="@layout/wc_base_top_title" /> <androidx.appcompat.widget.AppCompatEditText android:id="@+id/vip_query_name" android:layout_marginLeft="12dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@+id/vip_query_btn" app:layout_constraintTop_toTopOf="@+id/vip_query_btn" app:layout_constraintBottom_toBottomOf="@+id/vip_query_btn" android:hint="@string/wc_vip_manager_query_tip" android:layout_marginRight="10dp" android:layout_width="0dp" android:layout_height="wrap_content"/> <androidx.appcompat.widget.AppCompatButton android:id="@+id/vip_query_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginRight="12dp" android:text="查询" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/base_top_root_layout" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/vip_recyclerview" app:layout_constraintTop_toBottomOf="@+id/vip_query_btn" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginTop="12dp" android:layout_width="match_parent" android:layout_height="0dp"/> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/6/19 22:58 * Description : Vip管理页面 */ class VipManagerFragment : BaseDataBindingFragment<WcVipManagerItemBinding>(){ override fun getLayoutRes() = R.layout.wc_vip_manager_main private var adapter: VipManagerAdapter = VipManagerAdapter(mutableListOf()) private val vipManagerViewModel : VipManagerViewModel by viewModels() private val userViewModel: UserViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) super.builder().setTitleContent(R.string.wc_base_top_vip_manager) var linearLayoutManager = LinearLayoutManager(requireContext()) linearLayoutManager?.orientation = LinearLayoutManager.VERTICAL vip_recyclerview.layoutManager = linearLayoutManager vip_recyclerview.adapter = adapter var account = DataStoreUtils.getAccount() var userBean = userViewModel.getUserLocalAsync(account) TagUtils.d("获取vip操作员账号:${userBean.account}, ${userBean.nickName}") adapter.setOperatorName(userBean.nickName) adapter.setOnItemClick(object : OnItemClickVip{ override fun onItemClick(month: Int, vipBean: VipBean) { showVipConfirmDialog(month, vipBean) } }) vipManagerViewModel.getVipListServer(0) vipManagerViewModel.vipListServer.observe(viewLifecycleOwner){ if(it == null){ ToastUtils.makeText(R.string.wc_load_data_error) } else { adapter.refresh(it) } } vipManagerViewModel.isSuccessLiveData.observe(viewLifecycleOwner){ if(it){ ToastUtils.makeText(R.string.wc_vip_renewal_success) } else { ToastUtils.makeText(R.string.wc_vip_renewal_failure) } } vip_query_btn.setOnClickListener { if(TextUtils.isEmpty(vip_query_name.text.toString().trim())){ ToastUtils.makeText(R.string.wc_query_name_empty) } else { vipManagerViewModel.getVipListLikeServer(0, vip_query_name.text.toString().trim()) } } } /** * 开通vip确认框 */ private fun showVipConfirmDialog(month: Int, vipBean: VipBean){ if(month < 1 || vipBean == null){ ToastUtils.makeText(R.string.wc_vip_confirm_show_error) return } getFocus(true) var view = LayoutInflater.from(requireContext()).inflate(R.layout.wc_vip_confirm_view, null) var width = DisplayUtils.getScreenWidth() - BaseUtils.getDimension(R.dimen.distance_40) * 2 val popupWindow = PopupWindow(view, width, ViewGroup.LayoutParams.WRAP_CONTENT) popupWindow.isOutsideTouchable = false //点击弹窗外部是否取消弹窗 //弹窗出现外部为阴影 val attributes: WindowManager.LayoutParams = requireActivity().window.getAttributes() attributes.alpha = 0.5f requireActivity().window.setAttributes(attributes) //弹窗取消监听 取消之后恢复阴影 popupWindow.setOnDismissListener { val attributes: WindowManager.LayoutParams = requireActivity().window.getAttributes() attributes.alpha = 1f requireActivity().window.setAttributes(attributes) getFocus(false) } popupWindow.showAtLocation(vip_recyclerview, Gravity.CENTER, 0, 0) var accountTextView = view.findViewById<TextView>(R.id.vip_confirm_account) var nameTextView = view.findViewById<TextView>(R.id.vip_confirm_name) var monthTextView = view.findViewById<TextView>(R.id.vip_confirm_month) accountTextView.text = BaseUtils.getString(R.string.wc_vip_manager_user_account, vipBean.userAccount) nameTextView.text = BaseUtils.getString(R.string.wc_vip_manager_user_name, vipBean.userName) monthTextView.text = BaseUtils.getString(R.string.wc_vip_confirm_month, "${month}") view.findViewById<TextView>(R.id.vip_confirm_cancel).setOnClickListener { popupWindow.dismiss() } view.findViewById<TextView>(R.id.vip_confirm_ok).setOnClickListener { popupWindow.dismiss() vipManagerViewModel.updateVip(vipBean.userAccount, vipBean.operatorAccount, month) } } private fun getFocus(isForbidBack : Boolean){ view?.isFocusableInTouchMode = true view?.requestFocus() view?.setOnKeyListener { view, keyCode, event -> if(event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){ if(isForbidBack){ ToastUtils.makeText(R.string.wc_vip_confirm_back) } } isForbidBack } } }