优化列表更新和红点显示
This commit is contained in:
parent
13f3516566
commit
7b5b4b08e5
@ -9,6 +9,8 @@ class Constant {
|
||||
*/
|
||||
const val SERVER_ADDRESS = "http://ec2-52-81-73-5.cn-north-1.compute.amazonaws.com.cn:8088/"
|
||||
val DEBUG = Boolean.parseBoolean("true")
|
||||
|
||||
const val message_status_late = "预约,待发送"
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +1,39 @@
|
||||
package com.navinfo.volvo
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Application
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.os.Bundle
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
open class MyApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
|
||||
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||
}
|
||||
|
||||
override fun onActivityStarted(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityResumed(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityPaused(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivityStopped(activity: Activity) {
|
||||
}
|
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
|
||||
}
|
||||
|
||||
override fun onActivityDestroyed(activity: Activity) {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package com.navinfo.volvo.database.dao
|
||||
|
||||
import android.util.Log
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.room.*
|
||||
import com.navinfo.volvo.Constant
|
||||
import com.navinfo.volvo.database.entity.GreetingMessage
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@ -20,7 +22,7 @@ interface GreetingMessageDao {
|
||||
/**
|
||||
* 未读消息统计
|
||||
*/
|
||||
@Query("SELECT count(id) FROM GreetingMessage WHERE read = 0")
|
||||
@Query("SELECT count(id) FROM GreetingMessage WHERE status = '${Constant.message_status_late}'")
|
||||
fun countUnreadByFlow(): Flow<Long>
|
||||
|
||||
/**
|
||||
@ -32,8 +34,8 @@ interface GreetingMessageDao {
|
||||
/**
|
||||
* 检查某条数据是否存在
|
||||
*/
|
||||
@Query("SELECT id From GreetingMessage WHERE id = :id LIMIT 1")
|
||||
suspend fun getMessageId(id: Long): Long
|
||||
@Query("SELECT uuid From GreetingMessage WHERE id = :id LIMIT 1")
|
||||
suspend fun getMessageId(id: Long): Long?
|
||||
|
||||
/**
|
||||
*
|
||||
@ -41,12 +43,18 @@ interface GreetingMessageDao {
|
||||
@Transaction
|
||||
suspend fun insertOrUpdate(list: List<GreetingMessage>) {
|
||||
for (message in list) {
|
||||
val id = getMessageId(message.id)
|
||||
if (id == 0L) {
|
||||
insert(message)
|
||||
Log.e("jingo", "insertOrUpdate ${message.id}")
|
||||
val uuid = getMessageId(message.id)
|
||||
Log.e("jingo", "insertOrUpdate $uuid")
|
||||
if (uuid == null || uuid == 0L) {
|
||||
Log.e("jingo", "insertOrUpdate start ")
|
||||
val l = insert(message)
|
||||
Log.e("jingo", "insertOrUpdate $l ")
|
||||
} else {
|
||||
message.uuid = uuid
|
||||
update(message)
|
||||
}
|
||||
Log.e("jingo", "insertOrUpdate end")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ class HomeAdapter(fragment: Fragment) :
|
||||
|
||||
class DiffCallback : DiffUtil.ItemCallback<GreetingMessage>() {
|
||||
override fun areItemsTheSame(oldItem: GreetingMessage, newItem: GreetingMessage): Boolean {
|
||||
return oldItem.uuid == newItem.uuid
|
||||
return oldItem.uuid == newItem.uuid && oldItem.status == newItem.status
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(
|
||||
|
@ -12,6 +12,7 @@ import androidx.lifecycle.lifecycleScope
|
||||
import androidx.paging.LoadState
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.easytools.tools.ThreadPoolUtils.runOnUiThread
|
||||
import com.navinfo.volvo.R
|
||||
import com.navinfo.volvo.databinding.FragmentHomeBinding
|
||||
import com.navinfo.volvo.databinding.HomeAdapterNotingBinding
|
||||
@ -21,6 +22,7 @@ import com.navinfo.volvo.ui.fragments.BaseFragment
|
||||
import com.yanzhenjie.recyclerview.*
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.IOException
|
||||
|
||||
@AndroidEntryPoint
|
||||
@ -55,19 +57,19 @@ class HomeFragment : BaseFragment(), OnItemClickListener, OnItemMenuClickListene
|
||||
var mSwipeMenuCreator = SwipeMenuCreator { _, rightMenu, _ ->
|
||||
//添加菜单自动添加至尾部
|
||||
var deleteItem = SwipeMenuItem(context)
|
||||
deleteItem.height = DisplayUtil.dip2px(context!!, 60f)
|
||||
deleteItem.width = DisplayUtil.dip2px(context!!, 80f)
|
||||
deleteItem.background = context!!.getDrawable(R.color.red)
|
||||
deleteItem.text = context!!.getString(R.string.delete)
|
||||
deleteItem.height = DisplayUtil.dip2px(requireContext(), 60f)
|
||||
deleteItem.width = DisplayUtil.dip2px(requireContext(), 80f)
|
||||
deleteItem.background = requireContext().getDrawable(R.color.red)
|
||||
deleteItem.text = requireContext().getString(R.string.delete)
|
||||
rightMenu.addMenuItem(deleteItem)
|
||||
|
||||
//分享
|
||||
var shareItem = SwipeMenuItem(context)
|
||||
shareItem.height = DisplayUtil.dip2px(context!!, 60f)
|
||||
shareItem.width = DisplayUtil.dip2px(context!!, 80f)
|
||||
shareItem.background = context!!.getDrawable(R.color.gray)
|
||||
shareItem.text = context!!.getString(R.string.share)
|
||||
shareItem.setTextColor(R.color.white)
|
||||
shareItem.height = DisplayUtil.dip2px(requireContext(), 60f)
|
||||
shareItem.width = DisplayUtil.dip2px(requireContext(), 80f)
|
||||
shareItem.background = requireContext().getDrawable(R.color.gray)
|
||||
shareItem.text = requireContext().getString(R.string.share)
|
||||
shareItem.setTextColor(requireContext().getColor(R.color.white))
|
||||
rightMenu.addMenuItem(shareItem)
|
||||
}
|
||||
//侧滑按钮
|
||||
@ -123,11 +125,14 @@ class HomeFragment : BaseFragment(), OnItemClickListener, OnItemMenuClickListene
|
||||
messageAdapter.addLoadStateListener {
|
||||
when (it.refresh) {
|
||||
is LoadState.NotLoading -> {
|
||||
binding.homeRecyclerview.addHeaderView(headBinding!!.root)
|
||||
if (messageAdapter.itemCount == 0)
|
||||
binding.homeRecyclerview.addHeaderView(headBinding!!.root)
|
||||
else{
|
||||
binding.homeRecyclerview.removeHeaderView(headBinding!!.root)
|
||||
}
|
||||
Log.d("jingo", "is NotLoading")
|
||||
}
|
||||
is LoadState.Loading -> {
|
||||
binding.homeRecyclerview.removeHeaderView(headBinding!!.root)
|
||||
Log.d("jingo", "is Loading")
|
||||
}
|
||||
is LoadState.Error -> {
|
||||
|
@ -7,7 +7,8 @@ import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.*
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemSelectedListener
|
||||
@ -18,17 +19,9 @@ import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.easytools.tools.DateUtils
|
||||
import com.easytools.tools.DisplayUtils
|
||||
import com.easytools.tools.FileIOUtils
|
||||
import com.easytools.tools.ResourceUtils
|
||||
import com.easytools.tools.ThreadPoolUtils.runOnUiThread
|
||||
import com.easytools.tools.ToastUtils
|
||||
import com.easytools.tools.*
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.github.file_picker.FileType
|
||||
import com.github.file_picker.ListDirection
|
||||
@ -58,7 +51,6 @@ import com.nhaarman.supertooltips.ToolTip
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import indi.liyi.viewer.Utils
|
||||
import indi.liyi.viewer.ViewData
|
||||
import kotlinx.coroutines.launch
|
||||
import top.zibin.luban.Luban
|
||||
import top.zibin.luban.OnCompressListener
|
||||
import java.io.File
|
||||
@ -196,8 +188,11 @@ class ObtainMessageFragment : Fragment() {
|
||||
}
|
||||
val sendToArray = mutableListOf<VolvoModel>(VolvoModel("XC60", "智雅", "LYVXFEFEXNL754427"))
|
||||
binding.edtSendTo.adapter = ArrayAdapter<String>(requireContext(),
|
||||
android.R.layout.simple_dropdown_item_1line, android.R.id.text1, sendToArray.stream().map { it -> "${it.version} ${it.model} ${it.num}" }.toList())
|
||||
binding.edtSendTo.onItemSelectedListener = object: OnItemSelectedListener {
|
||||
android.R.layout.simple_dropdown_item_1line,
|
||||
android.R.id.text1,
|
||||
sendToArray.stream().map { it -> "${it.version} ${it.model} ${it.num}" }.toList()
|
||||
)
|
||||
binding.edtSendTo.onItemSelectedListener = object : OnItemSelectedListener {
|
||||
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
|
||||
obtainMessageViewModel.getMessageLiveData().value?.toWho = sendToArray[p2].num
|
||||
}
|
||||
@ -287,13 +282,23 @@ class ObtainMessageFragment : Fragment() {
|
||||
// Do something here with selected files
|
||||
val audioFile = files.get(0).file
|
||||
if (!audioFile.parentFile.parentFile.absolutePath.equals(SystemConstant.SoundFolder)) {
|
||||
val copyResult = FileIOUtils.writeFileFromIS(File(SystemConstant.SoundFolder, audioFile.name), FileInputStream(audioFile))
|
||||
XLog.e("拷贝结果:"+copyResult)
|
||||
val copyResult = FileIOUtils.writeFileFromIS(
|
||||
File(
|
||||
SystemConstant.SoundFolder,
|
||||
audioFile.name
|
||||
), FileInputStream(audioFile)
|
||||
)
|
||||
XLog.e("拷贝结果:" + copyResult)
|
||||
if (!copyResult) {
|
||||
ToastUtils.showToast("无法访问该文件,请重新选择其他文件")
|
||||
return
|
||||
}
|
||||
obtainMessageViewModel.updateMessageAudio(File(SystemConstant.SoundFolder, audioFile.name).absolutePath)
|
||||
obtainMessageViewModel.updateMessageAudio(
|
||||
File(
|
||||
SystemConstant.SoundFolder,
|
||||
audioFile.name
|
||||
).absolutePath
|
||||
)
|
||||
} else {
|
||||
obtainMessageViewModel.updateMessageAudio(audioFile.absolutePath)
|
||||
}
|
||||
@ -306,7 +311,7 @@ class ObtainMessageFragment : Fragment() {
|
||||
ToastUtils.showToast("只能选择.m4a文件")
|
||||
return
|
||||
}
|
||||
if (media.file.length()>2*1000*1000) {
|
||||
if (media.file.length() > 2 * 1000 * 1000) {
|
||||
ToastUtils.showToast("文件不能超过2M!")
|
||||
return
|
||||
}
|
||||
@ -349,12 +354,13 @@ class ObtainMessageFragment : Fragment() {
|
||||
false
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (System.currentTimeMillis() - startRecordTime<2000) {
|
||||
if (System.currentTimeMillis() - startRecordTime < 2000) {
|
||||
ToastUtils.showToast("录音时间太短!")
|
||||
recorderLifecycleObserver.stopAndReleaseRecorder()
|
||||
return
|
||||
}
|
||||
val recorderAudioPath = recorderLifecycleObserver.stopAndReleaseRecorder()
|
||||
val recorderAudioPath =
|
||||
recorderLifecycleObserver.stopAndReleaseRecorder()
|
||||
if (File(recorderAudioPath).exists()) {
|
||||
obtainMessageViewModel.updateMessageAudio(recorderAudioPath)
|
||||
}
|
||||
@ -408,25 +414,29 @@ class ObtainMessageFragment : Fragment() {
|
||||
}
|
||||
// 如果当前文件不在camera缓存文件夹下,则移动该文件
|
||||
if (!file!!.parentFile.absolutePath.equals(SystemConstant.CameraFolder)) {
|
||||
val copyResult = FileIOUtils.writeFileFromIS(
|
||||
File(
|
||||
SystemConstant.CameraFolder,
|
||||
fileName
|
||||
), FileInputStream(file)
|
||||
)
|
||||
XLog.e("拷贝结果:" + copyResult)
|
||||
// 跳转回原Fragment,展示拍摄的照片
|
||||
ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java)
|
||||
.updateMessagePic(
|
||||
try {
|
||||
val copyResult = FileIOUtils.writeFileFromIS(
|
||||
File(
|
||||
SystemConstant.CameraFolder,
|
||||
fileName
|
||||
).absolutePath
|
||||
), FileInputStream(file)
|
||||
)
|
||||
XLog.e("拷贝结果:$copyResult")
|
||||
// 跳转回原Fragment,展示拍摄的照片
|
||||
obtainMessageViewModel
|
||||
.updateMessagePic(
|
||||
File(
|
||||
SystemConstant.CameraFolder,
|
||||
fileName
|
||||
).absolutePath
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
XLog.e("崩溃:${e.message}")
|
||||
}
|
||||
|
||||
} else {
|
||||
// 跳转回原Fragment,展示拍摄的照片
|
||||
ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java)
|
||||
.updateMessagePic(file!!.absolutePath)
|
||||
obtainMessageViewModel.updateMessagePic(file!!.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
@ -612,7 +622,7 @@ class ObtainMessageFragment : Fragment() {
|
||||
val sendDate = DateUtils.str2Date(messageData?.sendDate, dateSendFormat)
|
||||
val cal = Calendar.getInstance()
|
||||
cal.time = Date()
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE)+1)
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + 1)
|
||||
if (sendDate.time < cal.time.time) { // 发送时间设置小于当前时间1分钟后,Toast提示用户并自动设置发送时间
|
||||
messageData?.sendDate = DateUtils.date2Str(cal.time, dateSendFormat)
|
||||
ToastUtils.showToast("自动调整发送时间为1分钟后发送")
|
||||
@ -692,6 +702,7 @@ class ObtainMessageFragment : Fragment() {
|
||||
})
|
||||
.show()
|
||||
}
|
||||
|
||||
fun onRecorderDenied() {
|
||||
ToastUtils.showToast("当前操作需要您授权录音权限!")
|
||||
}
|
||||
|
@ -27,13 +27,13 @@ import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class ObtainMessageViewModel @Inject constructor(
|
||||
private val pre: PreferencesRepository
|
||||
private val pre: PreferencesRepository,
|
||||
) : ViewModel() {
|
||||
private val msgLiveData: MutableLiveData<GreetingMessage> by lazy {
|
||||
MutableLiveData<GreetingMessage>()
|
||||
}
|
||||
|
||||
lateinit var username: String
|
||||
var username: String = ""
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
|
@ -1,12 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
|
||||
<import type="android.view.View" />
|
||||
|
||||
<import type="com.navinfo.volvo.Constant" />
|
||||
|
||||
<variable
|
||||
name="greetingMessage"
|
||||
type="com.navinfo.volvo.database.entity.GreetingMessage" />
|
||||
@ -24,10 +26,10 @@
|
||||
android:layout_marginLeft="8dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:roundPercent="0.4"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:roundPercent="0.4" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/message_badge"
|
||||
@ -36,6 +38,7 @@
|
||||
android:background="@drawable/shape_circular"
|
||||
android:gravity="center"
|
||||
android:textColor="#000000"
|
||||
android:visibility="@{Constant.message_status_late.equals(greetingMessage.status)?View.VISIBLE:View.INVISIBLE}"
|
||||
app:layout_constraintCircle="@id/message_head_icon"
|
||||
app:layout_constraintCircleAngle="45"
|
||||
app:layout_constraintCircleRadius="40dp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user