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)
|
||||
}
|
||||
}
|
||||