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

实现代码:
/** * Author : wangning * Email : maoning20080809@163.com * Date : 2022/5/21 12:46 * Description : 充值页面,没有接入银行系统,模拟充值成功 */ class RechargeFragment : BaseDataBindingFragment(), MyDispatchTouchEventListener { override fun getLayoutRes() = R.layout.wc_payment_recharge private val userViewModel : UserViewModel by viewModels() private var navController : NavController? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) super.builder().setTitleContent(R.string.wc_base_top_rechange) navController = findNavController() DispatchTouchEventUtils.registerDispatchTouchListener(this) rechange_balance.showSoftInputOnFocus = false num_keyboard_view.initEditText(rechange_balance) rechange_balance.setOnClickListener { num_keyboard_view.visibility = View.VISIBLE } num_keyboard_item_recharge.setOnClickListener { var result = rechange_balance.text.toString().trim() if(TextUtils.isEmpty(result)){ ToastUtils.makeText(requireActivity(), "请输入金额") return@setOnClickListener } //如果充值额度太大, 不能使用float类型,否则10个亿计算就会出错 if(result.toFloat() > CommonUtils.Base.MAX_BALANCE){ ToastUtils.makeText(R.string.wc_payment_balance_max) return@setOnClickListener } TagUtils.d("返回值:${result.toDouble()}") var account = DataStoreUtils.getAccount() userViewModel.updateBalanceServer(account, CommonUtils.User.OPERATOR_PLUS, result.toFloat()) } userViewModel.balanceLiveData.observe(viewLifecycleOwner){ if(it > 0){ ToastUtils.makeText(requireActivity(), "充值成功!") //弹出的id为fragment,不能为action Navigation.findNavController(num_keyboard_item_recharge).popBackStack(R.id.nav_small_change, true) EventBus.getDefault().post(RechargeBalanceBean(it)) } else { ToastUtils.makeText(requireActivity(), "充值失败!") } } } override fun onDestroy() { super.onDestroy() DispatchTouchEventUtils.unregisterDispatchTouchListener(this) } override fun dispatchTouchEvent(ev: MotionEvent) { if (ev.action == MotionEvent.ACTION_DOWN) { if (SoftInputUtils.isInput(rechange_balance, ev)) { num_keyboard_view?.visibility = View.GONE } } } override fun onResume() { super.onResume() rechange_balance.isFocusableInTouchMode = true rechange_balance.requestFocus() rechange_balance.setOnKeyListener { view, i, keyEvent -> if (i == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { if(num_keyboard_view.visibility == View.VISIBLE){ hideNumKeyboardView() true } else { false } } else { false } } } private fun hideNumKeyboardView(){ num_keyboard_view.visibility = View.GONE } private fun showNumKeyboardView(){ num_keyboard_view.visibility = View.VISIBLE } }
/**
* Author : wangning
* Email : maoning20080809@163.com
* Date : 2022/5/21 14:58
* Description : 自定义充值键盘
*/
class NumberKeyboardView : RelativeLayout , View.OnClickListener {
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){
initView()
}
private var view : View? = null
private var viewList = arrayOfNulls(13)
private var inputEditText : EditText? = null
private var result :String = ""
fun initView() {
view = LayoutInflater.from(WcApp.getContext()).inflate(R.layout.wc_number_keyboard_item, this, true)
viewList = arrayOf(findView(R.id.num_keyboard_item_1),findView(R.id.num_keyboard_item_2),findView(R.id.num_keyboard_item_3),findView(R.id.num_keyboard_item_4),
findView(R.id.num_keyboard_item_5),findView(R.id.num_keyboard_item_6),findView(R.id.num_keyboard_item_7),findView(R.id.num_keyboard_item_8),
findView(R.id.num_keyboard_item_9),findView(R.id.num_keyboard_item_0),findView(R.id.delete),findView(R.id.num_keyboard_item_spot),findView(R.id.num_keyboard_item_recharge),)
setListener()
}
private fun setListener(){
for (item in viewList) {
item?.setOnClickListener(this)
}
}
override fun onClick(v: View) {
when(v.id) {
R.id.delete -> {
if(result.length > 0){
result = result.substring(0, result.length - 1)
inputEditText?.setText(result)
inputEditText?.setSelection(result.length)
}
}
R.id.num_keyboard_item_recharge -> {TagUtils.d("充值222")}
else -> {
var numberView = v as TextView
result += numberView.text.toString()
inputEditText?.setText(result)
//光标放在最后
inputEditText?.setSelection(result.length)
}
}
}
fun initEditText(inputET: EditText){
inputEditText = inputET
}
//设置充值按钮的背景
fun setRechargeBackground(resId : Int){
num_keyboard_item_recharge.setBackgroundResource(resId)
}
fun setValue(resId: Int){
num_keyboard_item_recharge.text = BaseUtils.getString(resId)
}
private fun findView(id : Int) : View {
return view?.findViewById(id)!!
}
}