增加消息未读提示气泡

This commit is contained in:
squallzhjch
2023-01-06 13:46:55 +08:00
parent de0a2fe5fc
commit e569ab4a82
18 changed files with 210 additions and 66 deletions

View File

@@ -5,7 +5,4 @@ import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
open class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
}
}

View File

@@ -1,27 +1,42 @@
package com.navinfo.volvo.database.dao
import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.*
import com.navinfo.volvo.database.entity.GreetingMessage
import kotlinx.coroutines.flow.Flow
@Dao
interface GreetingMessageDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(vararg check: GreetingMessage)
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(list: List<GreetingMessage>)
@Insert
fun insert(message: GreetingMessage): Long
@Query("SELECT * FROM GreetingMessage where id =:id")
fun findCheckManagerById(id: Long): GreetingMessage?
@Update(onConflict = OnConflictStrategy.REPLACE)
fun update(message: GreetingMessage)
@Query("SELECT * FROM GreetingMessage")
fun findAllByFlow(): Flow<List<GreetingMessage>>
@Query("SELECT count(id) FROM GreetingMessage WHERE read = 0")
fun countUnreadByFlow(): Flow<Long>
/**
* 分页查询
*/
@Query("SELECT * FROM GreetingMessage")
fun findAllByDataSource(): PagingSource<Int, GreetingMessage>
/**
* 检查某条数据是否存在
*/
@Query("SELECT id From GreetingMessage WHERE id = :id LIMIT 1")
fun getMessageId(id: Long): Long
@Transaction
suspend fun insertOrUpdate(list: List<GreetingMessage>) {
for (message in list) {
val id = getMessageId(message.id)
if (id == 0L) {
insert(message)
}
}
}
}

View File

