Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
效果图:
实现代码:
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/4/21 12:24 * Description : 一行通用控件, 左边一个图标, 右边一个箭头, 中间有标题和描述 */ class LineBaseView : LinearLayout { constructor(context:Context) : this(context, null) constructor(context: Context, attributeSet: AttributeSet?) : this(context, attributeSet, 0) constructor(context: Context, attributeSet: AttributeSet? , defStyleAttr : Int) : super(context, attributeSet, defStyleAttr){ } var baseView : View? = null init { baseView = LayoutInflater.from(context).inflate(R.layout.wc_line_base_view, this) } fun builder() : Builder{ return Builder(line_base_left, line_base_right, line_base_title, line_base_content, line_base_root, line_base_dividing) } class Builder(leftImageView : ImageView, rightImageView : ImageView, titleTextView : TextView, contentTextView : TextView, rootView : ConstraintLayout, dividingView : TextView) { private var leftImageView : ImageView = leftImageView private var rightImageView = rightImageView private var titleTextView = titleTextView private var contentTextView = contentTextView private var rootView = rootView private var dividingView = dividingView fun setLeftImage(resId : Int) : Builder{ leftImageView.setImageResource(resId) return this } fun setLeftClick(onClickListener: OnClickListener) : Builder{ leftImageView.setOnClickListener(onClickListener) return this } fun hideLeftImage() : Builder { leftImageView.visibility = GONE return this } fun setTitle(resId: Int) : Builder { titleTextView.text = WcApp.getContext().resources.getString(resId) return this } fun setTitle(title: String) : Builder { titleTextView.text = title return this } fun setTitleColor(colorId : Int) : Builder { titleTextView.setTextColor(WcApp.getContext().resources.getColor(colorId)) return this } fun setTitleSize(size : Float) : Builder{ titleTextView.setTextSize(size) return this } fun setContentSize(size : Float) : Builder{ contentTextView.setTextSize(size) return this } fun setContentColor(colorId : Int) : Builder { contentTextView.setTextColor(WcApp.getContext().resources.getColor(colorId)) return this } fun setContent(resId : Int) : Builder { contentTextView.text = WcApp.getContext().resources.getString(resId) return this } fun setContent(content : String) : Builder { contentTextView.text = content return this } fun hideContent() : Builder{ contentTextView.visibility = GONE return this } fun showContent() : Builder{ contentTextView.visibility = VISIBLE return this } fun setRightImage(resId : Int) : Builder{ rightImageView.setImageResource(resId) return this } fun setRightClick(onClickListener: OnClickListener) : Builder { rightImageView.setOnClickListener(onClickListener) return this } fun hideRightImage() : Builder { rightImageView.visibility = GONE return this } fun setRootClick(onClickListener: OnClickListener) : Builder { rootView.setOnClickListener(onClickListener) return this } fun hideDevideingView() : Builder{ dividingView.visibility = View.GONE return this } } }
/** * author : wangning * email : maoning20080809@163.com * Date : 2022/4/7 13:12 * description : 我的页面 */ class MeFragment : BaseDataBindingFragment() { override fun getLayoutRes()= R.layout.wc_fragment_me //文件存储权限 private val REQ_CODE_STORAGE = 1 private val userViewModel : UserViewModel by viewModels() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initView() me_personal_avatar.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_me_personal) } //handlePermission() initData() //先判断是否已经注册 if(!EventBus.getDefault().isRegistered(this)){ EventBus.getDefault().register(this) } } @Subscribe(threadMode = ThreadMode.MAIN) fun onMessageCallback(obj: Any) { if(obj == null){ return } if(obj is EventMsgBean){ if(obj.type == EventMsgBean.TYPE_REFRESH_USER_NAME){ //刷新昵称 me_personal_name.text = obj.obj as String } else if(obj.type == EventMsgBean.TYPE_REFRESH_AVATAR){ //刷新头像 GlideUtils.load(me_personal_img, obj.obj as String) } } } override fun onDestroy() { super.onDestroy() EventBus.getDefault().unregister(this) } fun initView() { //支付 me_payment.builder() .setLeftImage(R.drawable.me_base_payment) .setTitle(BaseUtils.getString(R.string.me_base_payment)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.action_me_payment) } /*//收藏 me_collection.builder() .setLeftImage(R.drawable.me_base_collection) .setTitle(BaseUtils.getString(R.string.me_base_collection)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.action_me_collection) }*/ //朋友圈 me_moments.builder() .setLeftImage(R.drawable.me_base_moments) .setTitle(BaseUtils.getString(R.string.me_base_moments)) .hideContent() .setRootClick { //旧的没实现 navCollection?.navigate(R.id.action_me_moments) Navigation.findNavController(it).navigate(R.id.action_discover_moments) } //扫一扫 me_scan.builder() .setLeftImage(R.drawable.wc_moments_scan) .setTitle(BaseUtils.getString(R.string.me_moments_sanc)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.nav_qrcode_scan) } /*//视频号 me_video.builder() .setLeftImage(R.drawable.me_base_video) .setTitle(BaseUtils.getString(R.string.me_base_video)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.action_me_video) }*/ //卡包 /*me_card_bag.builder() .setLeftImage(R.drawable.me_base_card_bag) .setTitle(BaseUtils.getString(R.string.me_base_card_bag)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.action_me_card_bag) }*/ /*//表情 me_expression.builder() .setLeftImage(R.drawable.me_base_expression) .setTitle(BaseUtils.getString(R.string.me_base_expression)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.action_me_expression) }*/ //设置 me_setting.builder() .setLeftImage(R.drawable.me_base_setting) .setTitle(BaseUtils.getString(R.string.me_base_setting)) .hideContent() .setRootClick { Navigation.findNavController(it).navigate(R.id.action_me_setting) } } fun initData(){ var account = DataStoreUtils.getAccount() userViewModel.getUserLocal(account) userViewModel.userBeanLocal.observe(viewLifecycleOwner){ if(it == null) return@observe me_personal_name.text = it.nickName var accountResult = getString(R.string.wc_me_show_account, it.account) me_personal_account.text = accountResult GlideUtils.load(me_personal_img, it.getReallyAvatar(), R.drawable.contacts_default_icon) } userViewModel.avatarFilePathLiveData.observe(viewLifecycleOwner){ if(!TextUtils.isEmpty(it)){ GlideUtils.load(me_personal_img, it) } } } //授权成功,刷新页面 fun refresh(){ initData() } }