保存图片到相册
https://blog.csdn.net/u011193452/article/details/127065427
- dependencies {
- def paging_version = "3.1.1"
- implementation "androidx.paging:paging-runtime:$paging_version"
- // alternatively - without Android dependencies for tests
- testImplementation "androidx.paging:paging-common:$paging_version"
-
- //retrofit网络请求库
- implementation 'com.squareup.retrofit2:retrofit:2.9.0'
- implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
- }
- class PixabayDataSources(private val context: Context) : PageKeyedDataSource<Int, PhotoItem>() {
- private val queryKey =
- arrayOf("cat", "beauty", "car", "dog", "phone", "computer", "flower", "animal")
- private var keyValue = ""
- //Initial 最初
- override fun loadInitial(
- params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, PhotoItem>
- ) {
- keyValue = queryKey.random()
- val url = "https://pixabay.com/api/?key=30070990-cfc31c9f778ceeef4009d910d&q=${keyValue}&per_page=30&page=1"
- StringRequest(
- Request.Method.GET,
- url,
- {
- val dataList = Gson().fromJson(it, Pixabay::class.java).hits.toList()
- callback.onResult(dataList, null, 2)
- },
- {
- Log.e("MyTag", "loadInitial: $it")
- }
- ).also {
- VolleySingleton.getInstance(context).requestQueue.add(it)
- }
- }
-
- override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, PhotoItem>) {
- val url =
- "https://pixabay.com/api/?key=30070990-cfc31c9f778ceeef4009d910d&q=${keyValue}&per_page=30&page=${params.key}"
- StringRequest(
- Request.Method.GET,
- url,
- {
- val dataList = Gson().fromJson(it, Pixabay::class.java).hits.toList()
- callback.onResult(dataList, params.key + 1)
- },
- {
- Log.e("MyTag", "loadAfter: $it")
- }
- ).also {
- VolleySingleton.getInstance(context).requestQueue.add(it)
- }
- }
-
- override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, PhotoItem>) {
- }
- }
- class PixabayDataSourceFactory(private val context: Context) : DataSource.Factory<Int, PhotoItem>() {
- override fun create(): DataSource<Int, PhotoItem> {
- return PixabayDataSources(context)
- }
- }
- class GalleryViewModel(application: Application) : AndroidViewModel(application) {
- val pagedListLiveData = PixabayDataSourceFactory(application).toLiveData(1)
- fun resetQuery() {
- pagedListLiveData.value?.dataSource?.invalidate()
- }
- }
- class GalleryFragment : Fragment() {
- private lateinit var binding: FragmentGalleryBinding
- private lateinit var galleryAdapter:GalleryAdapter
- private val galleryViewModel by viewModels
() -
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
- ): View? {
- binding = FragmentGalleryBinding.inflate(inflater, container, false)
- return binding.root
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.swipeIndicator -> {
- binding.swipeLayoutGallery.isRefreshing = true
- Handler().postDelayed({
- galleryViewModel.resetQuery()
- }, 300)
-
- }
- }
- return super.onOptionsItemSelected(item)
- }
-
- //加载菜单栏
- override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
- super.onCreateOptionsMenu(menu, inflater)
- inflater.inflate(R.menu.menu, menu)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- setHasOptionsMenu(true)
- galleryAdapter = GalleryAdapter()
-
- binding.recyclerView?.apply {
- adapter = galleryAdapter
- //GridLayouStaager(requireContext(), 2) 对齐 StaggeredGridLayoutManager 交错感
- layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
- }
- viewModel()
- }
-
- private fun viewModel(){
- galleryViewModel.pagedListLiveData.observe(viewLifecycleOwner, Observer {
- galleryAdapter.submitList(it)
- binding.swipeLayoutGallery.isRefreshing = false
- })
- binding.swipeLayoutGallery.setOnRefreshListener {
- galleryViewModel.resetQuery()
- }
- }
- }
- class PixabayResponse {
- val hits: List
= emptyList() - val total = 0
- val totalHits = 0
- }
- //https://pixabay.com/api/?key=30070990-cfc31c9f778ceeef4009d910d&q=beauty&per_page=30&page=1
- const val key = "30070990-cfc31c9f778ceeef4009d910d"
- interface ApiService {
- @GET("?key=$key")
- suspend fun queryPixabay(@Query("q") queryKey : String, @Query("page") page: Int, @Query("per_page") perPage: Int): PixabayResponse
-
- companion object {
- private const val BASE_URL = "https://pixabay.com/api/"
- fun create(): ApiService {
- return Retrofit.Builder()
- .baseUrl(BASE_URL)
- .addConverterFactory(GsonConverterFactory.create())
- .build()
- .create(ApiService::class.java)
- }
- }
- }
- class PixabayPagingSource(private val apiService: ApiService) : PagingSource<Int, PhotoItem>() {
- private val queryKey = arrayOf("cat", "beauty", "car", "dog", "phone", "computer", "flower", "animal")
- private var key = queryKey.random()
-
- override fun getRefreshKey(state: PagingState<Int, PhotoItem>): Int? {
- key = queryKey.random();
- return null
- }
-
- override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PhotoItem> {
- return try {
- val page = params.key ?: 1
- val pageSize = params.loadSize
- val repoResponse = apiService.queryPixabay(key, page, pageSize)
- val repoItems = repoResponse.hits
- val prevKey = if (page > 1) page - 1 else null
- val nextKey = if (repoItems.isNotEmpty()) page + 1 else null
- Log.i("MyTag", "page: $page pageSize: $pageSize prevKey: $prevKey nextKey: $nextKey")
- LoadResult.Page(repoItems, prevKey, nextKey)
- } catch (e: Exception) {
- LoadResult.Error(e)
- }
- }
- }
- //1. Repository中实现网络请求
- object Repository {
- private const val PAGE_SIZE = 10
- private val apiService = ApiService.create()
- fun getPagingData(): Flow
> { - // PagingConfig的一个参数prefetchDistance,用于表示距离底部多少条数据开始预加载,
- // 设置0则表示滑到底部才加载。默认值为分页大小。
- // 若要让用户对加载无感,适当增加预取阈值即可。 比如调整到分页大小的5倍
- return Pager(
- config = PagingConfig(pageSize = PAGE_SIZE, prefetchDistance = 2 * PAGE_SIZE),
- pagingSourceFactory = { PixabayPagingSource(apiService) }).flow
- }
- }
-
- class GalleryPagingViewModel : ViewModel() {
- fun getPagingData(): Flow
> { - return Repository.getPagingData().cachedIn(viewModelScope)
- }
- }
- class GalleryFragment : Fragment() {
- private lateinit var binding: FragmentGalleryBinding
- private lateinit var galleryAdapter:GalleryAdapter
- private val galleryPagingViewModel by viewModels
() -
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
- ): View? {
- binding = FragmentGalleryBinding.inflate(inflater, container, false)
- return binding.root
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
- when (item.itemId) {
- R.id.swipeIndicator -> {
- binding.swipeLayoutGallery.isRefreshing = true
- Handler().postDelayed({
- galleryAdapter.refresh()
- }, 300)
-
- }
- }
- return super.onOptionsItemSelected(item)
- }
-
- //加载菜单栏
- override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
- super.onCreateOptionsMenu(menu, inflater)
- inflater.inflate(R.menu.menu, menu)
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- setHasOptionsMenu(true)
- galleryAdapter = GalleryAdapter()
-
- binding.recyclerView?.apply {
- adapter = galleryAdapter
- //GridLayouStaager(requireContext(), 2) 对齐 StaggeredGridLayoutManager 交错感
- layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
- }
-
- pagingViewModel()
- }
-
- private fun pagingViewModel() {
- lifecycleScope.launch {
- galleryPagingViewModel.getPagingData().collect {
- galleryAdapter.submitData(it)
- binding.swipeLayoutGallery.isRefreshing = false
- }
- }
- binding.swipeLayoutGallery.setOnRefreshListener {
- galleryAdapter.refresh()
- }
- }
- }
