1. 基于 滑动图片浏览 添加
滑动图片浏览https://blog.csdn.net/u011193452/article/details/127049762
2. 添加资源文件,矢量图片
2.1 下载图片默认 ic_baseline_file_download_white.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
</vector>
2.2 下砸图片按下 ic_baseline_file_download_gray.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#CCCFCF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
</vector>
2.3 状态资源 save_button_image.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_baseline_file_download_gray" android:state_pressed="true" />
<item android:drawable="@drawable/ic_baseline_file_download_white" />
</selector>
3. 布局文件添加 fragment_pager_photo.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:drawable/screen_background_dark"
tools:context=".PagerPhotoFragment">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toBottomOf="@+id/photoTag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/photoTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom|center_horizontal"
android:text="@string/hello_blank_fragment"
android:textColor="@color/white"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.95" />
<ImageView
android:id="@+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginEnd="16dp"
android:clickable="true"
android:src="@drawable/save_button_image"
app:layout_constraintBottom_toBottomOf="@+id/photoTag"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/photoTag" />
</androidx.constraintlayout.widget.ConstraintLayout>
4. 调用使用 PagerPhotoFragment.kt
const val REQUEST_WRITE_EXTERNAL_STORAGE = 1
class PagerPhotoFragment : Fragment() {
private lateinit var binding: FragmentPagerPhotoBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
binding = FragmentPagerPhotoBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val photoList = arguments?.getParcelableArrayList<PhotoItem>("PHOTO_LIST")
PagerPhotoListAdapter().apply {
binding.viewPager2.adapter = this
submitList(photoList)
}
binding.viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
binding.photoTag.text = getString(R.string.photo_tag, position + 1, photoList?.size)
}
})
binding.viewPager2.setCurrentItem(arguments?.getInt("PHOTO_POSITION") ?: 0, false)
binding.saveButton.setOnClickListener {
if (Build.VERSION.SDK_INT < Q && ContextCompat.checkSelfPermission(
requireContext(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
requestPermissions(
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
REQUEST_WRITE_EXTERNAL_STORAGE
)
} else {
viewLifecycleOwner.lifecycleScope.launch {
savePhoto()
}
}
}
}
@Deprecated("Deprecated in Java")
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<out String>, grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
REQUEST_WRITE_EXTERNAL_STORAGE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
viewLifecycleOwner.lifecycleScope.launch {
savePhoto()
}
} else {
Toast.makeText(requireContext(), "存储失败", Toast.LENGTH_SHORT).show()
}
}
}
}
//保存图片 suspend 允许挂起
private suspend fun savePhoto() {
//开启子线程 范围
withContext(Dispatchers.IO) {
val holder =
(binding.viewPager2[0] as RecyclerView).findViewHolderForAdapterPosition(binding.viewPager2.currentItem) as PagerPhotoViewHolder
val bitmap = holder.view.pagerPhoto.drawable.toBitmap()
val saveUrl = requireContext().contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ContentValues()
) ?: kotlin.run {
MainScope().launch {
Toast.makeText(requireContext(), "存储失败", Toast.LENGTH_SHORT).show()
}
return@withContext
}
requireContext().contentResolver.openOutputStream(saveUrl).use {
if (bitmap.compress(Bitmap.CompressFormat.JPEG, 90, it)) {
MainScope().launch {
Toast.makeText(requireContext(), "存储成功", Toast.LENGTH_SHORT).show()
}
} else {
MainScope().launch {
Toast.makeText(requireContext(), "存储失败", Toast.LENGTH_SHORT).show()
}
}
}
}
}
}
5. 效果图