init
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
BIN
app/PhotographyWallpapers.jks
Normal file
BIN
app/PhotographyWallpapersTest.jks
Normal file
72
app/build.gradle.kts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
import java.util.Date
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
plugins {
|
||||||
|
id("com.android.application")
|
||||||
|
id("org.jetbrains.kotlin.android")
|
||||||
|
kotlin("kapt")
|
||||||
|
}
|
||||||
|
|
||||||
|
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
|
||||||
|
android {
|
||||||
|
namespace = "com.wall.photography.wallpaper"
|
||||||
|
compileSdk = 34
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "com.wall.photography"
|
||||||
|
minSdk = 23
|
||||||
|
targetSdk = 34
|
||||||
|
versionCode = 1
|
||||||
|
versionName = "1.0.0"
|
||||||
|
setProperty("archivesBaseName", "Photography Wallpapers_V" + versionName + "(${versionCode})_$timestamp")
|
||||||
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
isMinifyEnabled = true
|
||||||
|
proguardFiles(
|
||||||
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
|
"proguard-rules.pro"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
val paging_version = "3.3.0"
|
||||||
|
implementation("androidx.paging:paging-runtime-ktx:$paging_version")
|
||||||
|
implementation("androidx.core:core-ktx:1.9.0")
|
||||||
|
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||||
|
implementation("com.google.android.material:material:1.12.0")
|
||||||
|
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
|
||||||
|
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.8.3")
|
||||||
|
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3")
|
||||||
|
testImplementation("junit:junit:4.13.2")
|
||||||
|
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
||||||
|
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||||
|
implementation("com.google.code.gson:gson:2.10.1")
|
||||||
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
|
kapt("com.github.bumptech.glide:compiler:4.16.0")
|
||||||
|
|
||||||
|
val room_version = "2.6.1"
|
||||||
|
implementation("androidx.room:room-runtime:$room_version")
|
||||||
|
kapt("androidx.room:room-compiler:$room_version")
|
||||||
|
implementation("androidx.room:room-ktx:$room_version")
|
||||||
|
implementation("androidx.room:room-paging:$room_version")
|
||||||
|
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:4.11.0")
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
38
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-keepclassmembers class com.wall.photography.wallpaper.MyApp {
|
||||||
|
public static final java.lang.String ROOM_NAME;
|
||||||
|
public static final int ROOM_Version;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@androidx.room.Query <methods>;
|
||||||
|
}
|
||||||
|
-keep class com.wall.photography.wallpaper.data.Bean { *; }
|
||||||
|
-keep class com.wall.photography.wallpaper.data.Author { *; }
|
||||||
|
-keep class com.wall.photography.wallpaper.data.Links { *; }
|
||||||
|
-keep class com.wall.photography.wallpaper.data.URLS { *; }
|
||||||
|
|
||||||
|
#-keepclassmembers class com.wall.photography.wallpaper.data { *; }
|
||||||
|
-keep class com.wall.photography.wallpaper.room.MyDataBase { *; }
|
||||||
|
-keep class com.wall.photography.wallpaper.room.BeanDao { *; }
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.wall.photography.wallpaper
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
assertEquals("com.wall.photography.wallpaper", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
50
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".MyApp"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/logo"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/logo"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.PhotographyWallpaper"
|
||||||
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".activivty.AboutActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".activivty.SetWallpaperActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".activivty.ListActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".activivty.MyWelComeActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:theme="@style/Welcome.Theme">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".activivty.MainActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/Base.Theme.PhotographyWallpaper" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
20702
app/src/main/assets/Animals.json
Normal file
20702
app/src/main/assets/Experimental.json
Normal file
20702
app/src/main/assets/Film.json
Normal file
20702
app/src/main/assets/Nature.json
Normal file
20702
app/src/main/assets/Patterns.json
Normal file
20702
app/src/main/assets/Street.json
Normal file
20702
app/src/main/assets/Travel.json
Normal file
20702
app/src/main/assets/Wallpaper.json
Normal file
71
app/src/main/java/com/wall/photography/wallpaper/MyApp.kt
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package com.wall.photography.wallpaper
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.util.Log
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.manager.DealData
|
||||||
|
import com.wall.photography.wallpaper.room.MyDataBase
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class MyApp : Application() {
|
||||||
|
companion object {
|
||||||
|
lateinit var application: Application
|
||||||
|
const val TAG = "-------------tt"
|
||||||
|
const val ROOM_NAME = "Photography_Wallpaper"
|
||||||
|
const val ROOM_Version = 1
|
||||||
|
const val TABLE_NAME = "wall_paper"
|
||||||
|
var data_Wallpaper: List<Bean>? = null
|
||||||
|
var data_animals: List<Bean>? = null
|
||||||
|
var data_experimental: List<Bean>? = null
|
||||||
|
var data_film: List<Bean>? = null
|
||||||
|
var data_nature: List<Bean>? = null
|
||||||
|
var data_streetphotography: List<Bean>? = null
|
||||||
|
var data_texturespatterns: List<Bean>? = null
|
||||||
|
var data_travel: List<Bean>? = null
|
||||||
|
var dataAlready: Boolean = false
|
||||||
|
const val pageSize = 10
|
||||||
|
|
||||||
|
lateinit var strings: Array<String>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
application = this
|
||||||
|
Log.d(TAG, "---------------onCreate")
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
Log.d(TAG, "---------------协程开始" + Thread.currentThread().name)
|
||||||
|
strings = resources.getStringArray(R.array.category_name)
|
||||||
|
val allWallpaper = MyDataBase.getInstance().getBeanDao().getCategoryCovert(strings[7])
|
||||||
|
if (allWallpaper != null) {
|
||||||
|
Log.d(TAG, "---------------协程结束 --" + Thread.currentThread().name)
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
for (i in 0 until 8) {
|
||||||
|
val initData = initData(strings[i] + ".json")
|
||||||
|
val subList = initData.subList(0, 500)
|
||||||
|
for (data in subList) {
|
||||||
|
MyDataBase.getInstance().getBeanDao().insertBean(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
dataAlready = true
|
||||||
|
Log.d(TAG, "---------------协程结束 --" + Thread.currentThread().name)
|
||||||
|
}
|
||||||
|
Log.d(TAG, "---------------onCreate end")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initData(fileName: String): List<Bean> {
|
||||||
|
Log.d(TAG, "-----------协程.......----fileName=$fileName")
|
||||||
|
val fdInput = assets.open(fileName)
|
||||||
|
val jsonStr = DealData.getJsonString(fdInput)
|
||||||
|
val cateName = fileName.substringBefore(".json")
|
||||||
|
val bean = DealData.getBean(this, jsonStr, cateName)
|
||||||
|
return bean
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
63
app/src/main/java/com/wall/photography/wallpaper/Test.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package com.wall.photography.wallpaper;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static Uri saveToGallery(Context context, File photoFile) {
|
||||||
|
String displayName = System.currentTimeMillis()+".jpg";
|
||||||
|
ContentValues contentValues = new ContentValues();
|
||||||
|
|
||||||
|
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, displayName);
|
||||||
|
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
contentValues.put(MediaStore.Images.Media.IS_PENDING, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri collectionUri;
|
||||||
|
ContentResolver contentResolver = context.getContentResolver();
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
collectionUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
|
||||||
|
} else {
|
||||||
|
collectionUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri imageUri = contentResolver.insert(collectionUri, contentValues);
|
||||||
|
if (imageUri == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
FileInputStream inputStream = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
try {
|
||||||
|
int byteLength = 0;
|
||||||
|
byte[] bytes = new byte[4096];
|
||||||
|
outputStream = contentResolver.openOutputStream(imageUri);
|
||||||
|
inputStream = new FileInputStream(photoFile);
|
||||||
|
while ((byteLength = inputStream.read(bytes)) != -1) {
|
||||||
|
outputStream.write(bytes, 0, byteLength);
|
||||||
|
}
|
||||||
|
inputStream.close();
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
contentValues.clear();
|
||||||
|
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0);
|
||||||
|
contentResolver.update(imageUri, contentValues, null, null);
|
||||||
|
}
|
||||||
|
return imageUri;
|
||||||
|
|
||||||
|
} catch (Exception exception) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.wall.photography.wallpaper.activivty
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivityAboutBinding
|
||||||
|
|
||||||
|
|
||||||
|
class AboutActivity : AppCompatActivity() {
|
||||||
|
private lateinit var vb: ActivityAboutBinding
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
vb = ActivityAboutBinding.inflate(layoutInflater)
|
||||||
|
setContentView(vb.root)
|
||||||
|
|
||||||
|
val appVersionName = getAppVersionName()
|
||||||
|
appVersionName?.run {
|
||||||
|
vb.tvVersion.text = String.format(getString(R.string.version), this.versionName)
|
||||||
|
} ?: run {
|
||||||
|
vb.tvVersion.text = String.format(getString(R.string.version), "1.0.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vb.back.setOnClickListener { finish() }
|
||||||
|
vb.layoutRate.setOnClickListener {
|
||||||
|
try {
|
||||||
|
val uri = String.format(getString(R.string.google_link), packageName)
|
||||||
|
startActivity(Intent(Intent.ACTION_VIEW).apply {
|
||||||
|
data = Uri.parse(uri)
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
})
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@AboutActivity,
|
||||||
|
this@AboutActivity.resources.getString(R.string.to_gp_exception),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAppVersionName(): PackageInfo? {
|
||||||
|
return try {
|
||||||
|
packageManager.getPackageInfo(packageName, 0)
|
||||||
|
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
package com.wall.photography.wallpaper.activivty
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.adapter.AdapterHomePaing
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivityListBinding
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivityMainBinding
|
||||||
|
import com.wall.photography.wallpaper.fragment.HomeViewModel
|
||||||
|
import com.wall.photography.wallpaper.manager.MyItemDecoration
|
||||||
|
import com.wall.photography.wallpaper.viewmode.ListActivityViewModel
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class ListActivity : AppCompatActivity() {
|
||||||
|
private lateinit var vb: ActivityListBinding
|
||||||
|
companion object{
|
||||||
|
const val KEY = "category_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var viewModel:ListActivityViewModel
|
||||||
|
private lateinit var adapterHomepaging: AdapterHomePaing
|
||||||
|
private lateinit var name:String
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
vb = ActivityListBinding.inflate(layoutInflater)
|
||||||
|
setContentView(vb.root)
|
||||||
|
viewModel = ViewModelProvider(this)[ListActivityViewModel::class.java]
|
||||||
|
name = intent.getStringExtra(KEY)!!
|
||||||
|
vb.tvName.text = name
|
||||||
|
vb.back.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
adapterHomepaging = AdapterHomePaing(mContext=this@ListActivity){
|
||||||
|
startActivity(Intent(this, SetWallpaperActivity::class.java).apply {
|
||||||
|
putExtra(SetWallpaperActivity.KEY_DATA, it)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
CoroutineScope(Dispatchers.Main).launch{
|
||||||
|
viewModel.getPagingData(name).collectLatest {
|
||||||
|
Log.d(MyApp.TAG,"------------collectLatest ")
|
||||||
|
adapterHomepaging.submitData(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initWallpaper()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initWallpaper() {
|
||||||
|
vb.list.run {
|
||||||
|
layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||||
|
adapter = adapterHomepaging
|
||||||
|
addItemDecoration(MyItemDecoration(this@ListActivity, 8, 8, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package com.wall.photography.wallpaper.activivty
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivityMainBinding
|
||||||
|
import com.wall.photography.wallpaper.fragment.CategoryFragment
|
||||||
|
import com.wall.photography.wallpaper.fragment.HomeFragment
|
||||||
|
import com.wall.photography.wallpaper.fragment.LoveFragment
|
||||||
|
import com.wall.photography.wallpaper.manager.DealData
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
private lateinit var vb: ActivityMainBinding
|
||||||
|
private lateinit var listOf: List<Fragment>
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
Log.d(MyApp.TAG, "------------MainActivity onCreate=$this")
|
||||||
|
vb = ActivityMainBinding.inflate(layoutInflater)
|
||||||
|
setContentView(vb.root)
|
||||||
|
listOf = listOf<Fragment>(
|
||||||
|
HomeFragment.newInstance(),
|
||||||
|
CategoryFragment.newInstance(),
|
||||||
|
LoveFragment.newInstance()
|
||||||
|
)
|
||||||
|
initVp2()
|
||||||
|
|
||||||
|
vb.iconSet.setOnClickListener {
|
||||||
|
startActivity(Intent(this@MainActivity,AboutActivity::class.java).apply {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
vb.bottomNavigation.setOnItemSelectedListener { menu ->
|
||||||
|
when (menu.itemId) {
|
||||||
|
R.id.home -> vb.viewpager2.currentItem = 0
|
||||||
|
R.id.category -> {
|
||||||
|
vb.viewpager2.currentItem = 1
|
||||||
|
val cateFragment = listOf[1] as CategoryFragment
|
||||||
|
cateFragment.refreshCate()
|
||||||
|
}
|
||||||
|
R.id.love -> {
|
||||||
|
vb.viewpager2.currentItem = 2
|
||||||
|
val loveFragment = listOf[2] as LoveFragment
|
||||||
|
loveFragment.refreshLoves()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initVp2() {
|
||||||
|
|
||||||
|
vb.viewpager2.run {
|
||||||
|
adapter = object : FragmentStateAdapter(this@MainActivity) {
|
||||||
|
override fun getItemCount(): Int = listOf.size
|
||||||
|
|
||||||
|
override fun createFragment(position: Int): Fragment = listOf[position]
|
||||||
|
|
||||||
|
}
|
||||||
|
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||||
|
override fun onPageSelected(position: Int) {
|
||||||
|
super.onPageSelected(position)
|
||||||
|
when (position) {
|
||||||
|
0 -> vb.bottomNavigation.selectedItemId = R.id.home
|
||||||
|
1 -> {
|
||||||
|
vb.bottomNavigation.selectedItemId = R.id.category
|
||||||
|
val cateFragment = listOf[1] as CategoryFragment
|
||||||
|
cateFragment.refreshCate()
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
vb.bottomNavigation.selectedItemId = R.id.love
|
||||||
|
val loveFragment = listOf[2] as LoveFragment
|
||||||
|
loveFragment.refreshLoves()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.wall.photography.wallpaper.activivty
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivityMainBinding
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivityWelcomeBinding
|
||||||
|
|
||||||
|
class MyWelComeActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var vb:ActivityWelcomeBinding
|
||||||
|
private lateinit var goTimer:CountDownTimer
|
||||||
|
private val countTime = 2000L
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
vb = ActivityWelcomeBinding.inflate(layoutInflater)
|
||||||
|
setContentView(vb.root)
|
||||||
|
init()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun init(){
|
||||||
|
goTimer = object :CountDownTimer(countTime,500){
|
||||||
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinish() {
|
||||||
|
enterMain()
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goTimer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enterMain(){
|
||||||
|
startActivity(Intent(this@MyWelComeActivity, MainActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package com.wall.photography.wallpaper.activivty
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.wall.photography.wallpaper.databinding.SelectDialogBinding
|
||||||
|
|
||||||
|
|
||||||
|
class SelectDialog(private var clickAction:(clickPos:Int)->Unit) : DialogFragment() {
|
||||||
|
|
||||||
|
private lateinit var vb: SelectDialogBinding
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View {
|
||||||
|
vb = SelectDialogBinding.inflate(layoutInflater)
|
||||||
|
dialog?.run {
|
||||||
|
setCanceledOnTouchOutside(true)
|
||||||
|
window?.run {
|
||||||
|
setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
||||||
|
setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
initCLick()
|
||||||
|
return vb.root
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun initCLick(){
|
||||||
|
vb.home.setOnClickListener {
|
||||||
|
clickAction.invoke(clickType_home)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
vb.lock.setOnClickListener {
|
||||||
|
clickAction.invoke(clickType_lock)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
vb.both.setOnClickListener {
|
||||||
|
clickAction.invoke(clickType_both)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val clickType_home = 0
|
||||||
|
const val clickType_lock = 1
|
||||||
|
const val clickType_both = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,414 @@
|
|||||||
|
package com.wall.photography.wallpaper.activivty
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.WallpaperManager
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.widget.RelativeLayout
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.core.view.marginBottom
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.Test
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.ActivitySetWallpaperBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.DealData
|
||||||
|
import com.wall.photography.wallpaper.manager.Other
|
||||||
|
import com.wall.photography.wallpaper.room.MyDataBase
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
class SetWallpaperActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val KEY_DATA = "key_data"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var code = 1
|
||||||
|
|
||||||
|
private var dialog: SelectDialog? = null
|
||||||
|
|
||||||
|
private lateinit var wallpaperManager: WallpaperManager
|
||||||
|
|
||||||
|
private lateinit var data: Bean
|
||||||
|
private lateinit var vb: ActivitySetWallpaperBinding
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
Log.d(MyApp.TAG, "----------SetWallpaperActivity--onCreate=$this")
|
||||||
|
|
||||||
|
vb = ActivitySetWallpaperBinding.inflate(layoutInflater)
|
||||||
|
setContentView(vb.root)
|
||||||
|
vb.loadingView.isVisible = true
|
||||||
|
initBar()
|
||||||
|
data = intent.getSerializableExtra(KEY_DATA) as Bean
|
||||||
|
wallpaperManager = WallpaperManager.getInstance(this)
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
data = MyDataBase.getInstance().getBeanDao().getCurWallpaper(data.id)
|
||||||
|
vb.imLove.isSelected = data.love
|
||||||
|
data.downloadFilePath?.let {
|
||||||
|
val file = File(it)
|
||||||
|
if (file.exists()) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Log.d(MyApp.TAG, "-------------load file =${it}")
|
||||||
|
Glide.with(MyApp.application)
|
||||||
|
.asDrawable()
|
||||||
|
.load(file)
|
||||||
|
.skipMemoryCache(true)
|
||||||
|
.thumbnail(0.2f)
|
||||||
|
.error(R.drawable.placeholder)
|
||||||
|
.placeholder(R.drawable.placeholder)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.into(vb.preview)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initView()
|
||||||
|
setClick()
|
||||||
|
relayout()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun relayout() {
|
||||||
|
val navigationBarHeight = Other.getNavigationBarHeight(MyApp.application)
|
||||||
|
Log.d(MyApp.TAG, "-------navigationBarHeight=${navigationBarHeight}")
|
||||||
|
|
||||||
|
if (navigationBarHeight != 0) {
|
||||||
|
val newLayoutParams = vb.relayout.layoutParams as ConstraintLayout.LayoutParams
|
||||||
|
vb.relayout.layoutParams = newLayoutParams.apply {
|
||||||
|
bottomMargin = navigationBarHeight+Other.dpToPx(20,MyApp.application)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setClick() {
|
||||||
|
vb.run {
|
||||||
|
back.setOnClickListener(this@SetWallpaperActivity)
|
||||||
|
imDownload.setOnClickListener(this@SetWallpaperActivity)
|
||||||
|
imSetWallpaper.setOnClickListener(this@SetWallpaperActivity)
|
||||||
|
imLove.setOnClickListener(this@SetWallpaperActivity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<out String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
if (requestCode == code) {
|
||||||
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
startSaveIm()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, getString(R.string.grant_permission), Toast.LENGTH_SHORT)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun startSaveIm() {
|
||||||
|
vb.loadingView.isVisible = true
|
||||||
|
data.downloadFilePath?.let { path ->
|
||||||
|
Log.d(MyApp.TAG, "-------------has downloadFilePath =${path}")
|
||||||
|
val file = File(path)
|
||||||
|
if (file.exists()) {
|
||||||
|
val saveToGallery = DealData.saveToGallery(this@SetWallpaperActivity, file)
|
||||||
|
Log.d(MyApp.TAG, "------------file exist")
|
||||||
|
saveResultToast(
|
||||||
|
if (saveToGallery != null) getString(R.string.save_ok) else getString(
|
||||||
|
R.string.save_fail
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Log.d(MyApp.TAG, "-------------file no exist")
|
||||||
|
downloadIm {
|
||||||
|
var msg: String = if (it == null) {
|
||||||
|
getString(R.string.save_exception)
|
||||||
|
} else {
|
||||||
|
val newFile = File(it)
|
||||||
|
val saveToGallery =
|
||||||
|
DealData.saveToGallery(this@SetWallpaperActivity, newFile)
|
||||||
|
if (saveToGallery != null) getString(R.string.save_ok) else getString(
|
||||||
|
R.string.save_fail
|
||||||
|
)
|
||||||
|
}
|
||||||
|
saveResultToast(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
downloadIm {
|
||||||
|
var msg: String = if (it == null) {
|
||||||
|
getString(R.string.save_exception)
|
||||||
|
} else {
|
||||||
|
val newFile = File(it)
|
||||||
|
// val saveToGallery = DealData.saveToGallery(this@SetWallpaperActivity, newFile)
|
||||||
|
val saveToGallery = Test.saveToGallery(this@SetWallpaperActivity, newFile)
|
||||||
|
if (saveToGallery != null) getString(R.string.save_ok) else getString(
|
||||||
|
R.string.save_fail
|
||||||
|
)
|
||||||
|
}
|
||||||
|
saveResultToast(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveResultToast(message: String) {
|
||||||
|
runOnUiThread {
|
||||||
|
Toast.makeText(
|
||||||
|
this@SetWallpaperActivity,
|
||||||
|
message,
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
|
||||||
|
vb.loadingView.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadIm(result: (filePath: String?) -> Unit) {
|
||||||
|
val filePath = Other.getInternalFilePath(this)
|
||||||
|
Log.d(MyApp.TAG, "-------------start downloadIm =${filePath}")
|
||||||
|
DealData.downloadFile(data.download, filePath) { isSave, inputStream ->
|
||||||
|
val file = File(filePath)
|
||||||
|
if (!isSave || inputStream == null || !file.exists()) {
|
||||||
|
Log.d(MyApp.TAG, "-------------downloadIm fail")
|
||||||
|
result.invoke(null)
|
||||||
|
return@downloadFile
|
||||||
|
}
|
||||||
|
MyDataBase.getInstance().getBeanDao().updateBean(data.apply {
|
||||||
|
downloadFilePath = filePath
|
||||||
|
})
|
||||||
|
result.invoke(filePath)
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"-------------updateBean=${data.id} ${data.downloadFilePath} thread=${Thread.currentThread().name}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
vb.run {
|
||||||
|
data.run {
|
||||||
|
authorName.text = user.name
|
||||||
|
Log.d(MyApp.TAG, "-------------load reguar initView")
|
||||||
|
loadRegular()
|
||||||
|
Glide.with(MyApp.application)
|
||||||
|
.asDrawable()
|
||||||
|
.load(user.header_medium)
|
||||||
|
.thumbnail(0.2f)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.error(R.drawable.placeholder)
|
||||||
|
.placeholder(R.drawable.placeholder)
|
||||||
|
.listener(object : RequestListener<Drawable>{
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<Drawable>,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
vb.loadingView.isVisible = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: Drawable,
|
||||||
|
model: Any,
|
||||||
|
target: Target<Drawable>?,
|
||||||
|
dataSource: DataSource,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
vb.loadingView.isVisible = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.into(header)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadRegular() {
|
||||||
|
Glide.with(MyApp.application)
|
||||||
|
.asDrawable()
|
||||||
|
.load(data.urls.regular)
|
||||||
|
.thumbnail(0.2f)
|
||||||
|
.error(R.drawable.placeholder)
|
||||||
|
.skipMemoryCache(true)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.placeholder(R.drawable.placeholder)
|
||||||
|
.into(vb.preview)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private fun initBar() {
|
||||||
|
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||||
|
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||||
|
vb.root.systemUiVisibility =
|
||||||
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
Log.d(MyApp.TAG, "-------------onPause")
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
vb.imLove.isSelected.let {
|
||||||
|
MyDataBase.getInstance().getBeanDao().updateBean(data.apply {
|
||||||
|
love = it
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?) {
|
||||||
|
v?.run {
|
||||||
|
vb.run {
|
||||||
|
when (v) {
|
||||||
|
back -> {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
imLove -> {
|
||||||
|
imLove.isSelected = !imLove.isSelected
|
||||||
|
}
|
||||||
|
|
||||||
|
imSetWallpaper -> {
|
||||||
|
if (dialog == null) {
|
||||||
|
dialog = SelectDialog {
|
||||||
|
vb.loadingView.visibility = View.VISIBLE
|
||||||
|
Log.d(MyApp.TAG, "-------------isVisible ${Thread.currentThread().name}")
|
||||||
|
data.downloadFilePath?.let { filePath ->
|
||||||
|
val file = File(filePath)
|
||||||
|
if (file.exists()) {
|
||||||
|
launchSet(it, file)
|
||||||
|
} else {
|
||||||
|
downloadIm { downloadpath ->
|
||||||
|
if (downloadpath == null) {
|
||||||
|
saveResultToast(getString(R.string.download_exception))
|
||||||
|
} else {
|
||||||
|
val file1 = File(downloadpath)
|
||||||
|
launchSet(it, file1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
downloadIm { downloadpath ->
|
||||||
|
if (downloadpath == null) {
|
||||||
|
saveResultToast(getString(R.string.download_exception))
|
||||||
|
} else {
|
||||||
|
val file1 = File(downloadpath)
|
||||||
|
launchSet(it, file1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isFinishing) {
|
||||||
|
dialog?.show(supportFragmentManager, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imDownload -> {
|
||||||
|
if (Other.requestPermission(this@SetWallpaperActivity, code)) {
|
||||||
|
startSaveIm()
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun launchSet(type: Int, file: File) {
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
var msg: String = try {
|
||||||
|
startSetWallpaper(type, file)
|
||||||
|
getString(R.string.set_success)
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
getString(R.string.set_fail)
|
||||||
|
}
|
||||||
|
saveResultToast(msg)
|
||||||
|
Log.d(MyApp.TAG, "------------end SetWallpaper")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startSetWallpaper(type: Int, file: File) {
|
||||||
|
Log.d(MyApp.TAG, "------------start SetWallpaper")
|
||||||
|
|
||||||
|
when (type) {
|
||||||
|
SelectDialog.clickType_home -> {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||||
|
wallpaperManager.setStream(file.inputStream())
|
||||||
|
} else {
|
||||||
|
wallpaperManager.setStream(
|
||||||
|
file.inputStream(),
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
WallpaperManager.FLAG_SYSTEM
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectDialog.clickType_lock -> {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||||
|
wallpaperManager.setStream(file.inputStream())
|
||||||
|
} else {
|
||||||
|
wallpaperManager.setStream(
|
||||||
|
file.inputStream(),
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
WallpaperManager.FLAG_LOCK
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectDialog.clickType_both -> {
|
||||||
|
wallpaperManager.setStream(file.inputStream())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
dialog?.dismiss()
|
||||||
|
Glide.with(MyApp.application).clear(vb.preview)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
package com.wall.photography.wallpaper.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.ItemCategoryBinding
|
||||||
|
import com.wall.photography.wallpaper.databinding.ItemHomeBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.DealData
|
||||||
|
import com.wall.photography.wallpaper.manager.Other
|
||||||
|
|
||||||
|
class AdapterCategory(private var mContext: Context,private var goList:(item:Bean)->Unit) : RecyclerView.Adapter<AdapterCategory.VH>() {
|
||||||
|
private var data: List<Bean> = emptyList()
|
||||||
|
|
||||||
|
inner class VH(var vb: ItemCategoryBinding) : RecyclerView.ViewHolder(vb.root)
|
||||||
|
|
||||||
|
fun updateData(newData: List<Bean>) {
|
||||||
|
val diffCallback = DiffCallback(data, newData)
|
||||||
|
val calculateDiff = DiffUtil.calculateDiff(diffCallback)
|
||||||
|
calculateDiff.dispatchUpdatesTo(this)
|
||||||
|
data = newData
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||||
|
val inflate = ItemCategoryBinding.inflate(LayoutInflater.from(parent.context),parent,false)
|
||||||
|
return VH(inflate)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = data.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||||
|
data[position].run {
|
||||||
|
holder.vb.tvName.text = cateName
|
||||||
|
holder.vb.cardView.setOnClickListener {
|
||||||
|
goList.invoke(this)
|
||||||
|
}
|
||||||
|
Log.d(MyApp.TAG, "--------AdapterCategory-----urls.small=${urls.small}")
|
||||||
|
Glide.with(MyApp.application)
|
||||||
|
.asDrawable()
|
||||||
|
.load(urls.small)
|
||||||
|
.thumbnail(0.2f)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.error(R.drawable.placeholder)
|
||||||
|
.placeholder(R.drawable.placeholder)
|
||||||
|
.listener(object : RequestListener<Drawable> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<Drawable>,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
Log.d(MyApp.TAG, "----------AdapterCategory-onLoadFailed----urls.thumb=${urls.thumb} e=${e?.message}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: Drawable,
|
||||||
|
model: Any,
|
||||||
|
target: Target<Drawable>?,
|
||||||
|
dataSource: DataSource,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.into(holder.vb.wallpaper)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class DiffCallback(var old: List<Bean>, var new: List<Bean>) : DiffUtil.Callback() {
|
||||||
|
override fun getOldListSize(): Int = old.size
|
||||||
|
|
||||||
|
override fun getNewListSize(): Int = new.size
|
||||||
|
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||||
|
val thumb = old[oldItemPosition].urls.thumb
|
||||||
|
val newThumb = new[newItemPosition].urls.thumb
|
||||||
|
return thumb == newThumb
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||||
|
val love = old[oldItemPosition].love
|
||||||
|
val newLove = new[newItemPosition].love
|
||||||
|
return love == newLove
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,135 @@
|
|||||||
|
package com.wall.photography.wallpaper.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.paging.PagingDataAdapter
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.ItemHomeBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.Other
|
||||||
|
|
||||||
|
|
||||||
|
class AdapterHomePaing(
|
||||||
|
private var isLove: Boolean = false,
|
||||||
|
private var mContext: Context,
|
||||||
|
var clickAction: (data: Bean) -> Unit
|
||||||
|
) : PagingDataAdapter<Bean, AdapterHomePaing.VH>(diff) {
|
||||||
|
// private var data: List<Bean> = emptyList()
|
||||||
|
|
||||||
|
inner class VH(var vb: ItemHomeBinding) : RecyclerView.ViewHolder(vb.root)
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||||
|
val inflate = ItemHomeBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
return VH(inflate)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override fun onViewRecycled(holder: VH) {
|
||||||
|
super.onViewRecycled(holder)
|
||||||
|
Glide.with(MyApp.application).clear(holder.vb.wallpaper)
|
||||||
|
Log.d(MyApp.TAG, "----------onViewRecycled")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||||
|
Log.d(MyApp.TAG, "----------onBindViewHolder---- position=${position}")
|
||||||
|
val item = getItem(position)
|
||||||
|
item?.run {
|
||||||
|
var curheight: Int
|
||||||
|
if (!isLove) {
|
||||||
|
if (position <= 1) {
|
||||||
|
curheight = Other.dpToPx(200, mContext)
|
||||||
|
} else if (position <= 3) {
|
||||||
|
curheight = Other.dpToPx(120, mContext)
|
||||||
|
} else if (position % 3 == 0) {
|
||||||
|
curheight = Other.dpToPx(240, mContext)
|
||||||
|
} else {
|
||||||
|
curheight = Other.dpToPx(200, mContext)
|
||||||
|
}
|
||||||
|
holder.vb.wallpaper.run {
|
||||||
|
layoutParams = layoutParams.apply {
|
||||||
|
height = curheight
|
||||||
|
width = RecyclerView.LayoutParams.MATCH_PARENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"----------onLoad----- urls.small=${urls.small}"
|
||||||
|
)
|
||||||
|
Glide.with(MyApp.application)
|
||||||
|
.asDrawable()
|
||||||
|
.load(urls.small)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.thumbnail(0.2f)
|
||||||
|
.error(R.drawable.placeholder)
|
||||||
|
.skipMemoryCache(true)
|
||||||
|
.centerCrop()
|
||||||
|
.placeholder(R.drawable.placeholder)
|
||||||
|
.listener(object : RequestListener<Drawable> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<Drawable>,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"----------onLoadFailed-----urls.thumb=${urls.regular} e=${e?.message}"
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: Drawable,
|
||||||
|
model: Any,
|
||||||
|
target: Target<Drawable>?,
|
||||||
|
dataSource: DataSource,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.into(holder.vb.wallpaper)
|
||||||
|
|
||||||
|
holder.vb.cardView.setOnClickListener {
|
||||||
|
clickAction.invoke(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val diff = object : DiffUtil.ItemCallback<Bean>() {
|
||||||
|
override fun areItemsTheSame(oldItem: Bean, newItem: Bean): Boolean {
|
||||||
|
|
||||||
|
return oldItem.id == newItem.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: Bean, newItem: Bean): Boolean {
|
||||||
|
|
||||||
|
return oldItem.love == newItem.love
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
package com.wall.photography.wallpaper.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.ItemCategoryBinding
|
||||||
|
import com.wall.photography.wallpaper.databinding.ItemHomeBinding
|
||||||
|
import com.wall.photography.wallpaper.databinding.ItemLoveBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.DealData
|
||||||
|
import com.wall.photography.wallpaper.manager.Other
|
||||||
|
|
||||||
|
class AdapterLoves(private var mContext: Context, private var goList:(item:Bean)->Unit) : RecyclerView.Adapter<AdapterLoves.VH>() {
|
||||||
|
private var data: List<Bean> = emptyList()
|
||||||
|
|
||||||
|
inner class VH(var vb: ItemLoveBinding) : RecyclerView.ViewHolder(vb.root)
|
||||||
|
|
||||||
|
fun updateData(newData: List<Bean>) {
|
||||||
|
val diffCallback = DiffCallback(data, newData)
|
||||||
|
val calculateDiff = DiffUtil.calculateDiff(diffCallback)
|
||||||
|
calculateDiff.dispatchUpdatesTo(this)
|
||||||
|
data = newData
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||||
|
val inflate = ItemLoveBinding.inflate(LayoutInflater.from(parent.context),parent,false)
|
||||||
|
return VH(inflate)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int = data.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||||
|
data[position].run {
|
||||||
|
holder.vb.cardView.setOnClickListener {
|
||||||
|
goList.invoke(this)
|
||||||
|
}
|
||||||
|
Log.d(MyApp.TAG, "--------LoveAdapter-----urls.regular=${urls.regular}")
|
||||||
|
Glide.with(MyApp.application)
|
||||||
|
.asDrawable()
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||||
|
.load(urls.regular)
|
||||||
|
.thumbnail(0.2f)
|
||||||
|
.error(R.drawable.placeholder)
|
||||||
|
.placeholder(R.drawable.placeholder)
|
||||||
|
.listener(object : RequestListener<Drawable> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<Drawable>,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
Log.d(MyApp.TAG, "----------LoveAdapter-onLoadFailed----urls.thumb=${urls.thumb} e=${e?.message}")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: Drawable,
|
||||||
|
model: Any,
|
||||||
|
target: Target<Drawable>?,
|
||||||
|
dataSource: DataSource,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.into(holder.vb.loveWallpaper)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class DiffCallback(var old: List<Bean>, var new: List<Bean>) : DiffUtil.Callback() {
|
||||||
|
override fun getOldListSize(): Int = old.size
|
||||||
|
|
||||||
|
override fun getNewListSize(): Int = new.size
|
||||||
|
|
||||||
|
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||||
|
val thumb = old[oldItemPosition].urls.thumb
|
||||||
|
val newThumb = new[newItemPosition].urls.thumb
|
||||||
|
return thumb == newThumb
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||||
|
val love = old[oldItemPosition].love
|
||||||
|
val newLove = new[newItemPosition].love
|
||||||
|
return love == newLove
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package com.wall.photography.wallpaper.data
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
class Author(
|
||||||
|
var name: String,
|
||||||
|
var portfolio_url: String,
|
||||||
|
var authorHtml: String,
|
||||||
|
var header_large: String,
|
||||||
|
var header_medium: String,
|
||||||
|
var header_small: String
|
||||||
|
) : Serializable
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.wall.photography.wallpaper.data
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import androidx.room.TypeConverters
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.room.AuthorTypeCovert
|
||||||
|
import com.wall.photography.wallpaper.room.UrlsTypeCovert
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
@TypeConverters(AuthorTypeCovert::class, UrlsTypeCovert::class)
|
||||||
|
@Entity(tableName = MyApp.TABLE_NAME)
|
||||||
|
class Bean(
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
var id: Int = 0,
|
||||||
|
var alt_description: String,
|
||||||
|
var links: String,
|
||||||
|
var urls: URLS,
|
||||||
|
var user: Author,
|
||||||
|
var love: Boolean = false,
|
||||||
|
var cateName: String,
|
||||||
|
var download: String,
|
||||||
|
var downloadFilePath: String? = null
|
||||||
|
) : Serializable
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package com.wall.photography.wallpaper.data
|
||||||
|
|
||||||
|
class Links(
|
||||||
|
var download: String,
|
||||||
|
var download_location: String,
|
||||||
|
var html: String
|
||||||
|
) {
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package com.wall.photography.wallpaper.data
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
class URLS(
|
||||||
|
var full: String,
|
||||||
|
var raw: String,
|
||||||
|
var regular: String,
|
||||||
|
var small: String,
|
||||||
|
var thumb: String
|
||||||
|
) :Serializable{
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
package com.wall.photography.wallpaper.fragment
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.activivty.ListActivity
|
||||||
|
import com.wall.photography.wallpaper.adapter.AdapterCategory
|
||||||
|
import com.wall.photography.wallpaper.databinding.FragmentCategoryBinding
|
||||||
|
import com.wall.photography.wallpaper.databinding.FragmentHomeBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.MyItemDecoration
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class CategoryFragment : Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = CategoryFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var viewModel: CategoryViewModel? = null
|
||||||
|
private lateinit var vb: FragmentCategoryBinding
|
||||||
|
private lateinit var mAdapter: AdapterCategory
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
vb = FragmentCategoryBinding.inflate(layoutInflater)
|
||||||
|
return vb.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
viewModel = ViewModelProvider(this)[CategoryViewModel::class.java]
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
viewModel?.getData()
|
||||||
|
}
|
||||||
|
mAdapter = AdapterCategory(requireContext()){
|
||||||
|
startActivity(Intent(requireActivity(),ListActivity::class.java).apply {
|
||||||
|
putExtra(ListActivity.KEY,it.cateName)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel?.data?.observe(requireActivity()) {
|
||||||
|
Log.d(MyApp.TAG, "----------category ${it.size}- ${Thread.currentThread().name}")
|
||||||
|
mAdapter.updateData(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
vb.categoryRecycler.run {
|
||||||
|
adapter = mAdapter
|
||||||
|
layoutManager = GridLayoutManager(requireContext(), 2)
|
||||||
|
addItemDecoration(MyItemDecoration(requireContext(), 8, 8, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun refreshCate(){
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
viewModel?.getData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.wall.photography.wallpaper.fragment
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.R
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.room.MyDataBase
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class CategoryViewModel : ViewModel() {
|
||||||
|
var data: MutableLiveData<List<Bean>> = MutableLiveData()
|
||||||
|
|
||||||
|
|
||||||
|
suspend fun getData() {
|
||||||
|
return run {
|
||||||
|
val mutableListOf = mutableListOf<Bean>()
|
||||||
|
val strings = MyApp.application.resources.getStringArray(R.array.category_name)
|
||||||
|
for (i in 1 until 8) {
|
||||||
|
val categoryCovert =
|
||||||
|
MyDataBase.getInstance().getBeanDao().getCategoryCovert(strings[i])
|
||||||
|
Log.d(MyApp.TAG, "-------categoryCovert=${categoryCovert?.cateName} ${Thread.currentThread().name}")
|
||||||
|
if (categoryCovert != null) {
|
||||||
|
mutableListOf.add(categoryCovert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main){
|
||||||
|
data.value = mutableListOf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
package com.wall.photography.wallpaper.fragment
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.activivty.SetWallpaperActivity
|
||||||
|
import com.wall.photography.wallpaper.adapter.AdapterCategory
|
||||||
|
import com.wall.photography.wallpaper.adapter.AdapterHomePaing
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.FragmentHomeBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.MyItemDecoration
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class HomeFragment : Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = HomeFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var viewModel: HomeViewModel
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var adapterHomepaging: AdapterHomePaing
|
||||||
|
|
||||||
|
private lateinit var vb: FragmentHomeBinding
|
||||||
|
|
||||||
|
private var list :MutableList<PagingData<Bean>> = mutableListOf()
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
vb = FragmentHomeBinding.inflate(layoutInflater)
|
||||||
|
return vb.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
Log.d(MyApp.TAG, "------------onActivityCreated homeFragment=$this")
|
||||||
|
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
// 恢复之前的状态
|
||||||
|
Log.d(MyApp.TAG, "------------onActivityCreated homeFragment list=${list.size}")
|
||||||
|
}
|
||||||
|
adapterHomepaging = AdapterHomePaing(mContext = requireContext()) {
|
||||||
|
startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply {
|
||||||
|
putExtra(SetWallpaperActivity.KEY_DATA, it)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
viewModel = ViewModelProvider(this)[HomeViewModel::class.java]
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
viewModel.getPagingData(MyApp.strings[0]).collectLatest {
|
||||||
|
Log.d(MyApp.TAG, "------------collectLatest ")
|
||||||
|
adapterHomepaging.submitData(it)
|
||||||
|
list.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initWallpaper()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun initWallpaper() {
|
||||||
|
vb.wallpaperRecycler.run {
|
||||||
|
layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
|
||||||
|
adapter = adapterHomepaging
|
||||||
|
addItemDecoration(MyItemDecoration(requireContext(), 8, 8, 0))
|
||||||
|
addOnScrollListener(object : OnScrollListener() {
|
||||||
|
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||||
|
super.onScrollStateChanged(recyclerView, newState)
|
||||||
|
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||||
|
Glide.with(context).resumeRequests()
|
||||||
|
} else {
|
||||||
|
Glide.with(context).pauseRequests()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package com.wall.photography.wallpaper.fragment
|
||||||
|
|
||||||
|
//import com.wall.photography.wallpaper.paging.MySource
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import androidx.paging.Pager
|
||||||
|
import androidx.paging.PagingConfig
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.paging.cachedIn
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.paging.MySource
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import java.util.Random
|
||||||
|
|
||||||
|
|
||||||
|
class HomeViewModel : ViewModel() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun getPaging(cateName:String): Flow<PagingData<Bean>> {
|
||||||
|
val nextInt = Random().nextInt(100)
|
||||||
|
Log.d(MyApp.TAG,"----------nextInt=${nextInt}")
|
||||||
|
return Pager(
|
||||||
|
config = PagingConfig(pageSize = MyApp.pageSize, initialLoadSize = MyApp.pageSize),
|
||||||
|
pagingSourceFactory = { MySource(cateName,nextInt) }
|
||||||
|
).flow
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPagingData(cateName:String): Flow<PagingData<Bean>> {
|
||||||
|
|
||||||
|
return getPaging(cateName).cachedIn(viewModelScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,108 @@
|
|||||||
|
package com.wall.photography.wallpaper.fragment
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.paging.LoadState
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.activivty.SetWallpaperActivity
|
||||||
|
import com.wall.photography.wallpaper.adapter.AdapterHomePaing
|
||||||
|
import com.wall.photography.wallpaper.adapter.AdapterLoves
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.databinding.FragmentLoveBinding
|
||||||
|
import com.wall.photography.wallpaper.manager.MyItemDecoration
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class LoveFragment : Fragment() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = LoveFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
private lateinit var viewModel: LoveViewModel
|
||||||
|
private lateinit var vb: FragmentLoveBinding
|
||||||
|
private lateinit var adapterLove: AdapterLoves
|
||||||
|
|
||||||
|
private var adapterLovePaging: AdapterHomePaing? = null
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
vb = FragmentLoveBinding.inflate(layoutInflater)
|
||||||
|
return vb.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
viewModel = ViewModelProvider(this).get(LoveViewModel::class.java)
|
||||||
|
viewModel.setData()
|
||||||
|
initWallpaper()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initWallpaper() {
|
||||||
|
// adapterLove = AdapterLoves(requireContext()) {
|
||||||
|
// startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply {
|
||||||
|
// putExtra(SetWallpaperActivity.KEY_DATA, it)
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
adapterLovePaging = AdapterHomePaing(true,requireContext()) {
|
||||||
|
startActivity(Intent(requireActivity(), SetWallpaperActivity::class.java).apply {
|
||||||
|
putExtra(SetWallpaperActivity.KEY_DATA, it)
|
||||||
|
})
|
||||||
|
}.apply {
|
||||||
|
addLoadStateListener {
|
||||||
|
if(it.source.refresh is LoadState.NotLoading && adapterLovePaging?.itemCount == 0){
|
||||||
|
Log.d(MyApp.TAG, "------------love-空")
|
||||||
|
vb.tvNoLove.isVisible = true
|
||||||
|
vb.loveRecycler.isVisible = false
|
||||||
|
}else{
|
||||||
|
Log.d(MyApp.TAG, "------------love-不空")
|
||||||
|
vb.tvNoLove.isVisible = false
|
||||||
|
vb.loveRecycler.isVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
viewModel.getPagingData().collectLatest {
|
||||||
|
Log.d(MyApp.TAG, "------------love-update 分页")
|
||||||
|
adapterLovePaging?.submitData(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// viewModel.getLoves().observe(viewLifecycleOwner) {
|
||||||
|
// Log.d(MyApp.TAG, "-----------love-update ")
|
||||||
|
// adapterLove.updateData(it)
|
||||||
|
// }
|
||||||
|
vb.loveRecycler.run {
|
||||||
|
layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
adapter = adapterLovePaging
|
||||||
|
addItemDecoration(MyItemDecoration(requireContext(), 8, 8, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refreshLoves(){
|
||||||
|
adapterLovePaging?.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
Log.d(MyApp.TAG, "------------love onResume")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.wall.photography.wallpaper.fragment
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import androidx.paging.Pager
|
||||||
|
import androidx.paging.PagingConfig
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.paging.cachedIn
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.paging.MyLoveSource
|
||||||
|
//import com.wall.photography.wallpaper.paging.MyLoveSource
|
||||||
|
import com.wall.photography.wallpaper.room.BeanDao
|
||||||
|
import com.wall.photography.wallpaper.room.MyDataBase
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
|
||||||
|
class LoveViewModel : ViewModel() {
|
||||||
|
private lateinit var userDao: BeanDao
|
||||||
|
private lateinit var allLove: LiveData<List<Bean>>
|
||||||
|
|
||||||
|
|
||||||
|
private fun getPaging(): Flow<PagingData<Bean>> {
|
||||||
|
return Pager(
|
||||||
|
config = PagingConfig(pageSize = MyApp.pageSize, initialLoadSize = MyApp.pageSize),
|
||||||
|
pagingSourceFactory = { MyLoveSource() }
|
||||||
|
).flow
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPagingData(): Flow<PagingData<Bean>> {
|
||||||
|
|
||||||
|
return getPaging().cachedIn(viewModelScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setData() {
|
||||||
|
userDao = MyDataBase.getInstance().getBeanDao()
|
||||||
|
allLove = userDao.getLoveWallpaper()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLoves(): LiveData<List<Bean>> {
|
||||||
|
return allLove
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,318 @@
|
|||||||
|
package com.wall.photography.wallpaper.manager
|
||||||
|
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.drawable.BitmapDrawable
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Author
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.data.URLS
|
||||||
|
import okhttp3.Call
|
||||||
|
import okhttp3.Callback
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.json.JSONArray
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.io.OutputStream
|
||||||
|
import java.io.StringWriter
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
|
object DealData {
|
||||||
|
|
||||||
|
|
||||||
|
fun getJsonString(input: InputStream): String {
|
||||||
|
val stringWriter = StringWriter()
|
||||||
|
val charArray = CharArray(input.available())
|
||||||
|
var l = 0;
|
||||||
|
val bufReader = BufferedReader(InputStreamReader(input, StandardCharsets.UTF_8))
|
||||||
|
while (bufReader.read(charArray).also {
|
||||||
|
l = it
|
||||||
|
} != -1) {
|
||||||
|
stringWriter.write(charArray, 0, l)
|
||||||
|
}
|
||||||
|
return stringWriter.toString()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getBean(context: Context, jsonStr: String, cateName: String): MutableList<Bean> {
|
||||||
|
val jsonArray = JSONArray(jsonStr)
|
||||||
|
var data = mutableListOf<Bean>()
|
||||||
|
for (i in 0 until jsonArray.length()) {
|
||||||
|
val get = jsonArray.getJSONObject(i)
|
||||||
|
val description = get.getString("alt_description")
|
||||||
|
val links = get.getJSONObject("links")
|
||||||
|
val download = links.getString("download")
|
||||||
|
val downloadLocation = links.getString("download_location")
|
||||||
|
val html = links.getString("html")
|
||||||
|
|
||||||
|
|
||||||
|
val urls = get.getJSONObject("urls")
|
||||||
|
val full = urls.getString("full")
|
||||||
|
val raw = urls.getString("raw")
|
||||||
|
val regular = urls.getString("regular")
|
||||||
|
val small = urls.getString("small")
|
||||||
|
val thumb = urls.getString("thumb")
|
||||||
|
|
||||||
|
|
||||||
|
val users = get.getJSONObject("user")
|
||||||
|
val portfolio_url = users.getString("portfolio_url")
|
||||||
|
val name = users.getString("name")
|
||||||
|
val header_large = users.getString("header_large")
|
||||||
|
val header_medium = users.getString("header_medium")
|
||||||
|
val header_small = users.getString("header_small")
|
||||||
|
val user_html = users.getString("authorHtml")
|
||||||
|
|
||||||
|
val bean = Bean(
|
||||||
|
download = download,
|
||||||
|
cateName = cateName,
|
||||||
|
alt_description = description,
|
||||||
|
links = html,
|
||||||
|
urls = URLS(full, raw, regular, small, thumb),
|
||||||
|
user = Author(
|
||||||
|
name,
|
||||||
|
portfolio_url,
|
||||||
|
user_html,
|
||||||
|
header_large,
|
||||||
|
header_medium,
|
||||||
|
header_small
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data.add(bean)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun downloadFile(
|
||||||
|
url: String,
|
||||||
|
savePath: String,
|
||||||
|
result: (Boolean, input: InputStream?) -> Unit
|
||||||
|
) {
|
||||||
|
var client = OkHttpClient()
|
||||||
|
var request = Request.Builder().url(url).build()
|
||||||
|
var call = client.newCall(request)
|
||||||
|
call.enqueue(object : Callback {
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
result.invoke(false, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
response.body?.run {
|
||||||
|
val byteStream = byteStream()
|
||||||
|
val writeFile = writeFile(byteStream, savePath)
|
||||||
|
result.invoke(writeFile, byteStream)
|
||||||
|
} ?: run {
|
||||||
|
result.invoke(false, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun writeFile(input: InputStream, filePath: String): Boolean {
|
||||||
|
try {
|
||||||
|
val byte = ByteArray(4096)
|
||||||
|
val output = ByteArrayOutputStream()
|
||||||
|
var l: Int
|
||||||
|
while (input.read(byte).also { l = it } != -1) {
|
||||||
|
output.write(byte, 0, l)
|
||||||
|
}
|
||||||
|
val fileDe = File(filePath)
|
||||||
|
if (!fileDe.exists()) {
|
||||||
|
fileDe.createNewFile()
|
||||||
|
}
|
||||||
|
val fileOutputStream = FileOutputStream(filePath)
|
||||||
|
fileOutputStream.write(output.toByteArray())
|
||||||
|
output.close()
|
||||||
|
fileOutputStream.close()
|
||||||
|
return true
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Log.d("-----------", "---------ex=" + ex.message)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveImageQ(imagePath: String, context: Context): Boolean {
|
||||||
|
return try {
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
val contentValues =
|
||||||
|
getImageContentValues(File(imagePath))
|
||||||
|
val localUri = contentResolver.insert(
|
||||||
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
|
||||||
|
contentValues
|
||||||
|
)
|
||||||
|
// 拷贝到指定uri,如果没有这步操作,android11不会在相册显示
|
||||||
|
val out = context.contentResolver.openOutputStream(localUri!!)
|
||||||
|
copyFile(imagePath, out)
|
||||||
|
|
||||||
|
contentValues.clear();
|
||||||
|
contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
|
||||||
|
contentValues.putNull(MediaStore.MediaColumns.DATE_EXPIRES);
|
||||||
|
contentResolver.update(localUri, contentValues, null, null);
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getImageContentValues(paramFile: File): ContentValues {
|
||||||
|
val time = System.currentTimeMillis()
|
||||||
|
val localContentValues = ContentValues()
|
||||||
|
localContentValues.put(MediaStore.Images.Media.TITLE, paramFile.name)
|
||||||
|
localContentValues.put(MediaStore.Images.Media.DISPLAY_NAME, paramFile.name)
|
||||||
|
localContentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
|
||||||
|
localContentValues.put(MediaStore.Images.Media.RELATIVE_PATH, getSavePath())
|
||||||
|
// localContentValues.put(MediaStore.Images.Media.DATE_MODIFIED, time / 1000)
|
||||||
|
// localContentValues.put(MediaStore.Images.Media.DATE_ADDED, time / 1000)
|
||||||
|
return localContentValues
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSavePath(): String {
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveImage(imagePath: String, context: Context): Boolean {
|
||||||
|
return try {
|
||||||
|
val path = getSavePath() + File.separator + File(imagePath).name
|
||||||
|
val newFile = File(path)
|
||||||
|
if (!newFile!!.parentFile.exists()) {
|
||||||
|
newFile!!.parentFile.mkdirs()
|
||||||
|
}
|
||||||
|
val out = newFile.outputStream()
|
||||||
|
copyFile(imagePath, out)
|
||||||
|
|
||||||
|
val uri = Uri.fromFile(newFile)
|
||||||
|
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri))
|
||||||
|
out.close()
|
||||||
|
true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun copyFile(oldPath: String, out: OutputStream?): Boolean {
|
||||||
|
try {
|
||||||
|
var bytesum = 0
|
||||||
|
var byteread = 0
|
||||||
|
val oldFile = File(oldPath)
|
||||||
|
if (oldFile.exists()) {
|
||||||
|
// 读入原文件
|
||||||
|
val inStream: InputStream = FileInputStream(oldPath)
|
||||||
|
val buffer = ByteArray(1444)
|
||||||
|
while (inStream.read(buffer).also { byteread = it } != -1) {
|
||||||
|
bytesum += byteread //字节数 文件大小
|
||||||
|
println(bytesum)
|
||||||
|
out!!.write(buffer, 0, byteread)
|
||||||
|
}
|
||||||
|
inStream.close()
|
||||||
|
out!!.close()
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun saveToGallery(context: Context, photoFile: File): Uri? {
|
||||||
|
val displayName = "${System.currentTimeMillis()}.jpg"
|
||||||
|
val contentValues = ContentValues().apply {
|
||||||
|
put(MediaStore.Images.Media.DISPLAY_NAME, displayName)
|
||||||
|
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
put(MediaStore.Images.Media.IS_PENDING, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||||
|
} else {
|
||||||
|
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||||
|
}
|
||||||
|
|
||||||
|
val imageUri = contentResolver.insert(collectionUri, contentValues)
|
||||||
|
|
||||||
|
imageUri?.let { uri ->
|
||||||
|
try {
|
||||||
|
contentResolver.openOutputStream(uri)?.use { outputStream ->
|
||||||
|
val inputStream = FileInputStream(photoFile)
|
||||||
|
inputStream.copyTo(outputStream)
|
||||||
|
inputStream.close()
|
||||||
|
outputStream.close()
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
contentValues.clear()
|
||||||
|
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
|
||||||
|
contentResolver.update(uri, contentValues, null, null)
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
return uri
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.d(MyApp.TAG, "-----------------e=${e.printStackTrace()}")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} ?: run {
|
||||||
|
Log.d(MyApp.TAG, "----------------false")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveFreshAppImageToGallery(context: Context, bitmap: Bitmap) {
|
||||||
|
val bitmap = bitmap
|
||||||
|
val displayName = "${System.currentTimeMillis()}.jpg"
|
||||||
|
|
||||||
|
val values = ContentValues().apply {
|
||||||
|
put(MediaStore.Images.Media.DISPLAY_NAME, displayName)
|
||||||
|
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
|
||||||
|
put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
val collection =
|
||||||
|
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||||
|
val item = contentResolver.insert(collection, values)
|
||||||
|
|
||||||
|
item?.let { uri ->
|
||||||
|
try {
|
||||||
|
val outputStream = contentResolver.openOutputStream(uri)
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream!!)
|
||||||
|
outputStream.close()
|
||||||
|
|
||||||
|
Log.d(MyApp.TAG, "------------------Save successfully!")
|
||||||
|
val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
|
||||||
|
mediaScanIntent.data = uri
|
||||||
|
context.sendBroadcast(mediaScanIntent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.d(MyApp.TAG, "------------------Save Failed!")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
package com.wall.photography.wallpaper.manager
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
|
|
||||||
|
class MyItemDecoration(
|
||||||
|
private var context: Context,
|
||||||
|
private var v: Int,
|
||||||
|
private var h: Int,
|
||||||
|
private var ex: Int
|
||||||
|
) :
|
||||||
|
RecyclerView.ItemDecoration() {
|
||||||
|
// item占满一行时,该item是否需要左右间距
|
||||||
|
var mVerticalSpacing = true
|
||||||
|
|
||||||
|
var mHorizontalSpaci = true
|
||||||
|
|
||||||
|
init {
|
||||||
|
|
||||||
|
v = dpToPx(v, context)
|
||||||
|
h = dpToPx(h, context)
|
||||||
|
ex = dpToPx(ex, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
|
||||||
|
val position = parent.getChildAdapterPosition(view)
|
||||||
|
var spanCount = 1
|
||||||
|
var spanSize = 1
|
||||||
|
var spanIndex = 0
|
||||||
|
|
||||||
|
|
||||||
|
parent.layoutManager?.run {
|
||||||
|
if (this is StaggeredGridLayoutManager) {
|
||||||
|
spanCount = this.spanCount
|
||||||
|
(view.layoutParams as StaggeredGridLayoutManager.LayoutParams)?.run {
|
||||||
|
if (isFullSpan) spanSize = spanCount
|
||||||
|
spanIndex = this.spanIndex
|
||||||
|
}
|
||||||
|
} else if (this is GridLayoutManager) {
|
||||||
|
spanCount = this.spanCount
|
||||||
|
spanSize = this.spanSizeLookup.getSpanSize(position)
|
||||||
|
spanIndex = (view.layoutParams as GridLayoutManager.LayoutParams).spanIndex
|
||||||
|
} else if (this is LinearLayoutManager) {
|
||||||
|
outRect.left = v
|
||||||
|
outRect.right = v
|
||||||
|
outRect.bottom = h
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spanSize == spanCount) {
|
||||||
|
outRect.left =
|
||||||
|
if (mVerticalSpacing) v + ex else 0
|
||||||
|
outRect.right =
|
||||||
|
if (mVerticalSpacing) v + ex else 0
|
||||||
|
outRect.bottom = if (mHorizontalSpaci) h else 0
|
||||||
|
} else {
|
||||||
|
val itemAllSpacing = (v * (spanCount + 1) + ex * 2) / spanCount
|
||||||
|
val left = v * (spanIndex + 1) - itemAllSpacing * spanIndex + ex
|
||||||
|
val right = itemAllSpacing - left
|
||||||
|
outRect.left = left
|
||||||
|
outRect.right = right
|
||||||
|
outRect.bottom = h
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun dpToPx(dp: Int, context: Context): Int {
|
||||||
|
val density = context.resources.displayMetrics.density
|
||||||
|
return (dp * density).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
package com.wall.photography.wallpaper.manager
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
|
||||||
|
|
||||||
|
object Other {
|
||||||
|
|
||||||
|
fun dpToPx(dp: Int, context: Context): Int {
|
||||||
|
val density = context.resources.displayMetrics.density
|
||||||
|
return (dp * density).toInt()
|
||||||
|
}
|
||||||
|
fun pxToPx(context: Context, pxValue: Float): Int {
|
||||||
|
val scale = context.resources.displayMetrics.density
|
||||||
|
return (pxValue / scale + 0.5f).toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun getInternalFilePath(context: Context): String {
|
||||||
|
val filePath = "${context.cacheDir}/${System.currentTimeMillis()}.jpg"
|
||||||
|
return filePath
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestPermission(context: Activity, requestCode: Int): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return if (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
context,
|
||||||
|
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
|
||||||
|
requestCode
|
||||||
|
)
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getNavigationBarHeight(context: Context): Int {
|
||||||
|
val resources = context.resources
|
||||||
|
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||||
|
return if (resourceId > 0) {
|
||||||
|
resources.getDimensionPixelSize(resourceId)
|
||||||
|
} else 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.wall.photography.wallpaper.paging
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.paging.PagingSource
|
||||||
|
import androidx.paging.PagingState
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.room.MyDataBase
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class MyLoveSource( var diff:Int = 0) : PagingSource<Int, Bean>() {
|
||||||
|
override fun getRefreshKey(state: PagingState<Int, Bean>): Int? {
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Bean> {
|
||||||
|
|
||||||
|
val page = params.key ?: 1
|
||||||
|
var pageSize = params.loadSize
|
||||||
|
if(page == 1){
|
||||||
|
pageSize = MyApp.pageSize
|
||||||
|
}
|
||||||
|
val indexStart = pageSize * (page - 1)+diff
|
||||||
|
|
||||||
|
// val rspRepository = MyApp.data_Wallpaper?.subList(indexStart, indexStart + pageSize)
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
val rspRepository =
|
||||||
|
MyDataBase.getInstance().getBeanDao().getPagingLoveWallpaper(true,pageSize, indexStart)
|
||||||
|
val items = rspRepository
|
||||||
|
val preKey = if (page > 1) page - 1 else null
|
||||||
|
val nextKey = if (items.isNotEmpty()) page + 1 else null
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"-----------------Love--indexStart=${indexStart} pageSize=${pageSize} page=${page} items.size=${items.size}"
|
||||||
|
)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"--------------Love-----return thread=${Thread.currentThread().name}"
|
||||||
|
)
|
||||||
|
LoadResult.Page(items, preKey, nextKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package com.wall.photography.wallpaper.paging
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.paging.PagingSource
|
||||||
|
import androidx.paging.PagingState
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.room.MyDataBase
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class MySource(var name:String,var diff:Int = 0) : PagingSource<Int, Bean>() {
|
||||||
|
override fun getRefreshKey(state: PagingState<Int, Bean>): Int? {
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Bean> {
|
||||||
|
|
||||||
|
val page = params.key ?: 1
|
||||||
|
var pageSize = params.loadSize
|
||||||
|
if(page == 1){
|
||||||
|
pageSize = MyApp.pageSize
|
||||||
|
}
|
||||||
|
val indexStart = pageSize * (page - 1)+diff
|
||||||
|
|
||||||
|
// val rspRepository = MyApp.data_Wallpaper?.subList(indexStart, indexStart + pageSize)
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
val rspRepository =
|
||||||
|
MyDataBase.getInstance().getBeanDao().getNextWallpaper(name,pageSize, indexStart)
|
||||||
|
val items = rspRepository
|
||||||
|
val preKey = if (page > 1) page - 1 else null
|
||||||
|
val nextKey = if (items.isNotEmpty()) page + 1 else null
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"-------------------indexStart=${indexStart} pageSize=${pageSize} page=${page} items.size=${items.size}"
|
||||||
|
)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Log.d(
|
||||||
|
MyApp.TAG,
|
||||||
|
"-------------------return thread=${Thread.currentThread().name}"
|
||||||
|
)
|
||||||
|
LoadResult.Page(items, preKey, nextKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.wall.photography.wallpaper.room
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.wall.photography.wallpaper.data.Author
|
||||||
|
|
||||||
|
class AuthorTypeCovert {
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun getAuthor(value: String): Author {
|
||||||
|
|
||||||
|
return Gson().fromJson(value, Author::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun authorToString(author: Author): String {
|
||||||
|
return Gson().toJson(author)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.wall.photography.wallpaper.room
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.paging.PagingSource
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface BeanDao {
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
|
fun insertBean(bean: Bean)
|
||||||
|
|
||||||
|
@Update
|
||||||
|
fun updateBean(bean: Bean)
|
||||||
|
|
||||||
|
@Query("delete from wall_paper")
|
||||||
|
fun deleteTBData()
|
||||||
|
|
||||||
|
|
||||||
|
@Query("select * from wall_paper order by id desc")
|
||||||
|
fun getAllWallpaper(): List<Bean>
|
||||||
|
|
||||||
|
@Query("select * from wall_paper where id==:myId")
|
||||||
|
fun getCurWallpaper(myId: Int): Bean
|
||||||
|
|
||||||
|
@Query("select * from wall_paper where love==:isLove order by id desc ")
|
||||||
|
fun getLoveWallpaper(isLove:Boolean = true): LiveData<List<Bean>>
|
||||||
|
|
||||||
|
@Query("select * from wall_paper where love==:isLove order by id desc LIMIT :pageSize OFFSET :pageNUmber")
|
||||||
|
suspend fun getPagingLoveWallpaper(isLove:Boolean = true,pageSize: Int, pageNUmber: Int): List<Bean>
|
||||||
|
|
||||||
|
|
||||||
|
@Query("select * from wall_paper where cateName==:cateName order by id desc LIMIT 1 OFFSET 2")
|
||||||
|
suspend fun getCategoryCovert(cateName: String): Bean?
|
||||||
|
|
||||||
|
|
||||||
|
@Query("select * from wall_paper where cateName==:cateName order by id desc LIMIT :pageSize OFFSET :pageNUmber")
|
||||||
|
suspend fun getNextWallpaper(cateName: String, pageSize: Int, pageNUmber: Int): List<Bean>
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.wall.photography.wallpaper.room
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.Room.databaseBuilder
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
|
||||||
|
|
||||||
|
@Database(entities = [Bean::class], version = MyApp.ROOM_Version, exportSchema = false)
|
||||||
|
abstract class MyDataBase : RoomDatabase() {
|
||||||
|
|
||||||
|
abstract fun getBeanDao(): BeanDao
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private var myDataBase: MyDataBase? = null
|
||||||
|
fun getInstance(): MyDataBase {
|
||||||
|
return if (myDataBase == null) {
|
||||||
|
myDataBase = databaseBuilder(
|
||||||
|
MyApp.application,
|
||||||
|
MyDataBase::class.java, MyApp.ROOM_NAME
|
||||||
|
).build()
|
||||||
|
myDataBase!!
|
||||||
|
}else{
|
||||||
|
myDataBase!!
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.wall.photography.wallpaper.room
|
||||||
|
|
||||||
|
import androidx.room.TypeConverter
|
||||||
|
import com.google.gson.Gson
|
||||||
|
|
||||||
|
import com.wall.photography.wallpaper.data.URLS
|
||||||
|
|
||||||
|
class UrlsTypeCovert {
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun getUrls(value: String): URLS {
|
||||||
|
|
||||||
|
return Gson().fromJson(value, URLS::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun urlsToString(urls: URLS): String {
|
||||||
|
return Gson().toJson(urls)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.wall.photography.wallpaper.viewmode
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import androidx.paging.Pager
|
||||||
|
import androidx.paging.PagingConfig
|
||||||
|
import androidx.paging.PagingData
|
||||||
|
import androidx.paging.cachedIn
|
||||||
|
import com.wall.photography.wallpaper.MyApp
|
||||||
|
import com.wall.photography.wallpaper.data.Bean
|
||||||
|
import com.wall.photography.wallpaper.paging.MySource
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
|
||||||
|
class ListActivityViewModel : ViewModel() {
|
||||||
|
|
||||||
|
fun getPaging(cateName:String): Flow<PagingData<Bean>> {
|
||||||
|
return Pager(
|
||||||
|
config = PagingConfig(pageSize = MyApp.pageSize, initialLoadSize = MyApp.pageSize),
|
||||||
|
pagingSourceFactory = { MySource(cateName) }
|
||||||
|
).flow
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getPagingData(cateName:String): Flow<PagingData<Bean>> {
|
||||||
|
|
||||||
|
return getPaging(cateName).cachedIn(viewModelScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
6
app/src/main/res/color/bottom_color.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="@color/gray" android:state_checked="false" />
|
||||||
|
<item android:color="@color/main_color" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
30
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="85.84757"
|
||||||
|
android:endY="92.4963"
|
||||||
|
android:startX="42.9492"
|
||||||
|
android:startY="49.59793"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/back.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M941.3,553.2 L240.4,553.2l347.2,347.2 -58.3,58.3L82.7,512 529.4,65.3l58.3,58.3 -347.2,347.2 700.9,0L941.3,553.2zM199.2,512l0.6,0.6 0,-1.1L199.2,512z"
|
||||||
|
android:fillColor="#020202"/>
|
||||||
|
</vector>
|
||||||
6
app/src/main/res/drawable/back_bg.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/set_loading_color"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_category.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M487,347.4C487,424.5 424.5,487 347.4,487L237.6,487C160.5,487 98,424.5 98,347.4L98,237.6C98,160.5 160.5,98 237.6,98h109.9C424.5,98 487,160.5 487,237.6v109.9zM487,786.4C487,863.5 424.5,926 347.4,926L237.6,926C160.5,926 98,863.5 98,786.4L98,676.6C98,599.5 160.5,537 237.6,537h109.9C424.5,537 487,599.5 487,676.6v109.9zM926,347.4C926,424.5 863.5,487 786.4,487L676.6,487C599.5,487 537,424.5 537,347.4L537,237.6C537,160.5 599.5,98 676.6,98h109.9C863.5,98 926,160.5 926,237.6v109.9zM730.7,533.6c-107.9,0 -195.3,87.4 -195.3,195.3s87.4,195.3 195.3,195.3S926,836.8 926,728.9s-87.4,-195.3 -195.3,-195.3zM730.7,843.3c-63.2,0 -114.4,-51.2 -114.4,-114.4S667.5,614.5 730.7,614.5 845.1,665.7 845.1,728.9 793.9,843.3 730.7,843.3z"
|
||||||
|
android:fillColor="#666666"/>
|
||||||
|
</vector>
|
||||||
12
app/src/main/res/drawable/icon_download.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M819.2,405.6c0,-169.7 -137.5,-307.2 -307.2,-307.2s-307.2,137.5 -307.2,307.2c-113.1,0 -204.8,91.7 -204.8,204.8s91.7,204.8 204.8,204.8h102.4V733.3h-102.4c-67.8,0 -122.9,-55.1 -122.9,-122.9 0,-67.8 55.1,-122.9 122.9,-122.9h81.9v-81.9c0,-124.2 101.1,-225.3 225.3,-225.3 124.2,0 225.3,101.1 225.3,225.3v81.9h81.9c67.8,0 122.9,55.1 122.9,122.9 0,67.8 -55.1,122.9 -122.9,122.9h-102.4v81.9h102.4c113.1,0 204.8,-91.7 204.8,-204.8s-91.7,-204.8 -204.8,-204.8z"
|
||||||
|
android:fillColor="#040000"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M511.4,925.5l221.3,-238 -64.4,-60 -110.8,119.2V410.2h-92.2v336.5L354.5,627.5l-64.4,60z"
|
||||||
|
android:fillColor="#040000"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_home.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M938.6,420.1 L544.9,89.1c-0.1,-0.1 -0.1,-0.1 -0.2,-0.2 -0.4,-0.3 -0.8,-0.7 -1.2,-1 -0.2,-0.1 -0.3,-0.3 -0.5,-0.4 -0.5,-0.4 -1,-0.7 -1.5,-1.1 -0.1,-0.1 -0.2,-0.1 -0.2,-0.2 -0.6,-0.4 -1.2,-0.8 -1.8,-1.2 -0,-0 -0,-0 -0,-0 -18.3,-11.6 -42.9,-10.2 -59.7,4.1L86,420.1c-20.6,17.3 -22.7,47.4 -4.7,67.1 18,19.8 49.3,21.8 69.8,4.5l33.9,-28.5 0,279.2c0,65.7 55.6,119.2 124,119.2l73.9,0c27.3,0 49.5,-21.3 49.5,-47.6L432.5,589.5c0,-13.3 11.2,-24.1 25,-24.1l109.5,0c13.8,0 25.1,10.8 25.1,24.1l0,219c0,3.3 0.3,6.5 1,9.7l1.2,5.6c4.8,22 25,37.9 48.4,37.9l72.7,0c68.4,0 124,-53.5 124,-119.2l0,-279.2 33.9,28.5c9.4,7.9 21,11.7 32.6,11.7 13.8,0 27.5,-5.5 37.3,-16.3C961.2,467.4 959.1,437.4 938.6,420.1z"
|
||||||
|
android:fillColor="#272636"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_love.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M533.5,268.3q33.8,-42 71.7,-75.8 32.8,-27.6 74.2,-50.2t86.5,-19.5q63.5,5.1 106,30.2t67.6,63.5 34.3,87 6.1,99.8 -17.9,97.8 -36.9,87 -48.6,74.8 -53.2,62q-41,42 -85.5,78.3t-85,62.5 -73.7,41.5 -51.7,15.4q-20.5,1 -52.2,-14.3t-69.6,-41.5 -79.9,-62 -82.9,-75.8q-26.6,-25.6 -57.3,-59.4t-57.9,-74.2 -46.6,-87.6 -21.5,-100.4 11.3,-99.8 39.9,-83.5 65.5,-62 88.1,-35.3q24.6,-5.1 49.2,-1.5t48.1,12.3 45.1,22 41,27.6q45.1,33.8 86,80.9z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_set_wallapper.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M938.7,553.9L938.7,768c0,64.8 -52.5,117.3 -117.3,117.3L202.7,885.3c-64.8,0 -117.3,-52.5 -117.3,-117.3L85.3,256c0,-64.8 52.5,-117.3 117.3,-117.3h618.7c64.8,0 117.3,52.5 117.3,117.3v297.9zM874.7,479.3L874.7,256a53.3,53.3 0,0 0,-53.3 -53.3L202.7,202.7a53.3,53.3 0,0 0,-53.3 53.3v344.5A290.1,290.1 0,0 1,192 597.3a286.9,286.9 0,0 1,183.3 65.8C427,528.4 556.9,437.3 704,437.3c65.7,0 127,16.8 170.7,42zM874.7,561.5c-5.3,-8.3 -21.1,-21.7 -43.6,-32.9C796.8,511.5 753,501.3 704,501.3c-121.8,0 -229.1,76.3 -270.4,188.7 -2.7,7.4 -7.4,20.3 -14,38.6 -7.7,21.3 -34.5,28.1 -51.4,13.1 -16.4,-14.6 -28.6,-25.1 -36.1,-31.1A222.9,222.9 0,0 0,192 661.3c-14.5,0 -28.7,1.4 -42.7,4.1L149.3,768a53.3,53.3 0,0 0,53.3 53.3h618.7a53.3,53.3 0,0 0,53.3 -53.3L874.7,561.5zM320,480a96,96 0,1 1,0 -192,96 96,0 0,1 0,192zM320,416a32,32 0,1 0,0 -64,32 32,0 0,0 0,64z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_setting.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M951.7,428.8c-0.2,-1.8 -0.4,-3.3 -0.7,-4.2v-0.8l-0.4,-2.2c-7.1,-34.6 -30,-56.9 -58.5,-56.9h-4.7c-48.6,0 -88,-39.6 -88,-88 0,-11.2 5.2,-27.1 7.4,-32.7 13.8,-32.2 -0.9,-68.9 -35,-87.6L664.5,95.7l-2,-0.7c-8,-2.6 -17.3,-5.7 -27.7,-5.7 -19.4,0 -41.2,9 -54.7,22.5 -16.9,16.7 -51.2,41.6 -71.6,41.6 -20.3,0 -54.7,-24.8 -71.6,-41.6 -14.4,-14.2 -34.3,-22.5 -54.7,-22.5 -10.7,0 -19.7,3 -27.7,5.7l-1.8,0.7 -112.5,60.9 -0.7,0.4c-27.3,17.1 -38.4,56.3 -24.5,87.4l0.2,0.4 0.2,0.4c2.2,4.9 9,21.5 9,36 0,48.6 -39.6,88 -88,88h-4.7c-29.8,0 -52.1,22 -58.5,57.3l-0.4,2v0.7c0,1 -0.4,2.4 -0.7,4.2 -2.5,15.1 -8.5,50.7 -8.5,79.8 0,29.1 5.9,64.7 8.5,79.8 0.2,1.8 0.4,3.3 0.7,4.2v0.8l0.4,2.2c7.1,34.6 30,56.9 58.5,56.9h2.4c48.6,0 88,39.6 88,88 0,11.2 -5.2,27.1 -7.4,32.7 -13.3,30.3 -0.7,69.2 28.7,88.8l0.8,0.4 106,59 2,0.7c8,2.6 17.1,5.7 27.5,5.7 22.2,0 42.2,-8.5 54.7,-22.5 1.2,-0.9 2.4,-2.1 3.8,-3.3 12.8,-11.2 47.2,-40.8 69.9,-40.8 16.9,0 45.2,17.7 73.7,46.2 14.4,14.2 34.3,22.5 54.7,22.5 13.8,0 24,-3.8 35.6,-9.5l0.4,-0.2 108.7,-60.1 0.4,-0.4c27.3,-17.1 38.4,-56.3 24.5,-87.4l-0.2,-0.4 -0.2,-0.4c-0.2,-0.1 -8.7,-17.8 -7.1,-33.7l0.2,-1v-1c0,-48.6 39.6,-88 88,-88h5c29.8,0 52.1,-22 58.5,-57.3l0.4,-2v-0.7c0.2,-0.8 0.4,-2 0.7,-3.6 2.6,-14.7 8.6,-49 8.6,-80.4 0.2,-29 -5.7,-64.5 -8.3,-79.6zM511.7,651.2c-76.9,0 -139.2,-62.3 -139.2,-139.2s62.3,-139.2 139.2,-139.2S650.9,435.1 650.9,512s-62.3,139.2 -139.2,139.2z"
|
||||||
|
android:fillColor="@color/main_color"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/im_love_normal.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M667.8,117.3C832.9,117.3 938.7,249.7 938.7,427.9c0,138.3 -125.1,290.5 -371.6,461.6a96.8,96.8 0,0 1,-110.2 0C210.4,718.4 85.3,566.1 85.3,427.9 85.3,249.7 191.1,117.3 356.2,117.3c59.6,0 100.1,20.8 155.8,68.1C567.7,138.2 608.2,117.3 667.8,117.3zM667.8,180.5c-41.4,0 -70.3,15.2 -117,55 -2.2,1.8 -14.4,12.4 -17.9,15.4a32.3,32.3 0,0 1,-41.8 0c-3.5,-3 -15.8,-13.5 -17.9,-15.4 -46.7,-39.9 -75.5,-55 -117,-55C230.2,180.5 149.3,281.3 149.3,426.7 149.3,537.6 262.9,675.2 493.6,834.8a32.4,32.4 0,0 0,36.7 0C761.1,675.3 874.7,537.6 874.7,426.7c0,-145.4 -80.9,-246.2 -206.9,-246.2z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/im_love_selected.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M667.8,117.3C832.9,117.3 938.7,249.7 938.7,427.9c0,138.3 -125.1,290.5 -371.6,461.6a96.8,96.8 0,0 1,-110.2 0C210.4,718.4 85.3,566.1 85.3,427.9 85.3,249.7 191.1,117.3 356.2,117.3c59.6,0 100.1,20.8 155.8,68.1C567.7,138.2 608.2,117.3 667.8,117.3z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
||||||
6
app/src/main/res/drawable/love_selector.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/im_love_selected" android:state_selected="true" />
|
||||||
|
<item android:drawable="@drawable/im_love_normal" android:state_selected="false" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
BIN
app/src/main/res/drawable/placeholder.9.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
8
app/src/main/res/drawable/rate_app_bg.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<corners android:radius="12dp"/>
|
||||||
|
<stroke android:color="@color/main_color" android:width="1dp"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/select_dialog_bg.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
<corners android:radius="9dp" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/set_wallpaper_shape.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="18dp" />
|
||||||
|
<solid android:color="@color/category_aplah" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
86
app/src/main/res/layout/activity_about.xml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?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"
|
||||||
|
tools:context=".activivty.AboutActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back"
|
||||||
|
android:layout_width="44dp"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginTop="23dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/card_logo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="63dp"
|
||||||
|
app:cardCornerRadius="6dp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/back">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="86dp"
|
||||||
|
android:layout_height="86dp"
|
||||||
|
android:src="@mipmap/logo" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_version"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/version"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="15sp"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/card_logo" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_rate"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:layout_marginTop="35dp"
|
||||||
|
android:layout_marginEnd="35dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="5dp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/tv_version">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/rate_us"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:text="@string/rate_us_content"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0.5dp"
|
||||||
|
android:background="@color/set_loading_color"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/layout_rate"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:layout_marginEnd="25dp"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
36
app/src/main/res/layout/activity_list.xml
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout 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:orientation="vertical"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
tools:context=".activivty.ListActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back"
|
||||||
|
android:layout_width="44dp"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:src="@drawable/back" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:padding="10dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/tv_name"
|
||||||
|
android:layout_marginTop="10dp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
62
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?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="@color/bg_color"
|
||||||
|
tools:context=".activivty.MainActivity">
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/logo_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="70dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
app:cardCornerRadius="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/logo_icon"
|
||||||
|
android:layout_width="45dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:src="@mipmap/logo" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon_set"
|
||||||
|
android:layout_width="54dp"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginStart="22dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:padding="13dp"
|
||||||
|
android:src="@drawable/icon_setting" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/viewpager2"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/logo_layout" />
|
||||||
|
|
||||||
|
<com.google.android.material.bottomnavigation.BottomNavigationView
|
||||||
|
android:id="@+id/bottom_navigation"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/white"
|
||||||
|
app:itemIconTint="@color/bottom_color"
|
||||||
|
app:labelVisibilityMode="unlabeled"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:menu="@menu/bottom_navigation" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
117
app/src/main/res/layout/activity_set_wallpaper.xml
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?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"
|
||||||
|
tools:context=".activivty.SetWallpaperActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/preview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginTop="36dp"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:background="@drawable/back_bg"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:layout_marginEnd="25dp"
|
||||||
|
android:id="@+id/relayout"
|
||||||
|
android:background="@drawable/set_wallpaper_shape"
|
||||||
|
android:padding="20dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/header_card"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/header"
|
||||||
|
android:layout_width="33dp"
|
||||||
|
android:layout_height="33dp"
|
||||||
|
android:src="@mipmap/ic_launcher" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/author_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignTop="@id/header_card"
|
||||||
|
android:layout_alignBottom="@id/header_card"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_toEndOf="@id/header_card"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/header_card"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/im_download"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:src="@drawable/icon_download" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/im_set_wallpaper"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:src="@drawable/icon_set_wallapper" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/im_love"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:src="@drawable/love_selector" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/loading_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:clickable="true"
|
||||||
|
android:background="@color/set_loading_color">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminateTint="@color/white" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
31
app/src/main/res/layout/activity_welcome.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?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"
|
||||||
|
tools:context=".activivty.MyWelComeActivity">
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="90dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:src="@mipmap/welcome_icon"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/welcome_text"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/icon" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
13
app/src/main/res/layout/fragment_category.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragment.CategoryFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/category_recycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
13
app/src/main/res/layout/fragment_home.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".fragment.HomeFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/wallpaper_recycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
27
app/src/main/res/layout/fragment_love.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
tools:context=".fragment.LoveFragment">
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/loveRecycler"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:id="@+id/tv_no_love"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:text="@string/no_love"/>
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
38
app/src/main/res/layout/item_category.xml
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="260dp"
|
||||||
|
android:id="@+id/card_view"
|
||||||
|
app:cardCornerRadius="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/wallpaper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="260dp"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@color/category_aplah">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
15
app/src/main/res/layout/item_home.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:id="@+id/card_view"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="8dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/wallpaper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:layout_height="200dp" />
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
14
app/src/main/res/layout/item_love.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/card_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="260dp"
|
||||||
|
app:cardCornerRadius="8dp">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/love_wallpaper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
59
app/src/main/res/layout/select_dialog.xml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:background="@drawable/select_dialog_bg"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/home"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/home"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0.5dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:background="@color/main_color" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/lock"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/lock"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0.5dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:background="@color/main_color" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/both"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/both"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
19
app/src/main/res/menu/bottom_navigation.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/home"
|
||||||
|
android:icon="@drawable/icon_home"
|
||||||
|
android:title="." />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/category"
|
||||||
|
android:icon="@drawable/icon_category"
|
||||||
|
android:title="" />
|
||||||
|
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/love"
|
||||||
|
android:icon="@drawable/icon_love"
|
||||||
|
android:title="" />
|
||||||
|
|
||||||
|
</menu>
|
||||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/logo.png
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/wel_bg.png
Normal file
|
After Width: | Height: | Size: 575 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/welcome_icon.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
7
app/src/main/res/values-night/themes.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Base.Theme.PhotographyWallpaper" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<!-- Customize your dark theme here. -->
|
||||||
|
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
10
app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="black">#FF000000</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
<color name="main_color">#414548</color>
|
||||||
|
<color name="bg_color">#F5F5F5</color>
|
||||||
|
<color name="gray">#cdd5d5</color>
|
||||||
|
<color name="category_aplah">#80FFFFFF</color>
|
||||||
|
<color name="set_loading_color">#80414548</color>
|
||||||
|
</resources>
|
||||||
30
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">Photography Wallpapers</string>
|
||||||
|
<string name="welcome_text">Wallpaper</string>
|
||||||
|
<string name="grant_permission">Please grant permission to use related functions</string>
|
||||||
|
<string name="save_ok">Save to album successfully</string>
|
||||||
|
<string name="save_fail">Sorry,Save to album fail</string>
|
||||||
|
<string name="save_exception">Sorry,An error occurred while saving. Please try again.</string>
|
||||||
|
<string name="download_exception">Sorry,An error occurred while downloading. Please try again.</string>
|
||||||
|
<string name="home">Home screen</string>
|
||||||
|
<string name="lock">Lock screen</string>
|
||||||
|
<string name="both">Both</string>
|
||||||
|
<string name="set_success">Set wallpaper successfully</string>
|
||||||
|
<string name="set_fail">Failed to set wallpaper, please try again</string>
|
||||||
|
<string name="no_love">You haven not collected any wallpapers yet</string>
|
||||||
|
<string name="version">App Version V%s</string>
|
||||||
|
<string name="rate_us">Rate App</string>
|
||||||
|
<string name="rate_us_content">Consider giving us a review on the Google Play Store</string>
|
||||||
|
<string name="google_link">https://play.google.com/store/apps/details?id=%s</string>
|
||||||
|
<string name="to_gp_exception">An exception occurred. Please try again later.</string>
|
||||||
|
<string-array name="category_name">
|
||||||
|
<item>Wallpaper</item>
|
||||||
|
<item>Animals</item>
|
||||||
|
<item>Experimental</item>
|
||||||
|
<item>Film</item>
|
||||||
|
<item>Nature</item>
|
||||||
|
<item>Street</item>
|
||||||
|
<item>Patterns</item>
|
||||||
|
<item>Travel</item>
|
||||||
|
</string-array>
|
||||||
|
</resources>
|
||||||
15
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Base.Theme.PhotographyWallpaper" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<!-- Customize your light theme here. -->
|
||||||
|
<item name="colorPrimary">@color/main_color</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.PhotographyWallpaper" parent="Base.Theme.PhotographyWallpaper" />
|
||||||
|
|
||||||
|
<style name="Welcome.Theme" parent="Base.Theme.PhotographyWallpaper">
|
||||||
|
<item name="android:windowBackground">@mipmap/wel_bg</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample backup rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/guide/topics/data/autobackup
|
||||||
|
for details.
|
||||||
|
Note: This file is ignored for devices older that API 31
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore
|
||||||
|
-->
|
||||||
|
<full-backup-content>
|
||||||
|
<!--
|
||||||
|
<include domain="sharedpref" path="."/>
|
||||||
|
<exclude domain="sharedpref" path="device.xml"/>
|
||||||
|
-->
|
||||||
|
</full-backup-content>
|
||||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample data extraction rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||||
|
for details.
|
||||||
|
-->
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
-->
|
||||||
|
</cloud-backup>
|
||||||
|
<!--
|
||||||
|
<device-transfer>
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
</device-transfer>
|
||||||
|
-->
|
||||||
|
</data-extraction-rules>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.wall.photography.wallpaper
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||