Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。
效果图:
实现代码:
// 打开相册 ImageSelector.builder() .useCamera(true) // 设置是否使用拍照 .setSingle(true) //设置是否单选 .canPreview(true) //是否点击放大图片查看,,默认为true .start(this,REQUEST_CODE)
/** * author : wangning * email : maoning20080809@163.com * Date : 2022/4/15 22:20 * description : 裁剪头像 */ class ClipImageActivity : AppCompatActivity(), View.OnClickListener { //类别 1: 圆形头像, 2: 方形头像 private var type = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.wc_clip_image) type = intent.getIntExtra("type", 1) initView() } /** * 初始化组件 */ fun initView() { //设置点击事件监听器 iv_back.setOnClickListener(this) btn_cancel.setOnClickListener(this) bt_ok.setOnClickListener(this) } override fun onResume() { super.onResume() if (type == 1) { clipViewLayout1.visibility = View.VISIBLE clipViewLayout2.visibility = View.GONE //设置图片资源 clipViewLayout1.setImageSrc(intent.data) } else { clipViewLayout2.visibility = View.VISIBLE clipViewLayout1.visibility = View.GONE //设置图片资源 clipViewLayout2.setImageSrc(intent.data) } } override fun onClick(v: View) { when (v.id) { R.id.iv_back -> finish() R.id.btn_cancel -> finish() R.id.bt_ok -> generateUriAndReturn() } } /** * 生成Uri并且通过setResult返回给打开的activity */ private fun generateUriAndReturn() { //调用返回剪切图 val zoomedCropBitmap: Bitmap? zoomedCropBitmap = if (type == 1) { clipViewLayout1.clip() } else { clipViewLayout2.clip() } if (zoomedCropBitmap == null) { TagUtils.e( "zoomedCropBitmap == null") return } var file = File(cacheDir, "cropped_" + System.currentTimeMillis() + ".jpg") val mSaveUri = Uri.fromFile(file) TagUtils.d("保存路径file:${mSaveUri.path}" ) TagUtils.d("保存路径mSaveUri:${mSaveUri.path}" ) if (mSaveUri != null) { var outputStream: OutputStream? = null try { outputStream = contentResolver.openOutputStream(mSaveUri) if (outputStream != null) { zoomedCropBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream) } } catch (ex: IOException) { Log.e("android", "Cannot open file: $mSaveUri", ex) } finally { if (outputStream != null) { try { outputStream.close() } catch (e: IOException) { e.printStackTrace() } } } val intent = Intent() intent.data = mSaveUri setResult(RESULT_OK, intent) finish() } } companion object { private const val TAG = "ClipImageActivity" } }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_CODE && data != null) { val images = data.getStringArrayListExtra(ImageSelector.SELECT_RESULT) if(images != null && images.size > 0) { gotoClipActivity(images[0]) } } else if(requestCode == REQUEST_CROP_PHOTO && data != null){ var uri : Uri? = data.data var bitmap = BitmapFactory.decodeFile(uri?.path) personal_avatar_img.setImageBitmap(bitmap) userViewModel.uploadAvatar(uri?.path!!) } }
//上传头像 fun uploadAvatar(filePath : String) { //var filePath = "/sdcard/image/a.jpg" CoroutineScope(Dispatchers.IO).launch { var resultFilePath = UploadFileUtils.uploadAvatar(filePath) if(!TextUtils.isEmpty(resultFilePath)){ var account = DataStoreUtils.getAccount() var userBean = UserRepository.getUserByAccount(account) userBean.avatar = resultFilePath var result = UserRepository.updateUser(userBean) if(result > 0){ avatarFilePathLiveData.postValue(BaseUtils.BASE_URL_UPLOAD + resultFilePath) } val userStr = Gson().toJson(userBean) UserService.getApi().updateUser(user = userStr) } } }