diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_dir_list_rv.xml b/app/src/main/res/layout/item_dir_list_rv.xml
new file mode 100644
index 0000000..f7b7597
--- /dev/null
+++ b/app/src/main/res/layout/item_dir_list_rv.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_dir_list_rv.xml b/app/src/main/res/layout/item_dir_list_rv.xml
new file mode 100644
index 0000000..f7b7597
--- /dev/null
+++ b/app/src/main/res/layout/item_dir_list_rv.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_image_list_gv.xml b/app/src/main/res/layout/item_image_list_gv.xml
new file mode 100644
index 0000000..32fb2bd
--- /dev/null
+++ b/app/src/main/res/layout/item_image_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_dir_list_rv.xml b/app/src/main/res/layout/item_dir_list_rv.xml
new file mode 100644
index 0000000..f7b7597
--- /dev/null
+++ b/app/src/main/res/layout/item_dir_list_rv.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_image_list_gv.xml b/app/src/main/res/layout/item_image_list_gv.xml
new file mode 100644
index 0000000..32fb2bd
--- /dev/null
+++ b/app/src/main/res/layout/item_image_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_video_list_gv.xml b/app/src/main/res/layout/item_video_list_gv.xml
new file mode 100644
index 0000000..e879ef5
--- /dev/null
+++ b/app/src/main/res/layout/item_video_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_dir_list_rv.xml b/app/src/main/res/layout/item_dir_list_rv.xml
new file mode 100644
index 0000000..f7b7597
--- /dev/null
+++ b/app/src/main/res/layout/item_dir_list_rv.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_image_list_gv.xml b/app/src/main/res/layout/item_image_list_gv.xml
new file mode 100644
index 0000000..32fb2bd
--- /dev/null
+++ b/app/src/main/res/layout/item_image_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_video_list_gv.xml b/app/src/main/res/layout/item_video_list_gv.xml
new file mode 100644
index 0000000..e879ef5
--- /dev/null
+++ b/app/src/main/res/layout/item_video_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index e0708ab..184d22d 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -32,6 +32,9 @@
75dp
80dp
100dp
+ 110dp
+ 115dp
+ 120dp
125dp
150dp
180dp
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_dir_list_rv.xml b/app/src/main/res/layout/item_dir_list_rv.xml
new file mode 100644
index 0000000..f7b7597
--- /dev/null
+++ b/app/src/main/res/layout/item_dir_list_rv.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_image_list_gv.xml b/app/src/main/res/layout/item_image_list_gv.xml
new file mode 100644
index 0000000..32fb2bd
--- /dev/null
+++ b/app/src/main/res/layout/item_image_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_video_list_gv.xml b/app/src/main/res/layout/item_video_list_gv.xml
new file mode 100644
index 0000000..e879ef5
--- /dev/null
+++ b/app/src/main/res/layout/item_video_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index e0708ab..184d22d 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -32,6 +32,9 @@
75dp
80dp
100dp
+ 110dp
+ 115dp
+ 120dp
125dp
150dp
180dp
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..b6317cd
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3336534..b4fb060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -33,5 +33,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
new file mode 100644
index 0000000..28e22c9
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaDirAdapter.kt
@@ -0,0 +1,75 @@
+package com.casic.endoscope.adapter
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.os.Environment
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.casic.endoscope.view.BigImageActivity
+import com.pengxh.kt.lite.adapter.ViewHolder
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import java.io.File
+
+abstract class MediaDirAdapter(
+ private val context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val kTag = "MediaDirAdapter"
+ private var fileBeans = ArrayList()
+ private lateinit var fileAdapter: MediaFileAdapter
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(context).inflate(R.layout.item_dir_list_rv, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, @SuppressLint("RecyclerView") position: Int) {
+ val date = dataRows[position].name
+ holder.setText(R.id.dateView, date)
+
+ //根据不同的日期显示不同的改日期下的九宫格形式子文件
+ val videoDir = File(context.getExternalFilesDir(Environment.DIRECTORY_MOVIES), date)
+ videoDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val imageDir = File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), date)
+ imageDir.listFiles()?.forEach {
+ fileBeans.add(it)
+ }
+
+ val realPaths = ArrayList()
+ fileBeans.forEach {
+ val absolutePath = it.absolutePath
+ if (!absolutePath.endsWith(".mp4")) {
+ realPaths.add(absolutePath)
+ }
+ }
+
+ fileAdapter = object : MediaFileAdapter(context, fileBeans) {
+ override fun bindVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ bindChildVideoRes(child, childPos, item)
+ }
+
+ override fun bindImageRes(child: ViewHolder, item: File) {
+ child.setImageResource(R.id.imageView, item.absolutePath)
+ }
+ }
+ val recyclerView = holder.getView(R.id.recyclerView)
+ recyclerView.adapter = fileAdapter
+ fileAdapter.setOnItemClickedListener(object : MediaFileAdapter.OnItemClickedListener {
+ override fun onItemClicked(item: File) {
+ if (!item.name.endsWith(".mp4")) {
+ context.navigatePageTo(position, realPaths)
+ }
+ }
+ })
+ }
+
+ abstract fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File)
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
new file mode 100644
index 0000000..e447913
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/adapter/MediaFileAdapter.kt
@@ -0,0 +1,62 @@
+package com.casic.endoscope.adapter
+
+import android.content.Context
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.casic.endoscope.R
+import com.pengxh.kt.lite.adapter.ViewHolder
+import java.io.File
+
+abstract class MediaFileAdapter(
+ context: Context, private val dataRows: MutableList
+) : RecyclerView.Adapter() {
+
+ private val inflater: LayoutInflater = LayoutInflater.from(context)
+ private val TYPE_VIDEO = 0
+ private val TYPE_IMAGE = 1
+
+ override fun getItemCount(): Int = dataRows.size
+
+ override fun getItemViewType(position: Int): Int {
+ return if (dataRows[position].name.endsWith(".mp4")) {
+ TYPE_VIDEO
+ } else {
+ TYPE_IMAGE
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return if (viewType == TYPE_VIDEO) {
+ ViewHolder(inflater.inflate(R.layout.item_video_list_gv, parent, false))
+ } else {
+ ViewHolder(inflater.inflate(R.layout.item_image_list_gv, parent, false))
+ }
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val file = dataRows[position]
+ if (holder.itemViewType == TYPE_VIDEO) {
+ bindVideoRes(holder, position, dataRows[position])
+ } else {
+ bindImageRes(holder, dataRows[position])
+ }
+
+ holder.itemView.setOnClickListener {
+ itemClickedListener?.onItemClicked(file)
+ }
+ }
+
+ abstract fun bindVideoRes(child: ViewHolder, childPos: Int, item: File)
+ abstract fun bindImageRes(child: ViewHolder, item: File)
+
+ private var itemClickedListener: OnItemClickedListener? = null
+
+ interface OnItemClickedListener {
+ fun onItemClicked(item: File)
+ }
+
+ fun setOnItemClickedListener(listener: OnItemClickedListener) {
+ itemClickedListener = listener
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/extensions/Context.kt b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
index 0afcb27..a301aab 100644
--- a/app/src/main/java/com/casic/endoscope/extensions/Context.kt
+++ b/app/src/main/java/com/casic/endoscope/extensions/Context.kt
@@ -2,13 +2,22 @@
import android.content.Context
import android.os.Environment
+import com.pengxh.kt.lite.extensions.timestampToDate
import java.io.File
//扩展函数
fun Context.createVideoFileDir(): File {
- val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), System.currentTimeMillis().timestampToDate())
if (!videoDir.exists()) {
videoDir.mkdir()
}
return videoDir
+}
+
+fun Context.createImageFileDir(): File {
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), System.currentTimeMillis().timestampToDate())
+ if (!imageDir.exists()) {
+ imageDir.mkdir()
+ }
+ return imageDir
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
index c0020ec..8c4b495 100644
--- a/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/AlbumActivity.kt
@@ -1,32 +1,127 @@
package com.casic.endoscope.view
+import android.annotation.SuppressLint
+import android.content.pm.ActivityInfo
import android.os.Bundle
-import android.util.Log
+import android.os.Environment
+import android.view.View
+import android.widget.ImageView
+import androidx.activity.OnBackPressedCallback
+import androidx.lifecycle.lifecycleScope
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.adapter.MediaDirAdapter
import com.casic.endoscope.databinding.ActivityAlbumBinding
-import com.casic.endoscope.extensions.createVideoFileDir
import com.gyf.immersionbar.ImmersionBar
+import com.pengxh.kt.lite.adapter.ViewHolder
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.dp2px
import com.pengxh.kt.lite.extensions.getStatusBarHeight
+import com.shuyu.gsyvideoplayer.GSYVideoManager
+import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import java.io.File
class AlbumActivity : KotlinBaseActivity() {
private val kTag = "AlbumActivity"
+ private val context = this@AlbumActivity
+ //子文件夹集合
+ private var dirBeans = ArrayList()
+ private lateinit var directoryAdapter: MediaDirAdapter
+
+ @SuppressLint("NotifyDataSetChanged")
override fun initEvent() {
+ binding.ascButton.setOnClickListener {
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+ binding.decButton.setOnClickListener {
+ //升序
+ dirBeans.sortBy { dir -> dir.name }
+ directoryAdapter.notifyDataSetChanged()
+ }
+
+ //替换onBackPressed
+ onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
+ override fun handleOnBackPressed() {
+ GSYVideoManager.backFromWindowFull(context)
+ //解决退出全屏后会被强制竖屏的问题
+ requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
+ }
+ })
}
override fun initOnCreate(savedInstanceState: Bundle?) {
- val videoDir = createVideoFileDir()
- videoDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val temp = ArrayList()
+ val videoDir = File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "")
+ videoDir.list()?.forEach {
+ temp.add(it)
}
- val imageDir = createImageFileDir()
- imageDir.listFiles()?.forEach {
- Log.d(kTag, "initOnCreate => ${it.name}")
+ val imageDir = File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "")
+ imageDir.list()?.forEach {
+ temp.add(it)
}
+
+ //去重
+ val directoryNameSet = HashSet(temp)
+
+ //全部转为File类型,方便是用自带的排序函数
+ directoryNameSet.forEach {
+ dirBeans.add(File(it))
+ }
+
+ //按时间排序,降序
+ dirBeans.sortByDescending { dir -> dir.name }
+
+ //绑定数据
+ directoryAdapter = object : MediaDirAdapter(this, dirBeans) {
+ override fun bindChildVideoRes(child: ViewHolder, childPos: Int, item: File) {
+ val videoPlayer = child.getView(R.id.videoPlayer)
+ videoPlayer.titleTextView.visibility = View.GONE
+ videoPlayer.backButton.visibility = View.GONE
+ lifecycleScope.launch(Dispatchers.Main) {
+ try {
+ val drawable = withContext(Dispatchers.IO) {
+ Glide.with(context)
+ .load(item)
+ .submit()
+ .get()
+ }
+ val coverImg = ImageView(context)
+ coverImg.setImageDrawable(drawable)
+ videoPlayer.thumbImageView = coverImg
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+ videoPlayer.setUp(item.absolutePath, true, "")
+ videoPlayer.fullscreenButton.setOnClickListener {
+ videoPlayer.startWindowFullscreen(context, false, true)
+ }
+ //防止错位设置
+ videoPlayer.playTag = System.currentTimeMillis().toString()
+ videoPlayer.playPosition = childPos
+ //是否根据视频尺寸,自动选择竖屏全屏或者横屏全屏
+ videoPlayer.isAutoFullWithSize = true
+ //音频焦点冲突时是否释放
+ videoPlayer.isReleaseWhenLossAudio = false
+ //全屏动画
+ videoPlayer.isShowFullAnimation = true
+ }
+ }
+ val offset = 10.dp2px(this)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(offset, offset, offset, offset)
+ )
+ binding.recyclerView.adapter = directoryAdapter
}
override fun initViewBinding(): ActivityAlbumBinding {
@@ -44,4 +139,19 @@
binding.rootView.setPadding(0, statusBarHeight, 0, 0)
binding.rootView.requestLayout()
}
+
+ override fun onPause() {
+ super.onPause()
+ GSYVideoManager.onPause()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ GSYVideoManager.onResume()
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ GSYVideoManager.releaseAllVideos()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
new file mode 100644
index 0000000..c0aa2b3
--- /dev/null
+++ b/app/src/main/java/com/casic/endoscope/view/BigImageActivity.kt
@@ -0,0 +1,90 @@
+package com.casic.endoscope.view
+
+import android.content.Context
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.viewpager.widget.PagerAdapter
+import androidx.viewpager.widget.ViewPager
+import com.bumptech.glide.Glide
+import com.casic.endoscope.R
+import com.casic.endoscope.databinding.ActivityBigImageBinding
+import com.casic.endoscope.extensions.initImmersionBar
+import com.luck.picture.lib.photoview.PhotoView
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.utils.Constant
+
+class BigImageActivity : KotlinBaseActivity() {
+
+ override fun initViewBinding(): ActivityBigImageBinding {
+ return ActivityBigImageBinding.inflate(layoutInflater)
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.black)
+ binding.leftBackView.setOnClickListener { finish() }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ val index = intent.getIntExtra(Constant.BIG_IMAGE_INTENT_INDEX_KEY, 0)
+ val urls = intent.getStringArrayListExtra(Constant.BIG_IMAGE_INTENT_DATA_KEY)
+ if (urls == null || urls.size == 0) {
+ return
+ }
+ val imageSize = urls.size
+ binding.pageNumberView.text = String.format("(" + (index + 1) + "/" + imageSize + ")")
+ binding.imagePagerView.adapter = BigImageAdapter(this, urls)
+ binding.imagePagerView.currentItem = index
+ binding.imagePagerView.offscreenPageLimit = imageSize
+ binding.imagePagerView.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+ override fun onPageScrolled(
+ position: Int, positionOffset: Float, positionOffsetPixels: Int
+ ) {
+ }
+
+ override fun onPageSelected(position: Int) {
+ binding.pageNumberView.text =
+ String.format("(" + (position + 1) + "/" + imageSize + ")")
+ }
+
+ override fun onPageScrollStateChanged(state: Int) {}
+ })
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun initEvent() {
+
+ }
+
+ inner class BigImageAdapter(
+ private val context: Context, private val data: ArrayList
+ ) : PagerAdapter() {
+
+ override fun getCount(): Int = data.size
+
+ override fun isViewFromObject(view: View, any: Any): Boolean {
+ return view == any
+ }
+
+ override fun instantiateItem(container: ViewGroup, position: Int): Any {
+ val view =
+ LayoutInflater.from(context).inflate(R.layout.item_big_picture, container, false)
+ val photoView: PhotoView = view.findViewById(R.id.photoView)
+ Glide.with(context).load(data[position]).into(photoView)
+ photoView.scaleType = ImageView.ScaleType.CENTER_INSIDE
+ container.addView(view)
+ //点击大图取消预览
+ photoView.setOnClickListener { finish() }
+ return view
+ }
+
+ override fun destroyItem(container: ViewGroup, position: Int, any: Any) {
+ container.removeView(any as View)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
index 8c1a5dd..d05c4c5 100644
--- a/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
+++ b/app/src/main/java/com/casic/endoscope/view/MainActivity.kt
@@ -14,6 +14,7 @@
import com.casic.endoscope.adapter.CameraPointAdapter
import com.casic.endoscope.bean.CameraPointBean
import com.casic.endoscope.databinding.ActivityMainBinding
+import com.casic.endoscope.extensions.createImageFileDir
import com.casic.endoscope.extensions.createVideoFileDir
import com.casic.endoscope.extensions.getChannel
import com.casic.endoscope.extensions.toTime
@@ -28,7 +29,6 @@
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO
import com.hikvision.netsdk.PTZCommand
import com.pengxh.kt.lite.base.KotlinBaseActivity
-import com.pengxh.kt.lite.extensions.createImageFileDir
import com.pengxh.kt.lite.extensions.getStatusBarHeight
import com.pengxh.kt.lite.extensions.navigatePageTo
import com.pengxh.kt.lite.extensions.show
diff --git a/app/src/main/res/anim/activity_in.xml b/app/src/main/res/anim/activity_in.xml
new file mode 100644
index 0000000..f2696ba
--- /dev/null
+++ b/app/src/main/res/anim/activity_in.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/anim/activity_out.xml b/app/src/main/res/anim/activity_out.xml
new file mode 100644
index 0000000..1e424a5
--- /dev/null
+++ b/app/src/main/res/anim/activity_out.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_album.xml b/app/src/main/res/layout/activity_album.xml
index 38360ea..cf06f5a 100644
--- a/app/src/main/res/layout/activity_album.xml
+++ b/app/src/main/res/layout/activity_album.xml
@@ -51,7 +51,7 @@
android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_big_picture.xml b/app/src/main/res/layout/item_big_picture.xml
new file mode 100644
index 0000000..d90eb44
--- /dev/null
+++ b/app/src/main/res/layout/item_big_picture.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_dir_list_rv.xml b/app/src/main/res/layout/item_dir_list_rv.xml
new file mode 100644
index 0000000..f7b7597
--- /dev/null
+++ b/app/src/main/res/layout/item_dir_list_rv.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_image_list_gv.xml b/app/src/main/res/layout/item_image_list_gv.xml
new file mode 100644
index 0000000..32fb2bd
--- /dev/null
+++ b/app/src/main/res/layout/item_image_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_video_list_gv.xml b/app/src/main/res/layout/item_video_list_gv.xml
new file mode 100644
index 0000000..e879ef5
--- /dev/null
+++ b/app/src/main/res/layout/item_video_list_gv.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index e0708ab..184d22d 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -32,6 +32,9 @@
75dp
80dp
100dp
+ 110dp
+ 115dp
+ 120dp
125dp
150dp
180dp
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..b6317cd
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 315720c..caf4355 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -6,4 +6,8 @@
- @color/purple_500
+
+
\ No newline at end of file