Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
效果图:
实现代码:
<?xml version="1.0" encoding="utf-8"?> <layout > <androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/notification_setting_root" 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.AppCompatTextView android:id="@+id/notifi_tip" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="@+id/notifi_tip_cb" app:layout_constraintBottom_toBottomOf="@+id/notifi_tip_cb" app:layout_constraintStart_toStartOf="parent" android:layout_marginLeft="12dp" android:text="消息提示:"/> <CheckBox android:id="@+id/notifi_tip_cb" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginRight="12dp" android:layout_marginTop="30dp" android:checked="true" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/base_top_root_layout"/> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/notifi_voice_tip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:paddingVertical="10dp" app:layout_constraintTop_toBottomOf="@+id/notifi_tip" app:layout_constraintStart_toStartOf="@+id/notifi_tip" android:text="消息声音:"/> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/notifi_voice_content" app:layout_constraintTop_toTopOf="@+id/notifi_voice_tip" app:layout_constraintBottom_toBottomOf="@+id/notifi_voice_tip" app:layout_constraintStart_toEndOf="@+id/notifi_voice_tip" app:layout_constraintEnd_toEndOf="@+id/notifi_tip_cb" android:gravity="right" android:paddingVertical="10dp" android:layout_width="0dp" android:layout_height="wrap_content" android:drawableRight="@drawable/wc_notification_setting_arrow_down" android:drawablePadding="6dp" android:paddingRight="8dp" android:text="已选择声音:"/> <androidx.appcompat.widget.AppCompatTextView android:id="@+id/notifi_important_tip" app:layout_constraintTop_toBottomOf="@id/notifi_voice_tip" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" android:gravity="right" android:paddingVertical="10dp" android:layout_marginTop="40dp" android:layout_marginHorizontal="12dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="@color/red" android:textSize="18sp" android:visibility="gone" android:text="@string/wc_notification_setting_content2"/> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/7/3 18:56 * Description : 消息通知设置 */ class NotificationSettingFragment : BaseDataBindingFragment<WcNotificationSettingRootBinding>(){ override fun getLayoutRes() = R.layout.wc_notification_setting_root private var notificationSettingMsg : NotificationSettingMsg? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) super.builder().setTitleContent(R.string.wc_base_top_notify_message) notificationSettingMsg = NotificationSettingMsg() notifi_voice_content.setOnClickListener { showSingleDialog() } processNotification() notifi_tip_cb.setOnCheckedChangeListener { compoundButton, b -> if(!ChatNotificationUtils.isNotificationEnabled()){ processNotification() } else { if(b){ showVoiceTip() } else { hideVoiceTip() } DataStoreUtils.put(CommonUtils.Notification.Notify_TIP, b) } } var checkedId = DataStoreUtils.get(CommonUtils.Notification.SELECTED_VOICE_ID,1) as Int notifi_voice_content.text = BaseUtils.getString(R.string.wc_notification_setting_selected_voice, items.get(checkedId)) if(notifi_tip_cb.isChecked){ showVoiceTip() } else { hideVoiceTip() } } override fun onResume() { super.onResume() notification_setting_root.isFocusableInTouchMode = true notification_setting_root.requestFocus() notification_setting_root.setOnKeyListener { view, i, keyEvent -> if (i == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { TagUtils.d("onResume .> ${notificationSettingMsg} , ${notificationSettingMsg?.isShowing()}") if(notificationSettingMsg != null && notificationSettingMsg?.isShowing() != null && notificationSettingMsg?.isShowing()!!){ return@setOnKeyListener true } } return@setOnKeyListener false } } override fun onHiddenChanged(hidden: Boolean) { super.onHiddenChanged(hidden) if(!hidden){ processNotification() } } private fun hideVoiceTip(){ notifi_voice_tip.visibility = View.GONE notifi_voice_content.visibility = View.GONE } private fun showVoiceTip(){ notifi_voice_tip.visibility = View.VISIBLE notifi_voice_content.visibility = View.VISIBLE } /** * 判断手机通知栏是否启用, 如果不启用,跳转到页面开启 */ private fun processNotification(){ if(!ChatNotificationUtils.isNotificationEnabled()){ showVoiceTip() notifi_important_tip.visibility = View.VISIBLE notifi_tip_cb.isChecked = false notificationSettingMsg?.showNotificationSetting(requireActivity(), notification_setting_root, true, object : BasePopupWindow.IOnDismissListener{ override fun onDismiss() { if(!ChatNotificationUtils.isNotificationEnabled()) { showVoiceTip() notifi_important_tip.visibility = View.VISIBLE notifi_tip_cb.isChecked = false } else { hideVoiceTip() notifi_important_tip.visibility = View.GONE notifi_tip_cb.isChecked = DataStoreUtils.get(CommonUtils.Notification.Notify_TIP, true) as Boolean } } }) } else { hideVoiceTip() notifi_important_tip.visibility = View.GONE notifi_tip_cb.isChecked = DataStoreUtils.get(CommonUtils.Notification.Notify_TIP, true) as Boolean } } val items = arrayOf("无声音", "宿鸟流萤", "BB机", "老式闹钟", "鸟叫", "弹簧", "经典", "消失", "水滴") fun showSingleDialog(){ var checkedId = DataStoreUtils.get(CommonUtils.Notification.SELECTED_VOICE_ID,1) as Int TagUtils.d("开始选择:${checkedId}") val builder = AlertDialog.Builder(requireActivity()) .setTitle("请选择消息声音") .setSingleChoiceItems(items, checkedId, DialogInterface.OnClickListener { dialogInterface, i -> TagUtils.d("选择:${i}") checkedId = i CommonUtils.Notification.playNotification(i) }) .setPositiveButton("确定", DialogInterface.OnClickListener { dialogInterface, i -> DataStoreUtils.put(CommonUtils.Notification.SELECTED_VOICE_ID, checkedId) notifi_voice_content.text = BaseUtils.getString(R.string.wc_notification_setting_selected_voice, items.get(checkedId)) dialogInterface.dismiss() }) .setNegativeButton("取消", null) .show() //修改 确定取消 按钮的字体大小 builder.getButton(AlertDialog.BUTTON_POSITIVE).textSize = 20f builder.getButton(AlertDialog.BUTTON_POSITIVE).setTextColor(BaseUtils.getColor(R.color.color05C160)) builder.getButton(DialogInterface.BUTTON_NEGATIVE).textSize = 20f builder.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(BaseUtils.getColor(R.color.color05C160)) //下面是改变显示内容的字体和颜色 /*try { //获取mAlert对象 val mAlert: Field = AlertDialog::class.java.getDeclaredField("mAlert") mAlert.setAccessible(true) val mAlertController: Any = mAlert.get(builder) //获取mTitleView并设置大小颜色 val mTitle: Field = mAlertController.javaClass.getDeclaredField("mTitleView") mTitle.setAccessible(true) val mTitleView = mTitle.get(mAlertController) as TextView mTitleView.textSize = 40f mTitleView.setTextColor(Color.YELLOW) //获取mMessageView并设置大小颜色 val mMessage: Field = mAlertController.javaClass.getDeclaredField("mMessageView") mMessage.setAccessible(true) val mMessageView = mMessage.get(mAlertController) as TextView mMessageView.setTextColor(Color.RED) mMessageView.textSize = 30f } catch (e: IllegalAccessException) { e.printStackTrace() } catch (e: NoSuchFieldException) { e.printStackTrace() }*/ } }