@@ -11,7 +11,7 @@ import org.jetbrains.annotations.NotNull
@TypeConverters(AttachmentConverters::class)
data class GreetingMessage @JvmOverloads constructor(
@PrimaryKey(autoGenerate = true)
var uuid:Long = 0,
var uuid: Long = 0,
var id: Long = 0,
var searchValue: String? = "",
var createBy: String? = "",
@@ -41,5 +41,6 @@ data class GreetingMessage @JvmOverloads constructor(
/**
* 附件列表
*/
var attachment: MutableList<Attachment> = mutableListOf()
var attachment: MutableList<Attachment> = mutableListOf(),
var read: Boolean = false,
)

View File

@@ -3,6 +3,7 @@ package com.navinfo.volvo.di.module
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.navinfo.volvo.di.key.ViewModelKey
import com.navinfo.volvo.ui.MainActivityViewModel
import com.navinfo.volvo.ui.fragments.home.HomeViewModel
import com.navinfo.volvo.ui.fragments.login.LoginViewModel
import com.navinfo.volvo.ui.fragments.message.ObtainMessageViewModel
@@ -19,6 +20,11 @@ abstract class ViewModelModule {
@Binds
abstract fun bindViewModelFactory(viewModelFactory: ViewModelFactory): ViewModelProvider.Factory
@IntoMap
@Binds
@ViewModelKey(MainActivityViewModel::class)
abstract fun bindMainViewModel(viewModel: MainActivityViewModel): ViewModel
@IntoMap
@Binds
@ViewModelKey(LoginViewModel::class)
@@ -33,4 +39,6 @@ abstract class ViewModelModule {
@Binds
@ViewModelKey(ObtainMessageViewModel::class)
abstract fun bindObtainMessageFragmentViewModel(viewModel: ObtainMessageViewModel): ViewModel
}

View File

@@ -3,13 +3,15 @@ package com.navinfo.volvo.repository.database
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import com.navinfo.volvo.database.AppDatabase
import com.navinfo.volvo.database.dao.GreetingMessageDao
import com.navinfo.volvo.database.entity.GreetingMessage
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class DatabaseRepositoryImp @Inject constructor(
private val messageDao: GreetingMessageDao
private val messageDao: GreetingMessageDao,
private val database: AppDatabase
) : DatabaseRepository {
companion object {
const val PAGE_SIZE = 20
@@ -20,4 +22,5 @@ class DatabaseRepositoryImp @Inject constructor(
messageDao.findAllByDataSource()
}.flow
}
}

View File

@@ -28,7 +28,9 @@ class NetworkRepositoryImp @Inject constructor(
val result = netWorkService.queryCardListByApp(stringBody)
if (result.isSuccessful) {
val body = result.body()
messageDao.insert(body!!.data!!.rows)
if(body!!.data != null && body.data!!.rows != null){
messageDao.insertOrUpdate(body.data!!.rows)
}
NetResult.Success(body)
} else {
NetResult.Success(null)

View File

@@ -0,0 +1,11 @@
package com.navinfo.volvo.ui
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import javax.inject.Inject
abstract class BaseActivity : AppCompatActivity() {
@Inject
lateinit var viewModelFactoryProvider: ViewModelProvider.Factory
}

View File

@@ -4,7 +4,11 @@ import android.content.DialogInterface
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
@@ -30,18 +34,23 @@ import com.navinfo.volvo.R
import com.navinfo.volvo.databinding.ActivityMainBinding
import com.navinfo.volvo.utils.SystemConstant
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
class MainActivity : BaseActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel by viewModels<MainActivityViewModel> { viewModelFactoryProvider }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setupNavigation()
XXPermissions.with(this)
// 申请单个权限
@@ -61,6 +70,7 @@ class MainActivity : AppCompatActivity() {
}
// 在SD卡创建项目目录
createRootFolder()
setupNavigation()
}
override fun onDenied(permissions: MutableList<String>, never: Boolean) {
@@ -89,6 +99,20 @@ class MainActivity : AppCompatActivity() {
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
lifecycleScope.launch{
viewModel.getUnreadCount().collect {
runOnUiThread{
if(it == 0L){
navView.removeBadge(R.id.navigation_home)
}else{
var badge = navView.getOrCreateBadge(R.id.navigation_home);
badge.number = it.toInt()
}
}
}
}
navController.addOnDestinationChangedListener { controller, destination, arguments ->
if (destination.id == R.id.navigation_home
|| destination.id == R.id.navigation_dashboard

View File

@@ -0,0 +1,17 @@
package com.navinfo.volvo.ui
import androidx.lifecycle.ViewModel
import androidx.paging.PagingData
import com.navinfo.volvo.database.dao.GreetingMessageDao
import com.navinfo.volvo.database.entity.GreetingMessage
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
class MainActivityViewModel @Inject constructor(
private val messageDao: GreetingMessageDao,
) : ViewModel() {
fun getUnreadCount(): Flow<Long> = messageDao.countUnreadByFlow()
}

View File

@@ -1,4 +1,4 @@
package com.navinfo.volvo.ui
package com.navinfo.volvo.ui.fragments
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider

View File

@@ -12,7 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.volvo.R
import com.navinfo.volvo.databinding.FragmentHomeBinding
import com.navinfo.volvo.tools.DisplayUtil
import com.navinfo.volvo.ui.BaseFragment
import com.navinfo.volvo.ui.fragments.BaseFragment
import com.yanzhenjie.recyclerview.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
@@ -21,27 +21,30 @@ import kotlinx.coroutines.launch
@AndroidEntryPoint
class HomeFragment : BaseFragment(), OnItemClickListener, OnItemMenuClickListener {
private var _binding: FragmentHomeBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
private val viewModel by viewModels<HomeViewModel> { viewModelFactoryProvider }
private lateinit var messageAdapter: HomeAdapter
private lateinit var mDataBinding: FragmentHomeBinding
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
mDataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
mDataBinding.lifecycleOwner = this
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
initView()
return mDataBinding.root
return root
}
private fun initView() {
mDataBinding.homeViewModel = viewModel
// mDataBinding.homeViewModel = viewModel
messageAdapter = HomeAdapter(this)
val recyclerview: SwipeRecyclerView = mDataBinding.homeRecyclerview
val recyclerview: SwipeRecyclerView = binding.homeRecyclerview
recyclerview.adapter = null //先设置null否则会报错
//创建菜单选项
//注意:使用滑动菜单不能开启滑动删除,否则只有滑动删除没有滑动菜单
@@ -96,6 +99,7 @@ class HomeFragment : BaseFragment(), OnItemClickListener, OnItemMenuClickListene
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
override fun onItemClick(view: View?, adapterPosition: Int) {

View File

@@ -4,14 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.navigation.Navigation
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import com.navinfo.volvo.R
import com.navinfo.volvo.databinding.FragmentLoginBinding
import com.navinfo.volvo.ui.BaseFragment
import com.navinfo.volvo.ui.fragments.BaseFragment
import dagger.hilt.android.AndroidEntryPoint

View File

@@ -13,9 +13,10 @@ import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File
import java.util.*
import javax.inject.Inject
class ObtainMessageViewModel: ViewModel() {
class ObtainMessageViewModel @Inject constructor() : ViewModel() {
private val msgLiveData: MutableLiveData<GreetingMessage> by lazy {
MutableLiveData<GreetingMessage>()
}
@@ -40,7 +41,7 @@ class ObtainMessageViewModel: ViewModel() {
for (attachment in this.msgLiveData.value!!.attachment) {
if (attachment.attachmentType == AttachmentType.PIC) {
if (picUrl==null||picUrl.isEmpty()) {
if (picUrl == null || picUrl.isEmpty()) {
this.msgLiveData.value!!.attachment.remove(attachment)
} else {
attachment.pathUrl = picUrl
@@ -48,8 +49,14 @@ class ObtainMessageViewModel: ViewModel() {
hasPic = true
}
}
if (!hasPic&&picUrl!=null) {
this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), picUrl, AttachmentType.PIC))
if (!hasPic && picUrl != null) {
this.msgLiveData.value!!.attachment.add(
Attachment(
UUID.randomUUID().toString(),
picUrl,
AttachmentType.PIC
)
)
}
this.msgLiveData.postValue(this.msgLiveData.value)
}
@@ -59,7 +66,7 @@ class ObtainMessageViewModel: ViewModel() {
var hasAudio = false
for (attachment in this.msgLiveData.value!!.attachment) {
if (attachment.attachmentType == AttachmentType.AUDIO) {
if (audioUrl==null||audioUrl.isEmpty()) {
if (audioUrl == null || audioUrl.isEmpty()) {
this.msgLiveData.value!!.attachment.remove(attachment)
} else {
attachment.pathUrl = audioUrl
@@ -67,8 +74,14 @@ class ObtainMessageViewModel: ViewModel() {
hasAudio = true
}
}
if (!hasAudio&&audioUrl!=null) {
this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), audioUrl, AttachmentType.AUDIO))
if (!hasAudio && audioUrl != null) {
this.msgLiveData.value!!.attachment.add(
Attachment(
UUID.randomUUID().toString(),
audioUrl,
AttachmentType.AUDIO
)
)
}
this.msgLiveData.postValue(this.msgLiveData.value)
}
@@ -97,7 +110,11 @@ class ObtainMessageViewModel: ViewModel() {
try {
val requestFile: RequestBody =
RequestBody.create("multipart/form-data".toMediaTypeOrNull(), attachmentFile)
val body = MultipartBody.Part.createFormData("picture", attachmentFile.getName(), requestFile)
val body = MultipartBody.Part.createFormData(
"picture",
attachmentFile.getName(),
requestFile
)
val result = NavinfoVolvoCall.getApi().uploadAttachment(body)
XLog.d(result.code)
if (result.code == 200) { // 请求成功