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
|
||||
69
app/build.gradle.kts
Normal file
@ -0,0 +1,69 @@
|
||||
plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("io.objectbox")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.live.mylivewallpaper"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.live.mylivewallpaper"
|
||||
minSdk = 23
|
||||
targetSdk = 35
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation("androidx.appcompat:appcompat:1.7.0")
|
||||
implementation("com.google.android.material:material:1.12.0")
|
||||
implementation("androidx.constraintlayout:constraintlayout:2.2.0")
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.2.1")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||
|
||||
implementation ("androidx.paging:paging-runtime:3.3.5")
|
||||
implementation ("androidx.paging:paging-runtime-ktx:3.3.5") // 包含 Kotlin 扩展
|
||||
implementation ("androidx.lifecycle:lifecycle-livedata-ktx:2.6.0") // LiveData 相关
|
||||
implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.0")
|
||||
|
||||
implementation ("com.google.code.gson:gson:2.10.1")
|
||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||
|
||||
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||
implementation("io.reactivex.rxjava2:rxjava:2.2.21")
|
||||
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
|
||||
implementation("com.squareup.retrofit2:adapter-rxjava2:2.9.0")
|
||||
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")
|
||||
|
||||
// implementation ("com.google.android.exoplayer:exoplayer:2.19.1")
|
||||
implementation("androidx.media3:media3-exoplayer:1.4.1")
|
||||
implementation ("androidx.media3:media3-ui:1.4.1")
|
||||
implementation ("androidx.media3:media3-exoplayer-dash:1.4.1")
|
||||
}
|
||||
116
app/objectbox-models/default.json
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
|
||||
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
|
||||
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
||||
"entities": [
|
||||
{
|
||||
"id": "1:150505122699528186",
|
||||
"lastPropertyId": "10:76475728747825161",
|
||||
"name": "ResultData",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:2927637172002004906",
|
||||
"name": "objectId",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:1001748290350717302",
|
||||
"name": "category",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "3:4120630564091130628",
|
||||
"name": "description",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "4:279795966790436055",
|
||||
"name": "downloads",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "5:97414655938247912",
|
||||
"name": "id",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "6:729161467269206587",
|
||||
"name": "image",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "7:5042336858198490957",
|
||||
"name": "pro",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "8:6165031016937588605",
|
||||
"name": "resolution",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "9:1947268834796297839",
|
||||
"name": "thumbnail",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "10:76475728747825161",
|
||||
"name": "wallpapertype",
|
||||
"type": 5
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
},
|
||||
{
|
||||
"id": "2:8834432815557132690",
|
||||
"lastPropertyId": "6:6490742020031879416",
|
||||
"name": "LikeData",
|
||||
"properties": [
|
||||
{
|
||||
"id": "1:846923696920771332",
|
||||
"name": "objectId",
|
||||
"type": 6,
|
||||
"flags": 1
|
||||
},
|
||||
{
|
||||
"id": "2:2661563405594510728",
|
||||
"name": "description",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "3:3803068480811227076",
|
||||
"name": "id",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "4:2573175242602089587",
|
||||
"name": "image",
|
||||
"type": 9
|
||||
},
|
||||
{
|
||||
"id": "5:4073665339586807072",
|
||||
"name": "wallpapertype",
|
||||
"type": 5
|
||||
},
|
||||
{
|
||||
"id": "6:6490742020031879416",
|
||||
"name": "thumbnail",
|
||||
"type": 9
|
||||
}
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
],
|
||||
"lastEntityId": "2:8834432815557132690",
|
||||
"lastIndexId": "0:0",
|
||||
"lastRelationId": "0:0",
|
||||
"lastSequenceId": "0:0",
|
||||
"modelVersion": 5,
|
||||
"modelVersionParserMinimum": 5,
|
||||
"retiredEntityUids": [],
|
||||
"retiredIndexUids": [],
|
||||
"retiredPropertyUids": [],
|
||||
"retiredRelationUids": [],
|
||||
"version": 1
|
||||
}
|
||||
21
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# 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
|
||||
@ -0,0 +1,26 @@
|
||||
package com.live.mylivewallpaper;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.live.mylivewallpaper", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
60
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,60 @@
|
||||
<?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" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.MyLiveWallpaper"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".activity.WelcomeActivity"
|
||||
android:exported="true" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".activity.VideoActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".activity.MainActivity"
|
||||
android:exported="true">
|
||||
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".help.LiveWallpaperService"
|
||||
android:permission="android.permission.BIND_WALLPAPER"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.service.wallpaper.WallpaperService" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.service.wallpaper"
|
||||
android:resource="@xml/wallpaper" />
|
||||
</service>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
937
app/src/main/assets/Dnamic.json
Normal file
@ -0,0 +1,937 @@
|
||||
[
|
||||
{
|
||||
"category": "Superheroes",
|
||||
"description": "Superman at Dawn, Batman at Dusk ☀️🌙",
|
||||
"downloads": "764",
|
||||
"id": 706,
|
||||
"image": "CrbPFNhB",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1733389216-batplane_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Typography",
|
||||
"description": "Social Battery 🔋",
|
||||
"downloads": "1031",
|
||||
"id": 701,
|
||||
"image": "trzGWDfX",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1732524555-social battery_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Serenity in motion three shades of calm ☀🌲",
|
||||
"downloads": "1275",
|
||||
"id": 696,
|
||||
"image": "eOtW8H41",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1731653548-landofcurvehill2keve.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Miscellaneous",
|
||||
"description": "A day from the table ⌚",
|
||||
"downloads": "2390",
|
||||
"id": 691,
|
||||
"image": "FANHkrd7",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1730796439-phone and watch_eve_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Eyes gleam danger looms 🎃",
|
||||
"downloads": "1673",
|
||||
"id": 686,
|
||||
"image": "lsh6OApW",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1729762256-farmhousenight2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Miscellaneous",
|
||||
"description": "This house isn\u0027t abandoned, it’s waiting for its next visitor🎃👻",
|
||||
"downloads": "2668",
|
||||
"id": 681,
|
||||
"image": "PF7tAOTL",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1728902211-hunted house night_2k0001-0500.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Pattern",
|
||||
"description": "Pealing the day off 📃☀️🌙",
|
||||
"downloads": "1341",
|
||||
"id": 676,
|
||||
"image": "rsRfKScm",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1728028841-ring rap night_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Splash of a day 🌅☀️",
|
||||
"downloads": "3246",
|
||||
"id": 671,
|
||||
"image": "foOunWCk",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1727080435-shallow portal view_night2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Miscellaneous",
|
||||
"description": "A humble reminder ⏰",
|
||||
"downloads": "4073",
|
||||
"id": 666,
|
||||
"image": "4N7KayXW",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1726132168-bedroomday_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Up above the hills 🏔️",
|
||||
"downloads": "5122",
|
||||
"id": 661,
|
||||
"image": "JCHdnxSA",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1725268183-highhouse_night2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Typography",
|
||||
"description": "Some quotes to stay 🌙",
|
||||
"downloads": "2361",
|
||||
"id": 656,
|
||||
"image": "N3ajOeRy",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1724316209-Billboard_night_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Pierce every barrier 🗻",
|
||||
"downloads": "2853",
|
||||
"id": 646,
|
||||
"image": "7KFchroN",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1723452904-mountain_eve2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Movies",
|
||||
"description": "I am Batman 🦇",
|
||||
"downloads": "19931",
|
||||
"id": 574,
|
||||
"image": "8UY4wWqm",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1711615577-batman night_ 2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Water artist\u0027s 🐟",
|
||||
"downloads": "2758",
|
||||
"id": 569,
|
||||
"image": "WCjDYARS",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1710829619-flathouses_eve_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Pixel",
|
||||
"description": "You are not alone if connected 💜",
|
||||
"downloads": "16072",
|
||||
"id": 564,
|
||||
"image": "IjwSHbOr",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1709800635-street light_eve.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Everyones favorite place 🏡",
|
||||
"downloads": "10290",
|
||||
"id": 559,
|
||||
"image": "zTen6JvL",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1709018879-roomnight_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Typography",
|
||||
"description": "Magic to being productive 🥇",
|
||||
"downloads": "5379",
|
||||
"id": 553,
|
||||
"image": "RgKQDe0S",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1708009647-workaholic2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Natures Roar 🌋",
|
||||
"downloads": "4975",
|
||||
"id": 548,
|
||||
"image": "MLgeY5kb",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1707205639-volcanonight2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Dream",
|
||||
"description": "A dream unfolds on a planet of fantasy 🔮",
|
||||
"downloads": "5589",
|
||||
"id": 543,
|
||||
"image": "jrRQzc91",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1706254240-fantasy land_night.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Star gazing blossoms 🌼",
|
||||
"downloads": "4914",
|
||||
"id": 538,
|
||||
"image": "AkvcDByU",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1705390298-flower garden night.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Bridge to Destiny 🚄",
|
||||
"downloads": "5276",
|
||||
"id": 533,
|
||||
"image": "j7Yf0vPE",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1704439511-train bridgenight.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "A Christmas tale in every snowflake 🎅❄️",
|
||||
"downloads": "3976",
|
||||
"id": 526,
|
||||
"image": "1KgweoUH",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1703244493-christmas_day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "A gentle ascent to mountain dreams and breathtaking vistas ⛷️",
|
||||
"downloads": "9052",
|
||||
"id": 510,
|
||||
"image": "kC7u0GDZ",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1701242505-SkiLiftmrng_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Abstract",
|
||||
"description": "Ephemeral circles of iridescence dance into a fleeting symphony of beauty ⭕",
|
||||
"downloads": "9657",
|
||||
"id": 505,
|
||||
"image": "vOsK5gxp",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1700642080-shapeevolveday.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Travel",
|
||||
"description": "Breezy ride and happy vibe 🐶🚗",
|
||||
"downloads": "2071",
|
||||
"id": 641,
|
||||
"image": "oqKLQpJX",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1722497518-dog in window_day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Spell casted river 🛶",
|
||||
"downloads": "3420",
|
||||
"id": 636,
|
||||
"image": "hlV7OB5q",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1721641544-boatday_2k0001-0250.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "A lazy day 👕👖",
|
||||
"downloads": "3356",
|
||||
"id": 631,
|
||||
"image": "hmpBkRvY",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1720687677-outside window day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "New Day New Experience 🏙️🌆",
|
||||
"downloads": "7789",
|
||||
"id": 619,
|
||||
"image": "UJ4ZSlcs",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1719824128-urban scape day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Beach day ⛱️",
|
||||
"downloads": "2421",
|
||||
"id": 614,
|
||||
"image": "JObnZA06",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1718957451-portalland2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Bread and omelette 🍳",
|
||||
"downloads": "2261",
|
||||
"id": 609,
|
||||
"image": "sjrO4pVH",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1718009097-breakfast.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Gaming",
|
||||
"description": "Gaming all day 🎮",
|
||||
"downloads": "5716",
|
||||
"id": 604,
|
||||
"image": "pAIRqGec",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1717055172-gameboy_day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "A windowsill oasis 🌆",
|
||||
"downloads": "4639",
|
||||
"id": 599,
|
||||
"image": "RDroSvOc",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1716191583-window_eve_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Hope for the big treat 🎣",
|
||||
"downloads": "9603",
|
||||
"id": 594,
|
||||
"image": "2A3syjid",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1715246272-fishing boat_day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "In the embrace of the forest find solace ⛺",
|
||||
"downloads": "7731",
|
||||
"id": 589,
|
||||
"image": "KbB1xhFA",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1714378818-forest landscape night_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Travel",
|
||||
"description": "Long drives and good music 🚗🎧",
|
||||
"downloads": "10717",
|
||||
"id": 584,
|
||||
"image": "EUSHJ5ms",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1713522582-carpov_mor.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Whats up there ❓",
|
||||
"downloads": "7476",
|
||||
"id": 579,
|
||||
"image": "7LTmuH04",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1712651718-spnight_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Day\u0027s adventure night\u0027s enchantment camping\u0027s beauty 🏕",
|
||||
"downloads": "10886",
|
||||
"id": 502,
|
||||
"image": "wbVMoC72",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1699777136-dayminimalcamp2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Evergreen peaks mirrored in the river\u0027s embrace 🍃",
|
||||
"downloads": "14451",
|
||||
"id": 499,
|
||||
"image": "7IliEZsh",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1698823262-riverforest.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Rippling reflections tell the story of a city\u0027s soul 🏙️",
|
||||
"downloads": "8301",
|
||||
"id": 484,
|
||||
"image": "5VxMGf4h",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1696926778-skyscrapers_day_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Material",
|
||||
"description": "Dial of calmness 🌸",
|
||||
"downloads": "17673",
|
||||
"id": 480,
|
||||
"image": "AkMD8q3V",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1696153365-star_night_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Travel",
|
||||
"description": "Campfire tales starry night dreams 🏕",
|
||||
"downloads": "8055",
|
||||
"id": 477,
|
||||
"image": "3BREY1zm",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1695542596-day2k0001-0100.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Silent flakes weave winter\u0027s gentle hush ❄",
|
||||
"downloads": "7716",
|
||||
"id": 474,
|
||||
"image": "TVEMQfdH",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1694933088-2snowforest2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Travel",
|
||||
"description": "A day at the beach 🏖",
|
||||
"downloads": "3842",
|
||||
"id": 471,
|
||||
"image": "KTENzWDZ",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1694332551-beach_morning2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Awaiting the rain 🌧",
|
||||
"downloads": "4466",
|
||||
"id": 468,
|
||||
"image": "q0Lmh4nC",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1693725913-3mushroom2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Urban Window Ambiance 🌆",
|
||||
"downloads": "11173",
|
||||
"id": 465,
|
||||
"image": "7ti6pMzo",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1693037796-3window2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Harmonious Haven Hideaway 🏠",
|
||||
"downloads": "4368",
|
||||
"id": 462,
|
||||
"image": "vot53mEg",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1692510723-2houselandscape2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Peace at dawn ☀Spooky at night 🌑",
|
||||
"downloads": "4101",
|
||||
"id": 459,
|
||||
"image": "39OkjUYW",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1691908909-spookyforest2k1.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Abstract",
|
||||
"description": "Dynamic Hues",
|
||||
"downloads": "5342",
|
||||
"id": 456,
|
||||
"image": "T9hpfdF6",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1691219115-bubbleday2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "A nice summer day 🍃",
|
||||
"downloads": "9603",
|
||||
"id": 453,
|
||||
"image": "UC1p4dc0",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1690703238-windmill_morning_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "The structure which has seen the history 💡",
|
||||
"downloads": "5437",
|
||||
"id": 450,
|
||||
"image": "GlLs3CPm",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1690098169-lighthouse_morning_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Dream",
|
||||
"description": "It\u0027s a small world 🌏",
|
||||
"downloads": "6744",
|
||||
"id": 447,
|
||||
"image": "aXIU9jZA",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1689493040-smallworld_2k_3.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Anime",
|
||||
"description": "Flying Nimbus",
|
||||
"downloads": "20160",
|
||||
"id": 444,
|
||||
"image": "SUZkrEve",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1688808963-goku_3_2K.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Swinging through out the day 💡",
|
||||
"downloads": "8777",
|
||||
"id": 441,
|
||||
"image": "aQfHE7IL",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1688111542-hanginglight_night_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "A nice summer day 🌳",
|
||||
"downloads": "5505",
|
||||
"id": 438,
|
||||
"image": "UpSPDZNr",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1687325278-minimallandscape_day.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Inner peace is a journey, not a\r\ndestination ",
|
||||
"downloads": "6637",
|
||||
"id": 435,
|
||||
"image": "tKwXeBdu",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1686635110-monument_day2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Travel",
|
||||
"description": "Endless trip 🚗",
|
||||
"downloads": "9835",
|
||||
"id": 432,
|
||||
"image": "3lZGPbye",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1685945189-vanride_night_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Material",
|
||||
"description": "Beats 💓",
|
||||
"downloads": "5831",
|
||||
"id": 429,
|
||||
"image": "vQnFCqPU",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1685000893-circleevening_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Everything is minimal from a distance 🏙️",
|
||||
"downloads": "5186",
|
||||
"id": 426,
|
||||
"image": "Ev4RPbXV",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1684397426-minimalcity_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Grinding the wind 🍃",
|
||||
"downloads": "3996",
|
||||
"id": 423,
|
||||
"image": "7OpaDjwh",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1683616413-wnidmilllandscapeevening_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Part of a living city 🚅",
|
||||
"downloads": "8101",
|
||||
"id": 420,
|
||||
"image": "5CPKMsLU",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1682840557-citymetro2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Daily view of urbans 🏙️",
|
||||
"downloads": "5868",
|
||||
"id": 417,
|
||||
"image": "OtwdhJQR",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1682063015-building streethangingclothsday.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "A full day of hot air balloons 🎈",
|
||||
"downloads": "6765",
|
||||
"id": 414,
|
||||
"image": "0WgcXC1L",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1681456632-hot_ai_ balloon_even.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "The Day and the Night ☀️😁🌕",
|
||||
"downloads": "15132",
|
||||
"id": 411,
|
||||
"image": "xG4aVS5H",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1680846537-moon.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Hooked to window 🪟",
|
||||
"downloads": "11247",
|
||||
"id": 408,
|
||||
"image": "KsvVwGXP",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1680157029-windowviewnight_.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "The island home 🏝️",
|
||||
"downloads": "5638",
|
||||
"id": 405,
|
||||
"image": "tZO4Pze9",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1679473271-island house.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Riverside wind 🍃",
|
||||
"downloads": "6701",
|
||||
"id": 401,
|
||||
"image": "unvPskGZ",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1678775334-riversideeve.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Refreshing mist from the falls 🌊",
|
||||
"downloads": "10163",
|
||||
"id": 398,
|
||||
"image": "IZXfhvuc",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1678170639-waterfallnight.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Sometimes things just have to be simple ☺",
|
||||
"downloads": "7972",
|
||||
"id": 395,
|
||||
"image": "YgyP8SFt",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1677505261-minimal_line.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Frames of time🖼️",
|
||||
"downloads": "6405",
|
||||
"id": 392,
|
||||
"image": "EnmR9OMx",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1676881685-polaroideve_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Beginning and end of the day 🗻",
|
||||
"downloads": "15618",
|
||||
"id": 388,
|
||||
"image": "NYvVb8ao",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1676009757-birds flying_2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Nature",
|
||||
"description": "Smell the sea and feel the sky 🌊",
|
||||
"downloads": "6105",
|
||||
"id": 385,
|
||||
"image": "LI4s9KNo",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1675262581-ocean_morning.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "The bright lights and the vibrant night 🌃",
|
||||
"downloads": "17213",
|
||||
"id": 382,
|
||||
"image": "Pj7HMyp4",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1674544752-townnight.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Connecting with life 🏕",
|
||||
"downloads": "14067",
|
||||
"id": 379,
|
||||
"image": "hbekHNsG",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1673846419-forest_night.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Long flight ✈️",
|
||||
"downloads": "13289",
|
||||
"id": 376,
|
||||
"image": "D9tpNJzm",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1672734207-planewindownight2k.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Vow to self sustain 🌄",
|
||||
"downloads": "7370",
|
||||
"id": 373,
|
||||
"image": "AI4T0psQ",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1672126921-houselandscapenight.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Holidays are coming 🎄",
|
||||
"downloads": "20696",
|
||||
"id": 370,
|
||||
"image": "Rd9ytJEj",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1671351128-snowvillage_night.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Everyday begins with possibilities ☕",
|
||||
"downloads": "13715",
|
||||
"id": 365,
|
||||
"image": "QuoplWIM",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1670314326-bedroom window morning_1.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Some lonely time 🏠",
|
||||
"downloads": "5198",
|
||||
"id": 348,
|
||||
"image": "PWrOiuY6",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1669363297-valleyhousemorning.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "A day in 2100 🚀",
|
||||
"downloads": "9715",
|
||||
"id": 345,
|
||||
"image": "9NXpItYE",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1668758405-futurecitymorning.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "High tides and good vibes 🌊",
|
||||
"downloads": "12170",
|
||||
"id": 342,
|
||||
"image": "taCjkX40",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1668058177-seashoreafternoon.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Cityscape",
|
||||
"description": "Chillin 🐈",
|
||||
"downloads": "8269",
|
||||
"id": 337,
|
||||
"image": "UeEb3FBc",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1667803973-petcatday.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Minimal",
|
||||
"description": "Day and night 🌙",
|
||||
"downloads": "14361",
|
||||
"id": 336,
|
||||
"image": "ks7oXyil",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1667803843-day.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Weekend chills ⛺",
|
||||
"downloads": "8855",
|
||||
"id": 331,
|
||||
"image": "6mPApV97",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1667365369-campfiremorning.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Desert tells a different story every time 🏜",
|
||||
"downloads": "7561",
|
||||
"id": 330,
|
||||
"image": "7ZdHCDhS",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1667205037-desertafternoon.png",
|
||||
"wallpapertype": 1
|
||||
},
|
||||
{
|
||||
"category": "Landscape",
|
||||
"description": "Go green 🍃",
|
||||
"downloads": "11106",
|
||||
"id": 325,
|
||||
"image": "B8azYSqQ",
|
||||
"pro": 99,
|
||||
"resolution": "2160 x 3840",
|
||||
"thumbnail": "1666766444-windmill morning.png",
|
||||
"wallpapertype": 1
|
||||
}
|
||||
]
|
||||
4866
app/src/main/assets/Explore.json
Normal file
1053
app/src/main/assets/Shift.json
Normal file
BIN
app/src/main/assets/font.ttf
Normal file
1441
app/src/main/assets/live_wallpaper.json
Normal file
4831
app/src/main/assets/trending.json
Normal file
78
app/src/main/java/com/live/mylivewallpaper/App.java
Normal file
@ -0,0 +1,78 @@
|
||||
package com.live.mylivewallpaper;
|
||||
|
||||
import android.app.Application;
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.help.Db;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class App extends Application {
|
||||
private static Typeface defaultFont;
|
||||
private static App mApplication;
|
||||
private static String thumbStr = "https://neutrolabgames.com/LiveLoop/CpanelPix/VideoThumb/";
|
||||
|
||||
|
||||
public static String getThumbStr() {
|
||||
return thumbStr;
|
||||
}
|
||||
|
||||
public static App getApplication() {
|
||||
return mApplication;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
mApplication = this;
|
||||
defaultFont = Typeface.createFromAsset(getAssets(), "font.ttf");
|
||||
Db.init(this);
|
||||
loadData();
|
||||
}
|
||||
|
||||
public static Typeface getDefaultFont() {
|
||||
return defaultFont;
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
String name[] = {"trending.json","Explore.json","Shift.json"};
|
||||
ExecutorService cachedThreadPool = Executors.newFixedThreadPool(3);
|
||||
for (int i = 0;i<3;i++){
|
||||
int task = i;
|
||||
cachedThreadPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Common.logMsg("执行任务 "+task+"---开始--"+Thread.currentThread().getName());
|
||||
Gson gson = new Gson();
|
||||
InputStream open = null;
|
||||
try {
|
||||
open = getAssets().open(name[task]);
|
||||
}catch (Exception e){
|
||||
}
|
||||
if(open == null){
|
||||
return;
|
||||
}
|
||||
Type type = new TypeToken<List<ResultData>>() {
|
||||
}.getType();
|
||||
String covertStr = Common.getCovertStr(open);
|
||||
List<ResultData> data = gson.fromJson(covertStr, type);
|
||||
for (ResultData datum : data) {
|
||||
Db.insertDb(datum);
|
||||
}
|
||||
// Common.logMsg("执行任务 "+task+"---完成--"+Thread.currentThread().getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.live.mylivewallpaper.activity;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.tabs.TabLayout;
|
||||
import com.google.android.material.tabs.TabLayoutMediator;
|
||||
import com.live.mylivewallpaper.R;
|
||||
import com.live.mylivewallpaper.adapter.VpAdapter;
|
||||
import com.live.mylivewallpaper.base.BaseActivity;
|
||||
import com.live.mylivewallpaper.databinding.ActivityMainBinding;
|
||||
import com.live.mylivewallpaper.databinding.ItemTabBinding;
|
||||
import com.live.mylivewallpaper.fragment.LikeFragment;
|
||||
import com.live.mylivewallpaper.fragment.MainFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MainActivity extends BaseActivity<ActivityMainBinding> {
|
||||
|
||||
|
||||
@Override
|
||||
protected ActivityMainBinding getViewBinding() {
|
||||
return ActivityMainBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreateInit() {
|
||||
|
||||
List<Fragment> fragmentList = new ArrayList<>();
|
||||
fragmentList.add(MainFragment.newInstance(0));
|
||||
fragmentList.add(MainFragment.newInstance(3));
|
||||
fragmentList.add(MainFragment.newInstance(2));
|
||||
fragmentList.add(LikeFragment.newInstance());
|
||||
|
||||
VpAdapter adapter = new VpAdapter(this, fragmentList);
|
||||
vb.vp.setAdapter(adapter);
|
||||
new TabLayoutMediator(vb.tab, vb.vp, new TabLayoutMediator.TabConfigurationStrategy() {
|
||||
@Override
|
||||
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
|
||||
ItemTabBinding inflate = ItemTabBinding.inflate(getLayoutInflater());
|
||||
tab.setCustomView(inflate.getRoot());
|
||||
switch (position) {
|
||||
case 0:
|
||||
inflate.tabTitle.setText(ContextCompat.getString(MainActivity.this, R.string.tab_title_1));
|
||||
inflate.tabIm.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.tab_trending));
|
||||
break;
|
||||
case 1:
|
||||
inflate.tabTitle.setText(ContextCompat.getString(MainActivity.this, R.string.tab_title_2));
|
||||
inflate.tabIm.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.tab_explore));
|
||||
break;
|
||||
case 2:
|
||||
inflate.tabTitle.setText(ContextCompat.getString(MainActivity.this, R.string.tab_title_3));
|
||||
inflate.tabIm.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.tab_shift));
|
||||
break;
|
||||
case 3:
|
||||
inflate.tabTitle.setText(ContextCompat.getString(MainActivity.this, R.string.tab_title_4));
|
||||
inflate.tabIm.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.tab_like));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}).attach();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean statusBarLight() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,304 @@
|
||||
package com.live.mylivewallpaper.activity;
|
||||
|
||||
import static android.provider.Contacts.SettingsColumns.KEY;
|
||||
|
||||
import android.app.WallpaperInfo;
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.CountDownTimer;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.OptIn;
|
||||
import androidx.media3.common.MediaItem;
|
||||
import androidx.media3.common.util.UnstableApi;
|
||||
import androidx.media3.datasource.DefaultDataSourceFactory;
|
||||
import androidx.media3.datasource.DefaultHttpDataSource;
|
||||
import androidx.media3.exoplayer.ExoPlayer;
|
||||
|
||||
import com.live.mylivewallpaper.base.BaseActivity;
|
||||
import com.live.mylivewallpaper.data.LikeData;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.databinding.ActivityVideoBinding;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.help.Db;
|
||||
import com.live.mylivewallpaper.help.LiveWallpaperService;
|
||||
import com.live.mylivewallpaper.help.Shared;
|
||||
import com.live.mylivewallpaper.listener.OnVideoResultListener;
|
||||
import com.live.mylivewallpaper.request.RetrofitManager;
|
||||
|
||||
import java.io.File;
|
||||
import androidx.media3.exoplayer.SimpleExoPlayer;
|
||||
import androidx.media3.exoplayer.source.MediaSource;
|
||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource;
|
||||
|
||||
public class VideoActivity extends BaseActivity<ActivityVideoBinding> implements SurfaceHolder.Callback {
|
||||
|
||||
|
||||
private CountDownTimer countDownTimer;
|
||||
|
||||
private long time = 5000;
|
||||
|
||||
private SurfaceHolder mySurfaceHolder;
|
||||
private String filePath;
|
||||
private File mFile;
|
||||
|
||||
private boolean download = false;
|
||||
|
||||
private SimpleExoPlayer exoPlayer;
|
||||
|
||||
|
||||
private int id;
|
||||
private String image;
|
||||
private String describe;
|
||||
private String thumb;
|
||||
private int wallpaperType;
|
||||
|
||||
public static String KEY_ID = "ID";
|
||||
public static String KEY_image = "image";
|
||||
public static String KEY_describe = "describe";
|
||||
public static String KEY_wallpaperType = "wallpaperType";
|
||||
public static String KEY_thumb = "thumb";
|
||||
|
||||
@Override
|
||||
protected ActivityVideoBinding getViewBinding() {
|
||||
return ActivityVideoBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreateInit() {
|
||||
Intent intent = getIntent();
|
||||
id = intent.getIntExtra(KEY_ID, -1);
|
||||
wallpaperType = intent.getIntExtra(KEY_wallpaperType, -1);
|
||||
image = intent.getStringExtra(KEY_image);
|
||||
describe = intent.getStringExtra(KEY_image);
|
||||
thumb = intent.getStringExtra(KEY_thumb);
|
||||
|
||||
showLoading(true);
|
||||
initFavorite();
|
||||
filePath = Common.getCachePath(id);
|
||||
mFile = new File(filePath);
|
||||
initExoPlay();
|
||||
|
||||
if (mFile.exists()) {
|
||||
showLoading(false);
|
||||
download = true;
|
||||
checkPlay();
|
||||
return;
|
||||
}
|
||||
RetrofitManager.getInstance().getMp4(id, image, filePath, new OnVideoResultListener() {
|
||||
@Override
|
||||
public void onVideoResult(boolean success, String path) {
|
||||
|
||||
Common.logMsg("-------------success ="+success+"--path="+path);
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showLoading(false);
|
||||
if (success) {
|
||||
download = true;
|
||||
checkPlay();
|
||||
} else {
|
||||
Common.logMsg("-------------loading fail");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void initFavorite(){
|
||||
boolean b = Db.queryIsLike(id);
|
||||
vb.imFavorite.setSelected(b);
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void initExoPlay() {
|
||||
exoPlayer = new SimpleExoPlayer.Builder(this)
|
||||
.build();
|
||||
exoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ONE);
|
||||
vb.playerView.setPlayer(exoPlayer);
|
||||
}
|
||||
|
||||
|
||||
private void checkPlay() {
|
||||
|
||||
if (download) {
|
||||
playMedia3();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void showLoading(boolean loading) {
|
||||
if (loading) {
|
||||
// vb.topLayout.setBackgroundColor(getColor(R.color.color_white_80));
|
||||
vb.relativeLoading.setVisibility(View.VISIBLE);
|
||||
countDownTimer = new CountDownTimer(time, 100L) {
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
float v = 100 - (float) millisUntilFinished / time * 100;
|
||||
int v1 = (int) v;
|
||||
vb.progress.setProgress(v1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
|
||||
}
|
||||
};
|
||||
countDownTimer.start();
|
||||
} else {
|
||||
vb.progress.setProgress(100);
|
||||
// vb.topLayout.setBackgroundColor(getColor(R.color.transparent));
|
||||
vb.relativeLoading.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitClick() {
|
||||
vb.layoutFavorite.setOnClickListener(this);
|
||||
vb.layoutSet.setOnClickListener(this);
|
||||
vb.layoutBack.setOnClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullScreen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean statusBarLight() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.equals(vb.layoutFavorite)) {
|
||||
vb.imFavorite.setSelected(!vb.imFavorite.isSelected());
|
||||
boolean selected = vb.imFavorite.isSelected();
|
||||
if (selected) {
|
||||
LikeData likeData = new LikeData(describe, id, image, wallpaperType,thumb);
|
||||
Db.insertLike(likeData);
|
||||
} else {
|
||||
Db.deleteLike(id);
|
||||
}
|
||||
} else if (v.equals(vb.layoutSet)) {
|
||||
setLiveWallpaper();
|
||||
} else if (v.equals(vb.layoutBack)) {
|
||||
finish();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (exoPlayer != null) {
|
||||
exoPlayer.release();
|
||||
}
|
||||
Common.logMsg("-----Video-------onDestroy");
|
||||
if (countDownTimer != null) {
|
||||
countDownTimer.cancel();
|
||||
countDownTimer = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
||||
Common.logMsg("------------surfaceCreated");
|
||||
mySurfaceHolder = holder;
|
||||
checkPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
|
||||
Common.logMsg("------------surfaceChanged");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
||||
Common.logMsg("------------surfaceDestroyed");
|
||||
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
private void playMedia3() {
|
||||
try {
|
||||
Uri uriFromFilePath = Common.getUriFromFilePath(this, filePath);
|
||||
MediaItem mediaItem = MediaItem.fromUri(uriFromFilePath);
|
||||
ProgressiveMediaSource mediaSource = createMediaSource(mediaItem);
|
||||
exoPlayer.setMediaSource(mediaSource);
|
||||
exoPlayer.prepare();
|
||||
exoPlayer.play();
|
||||
}catch (Exception e){
|
||||
Common.logMsg("-------"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(markerClass = UnstableApi.class)
|
||||
public ProgressiveMediaSource createMediaSource(MediaItem mediaItem) {
|
||||
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(
|
||||
this, "user-agent"
|
||||
);
|
||||
ProgressiveMediaSource.Factory factory = new ProgressiveMediaSource.Factory(dataSourceFactory);
|
||||
return factory.createMediaSource(mediaItem);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void setLiveWallpaper() {
|
||||
if (mFile.exists()) {
|
||||
Shared.INSTANCE.setVideo_path(filePath);
|
||||
Common.logMsg("----------setVideo_path---filePath=" + filePath);
|
||||
}
|
||||
|
||||
WallpaperManager instance = WallpaperManager.getInstance(VideoActivity.this);
|
||||
|
||||
ComponentName componentName = new ComponentName(VideoActivity.this, LiveWallpaperService.class);
|
||||
WallpaperInfo wallpaperInfo = instance.getWallpaperInfo();
|
||||
|
||||
Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
|
||||
intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, componentName);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
// if((wallpaperInfo!= null)&&wallpaperInfo.getComponent()!= componentName){
|
||||
// Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
|
||||
// intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, componentName);
|
||||
// startActivity(intent);
|
||||
// }else {
|
||||
// Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
|
||||
// intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, componentName);
|
||||
// startActivity(intent);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package com.live.mylivewallpaper.activity;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.view.View;
|
||||
|
||||
import com.live.mylivewallpaper.R;
|
||||
import com.live.mylivewallpaper.base.BaseActivity;
|
||||
import com.live.mylivewallpaper.databinding.ActivityWelcomeBinding;
|
||||
|
||||
public class WelcomeActivity extends BaseActivity<ActivityWelcomeBinding> {
|
||||
|
||||
private static final int SPLASH_TIME_OUT = 2000;
|
||||
private CountDownTimer countDownTimer;
|
||||
|
||||
@Override
|
||||
protected ActivityWelcomeBinding getViewBinding() {
|
||||
return ActivityWelcomeBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreateInit() {
|
||||
|
||||
countDownTimer = new CountDownTimer(SPLASH_TIME_OUT,100) {
|
||||
@Override
|
||||
public void onTick(long l) {
|
||||
float v = 100 - (float) l / SPLASH_TIME_OUT * 100;
|
||||
int v1 = (int) v;
|
||||
vb.progressBar.setProgress(v1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
vb.progressBar.setProgress(100);
|
||||
Intent intent = new Intent(WelcomeActivity.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
};
|
||||
countDownTimer.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitClick() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullScreen() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean statusBarLight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,107 @@
|
||||
package com.live.mylivewallpaper.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.paging.PagingDataAdapter;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
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.live.mylivewallpaper.App;
|
||||
import com.live.mylivewallpaper.R;
|
||||
import com.live.mylivewallpaper.activity.VideoActivity;
|
||||
import com.live.mylivewallpaper.data.LikeData;
|
||||
import com.live.mylivewallpaper.databinding.ItemMainBinding;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.viewholder.MainViewHolder;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class LikeAdapter extends PagingDataAdapter<LikeData, MainViewHolder<ItemMainBinding>> {
|
||||
|
||||
private WeakReference<Context> contextWeakReference;
|
||||
private Context MContext;
|
||||
|
||||
public LikeAdapter(Context context) {
|
||||
super(DIFF_CALLBACK);
|
||||
contextWeakReference = new WeakReference<>(context);
|
||||
MContext = contextWeakReference.get();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MainViewHolder<ItemMainBinding> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
ItemMainBinding inflate = ItemMainBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new MainViewHolder<ItemMainBinding>(inflate);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MainViewHolder<ItemMainBinding> holder, int position) {
|
||||
ItemMainBinding itemVb = holder.getItemVb();
|
||||
LikeData item = getItem(position);
|
||||
|
||||
String thumbStr = App.getThumbStr() + item.getThumbnail();
|
||||
|
||||
Glide.with(MContext)
|
||||
.asDrawable()
|
||||
.load(thumbStr)
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(Common.dpToPx(MContext, 4))))
|
||||
.placeholder(R.mipmap.ic_launcher)
|
||||
.centerCrop()
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
||||
Common.logMsg(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(itemVb.imageThumb);
|
||||
itemVb.imageThumb.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(MContext, VideoActivity.class);
|
||||
intent.putExtra(VideoActivity.KEY_ID, item.getId());
|
||||
intent.putExtra(VideoActivity.KEY_wallpaperType, item.getWallpapertype());
|
||||
intent.putExtra(VideoActivity.KEY_image, item.getImage());
|
||||
intent.putExtra(VideoActivity.KEY_describe, item.getDescription());
|
||||
intent.putExtra(VideoActivity.KEY_thumb, item.getThumbnail());
|
||||
MContext.startActivity(intent);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static final DiffUtil.ItemCallback<LikeData> DIFF_CALLBACK = new DiffUtil.ItemCallback<LikeData>() {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull LikeData oldItem, @NonNull LikeData newItem) {
|
||||
return oldItem.getId() == newItem.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull LikeData oldItem, @NonNull LikeData newItem) {
|
||||
return oldItem.getId() == newItem.getId();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,108 @@
|
||||
package com.live.mylivewallpaper.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.paging.PagingDataAdapter;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.DataSource;
|
||||
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.live.mylivewallpaper.App;
|
||||
import com.live.mylivewallpaper.R;
|
||||
import com.live.mylivewallpaper.activity.VideoActivity;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.databinding.ItemMainBinding;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.viewholder.MainViewHolder;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class MainAdapter extends PagingDataAdapter<ResultData, MainViewHolder<ItemMainBinding>> {
|
||||
|
||||
private WeakReference<Context> contextWeakReference;
|
||||
private Context MContext;
|
||||
|
||||
public MainAdapter(Context context) {
|
||||
super(DIFF_CALLBACK);
|
||||
contextWeakReference = new WeakReference<>(context);
|
||||
MContext = contextWeakReference.get();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MainViewHolder<ItemMainBinding> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
ItemMainBinding inflate = ItemMainBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new MainViewHolder<ItemMainBinding>(inflate);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MainViewHolder<ItemMainBinding> holder, int position) {
|
||||
ItemMainBinding itemVb = holder.getItemVb();
|
||||
ResultData item = getItem(position);
|
||||
|
||||
String thumbStr = App.getThumbStr() + item.getThumbnail();
|
||||
|
||||
Glide.with(MContext)
|
||||
.asDrawable()
|
||||
.load(thumbStr)
|
||||
.apply(RequestOptions.bitmapTransform(new RoundedCorners(Common.dpToPx(MContext, 4))))
|
||||
.placeholder(R.mipmap.ic_launcher)
|
||||
.centerCrop()
|
||||
.listener(new RequestListener<Drawable>() {
|
||||
@Override
|
||||
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
|
||||
Common.logMsg(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.into(itemVb.imageThumb);
|
||||
itemVb.imageThumb.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(MContext, VideoActivity.class);
|
||||
intent.putExtra(VideoActivity.KEY_ID, item.getId());
|
||||
intent.putExtra(VideoActivity.KEY_wallpaperType, item.getWallpapertype());
|
||||
intent.putExtra(VideoActivity.KEY_image, item.getImage());
|
||||
intent.putExtra(VideoActivity.KEY_describe, item.getDescription());
|
||||
intent.putExtra(VideoActivity.KEY_thumb, item.getThumbnail());
|
||||
MContext.startActivity(intent);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private static final DiffUtil.ItemCallback<ResultData> DIFF_CALLBACK = new DiffUtil.ItemCallback<ResultData>() {
|
||||
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull ResultData oldItem, @NonNull ResultData newItem) {
|
||||
return oldItem.getId() == newItem.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(@NonNull ResultData oldItem, @NonNull ResultData newItem) {
|
||||
return oldItem.getId() == newItem.getId();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.live.mylivewallpaper.adapter;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VpAdapter extends FragmentStateAdapter {
|
||||
private final List<Fragment> fragmentList;
|
||||
|
||||
public VpAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {
|
||||
super(fragmentActivity);
|
||||
this.fragmentList = fragmentList;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
return fragmentList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return fragmentList.size();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,89 @@
|
||||
package com.live.mylivewallpaper.base;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.live.mylivewallpaper.databinding.ActivityBaseBinding;
|
||||
import com.live.mylivewallpaper.viewmode.VMApplication;
|
||||
import com.live.mylivewallpaper.viewmode.ViewModelScope;
|
||||
|
||||
|
||||
public abstract class BaseActivity<T extends ViewBinding> extends AppCompatActivity implements View.OnClickListener {
|
||||
|
||||
private final ViewModelScope mViewModelScope = new ViewModelScope();
|
||||
|
||||
protected T vb;
|
||||
|
||||
private Window window;
|
||||
private View decorView;
|
||||
protected View mView;
|
||||
private ActivityBaseBinding rootVb;
|
||||
|
||||
protected VMApplication vmApplication;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
vb = getViewBinding();
|
||||
View root = vb.getRoot();
|
||||
rootVb = ActivityBaseBinding.inflate(getLayoutInflater(), null, false);
|
||||
rootVb.frameLayout.addView(root);
|
||||
setContentView(rootVb.getRoot());
|
||||
window = getWindow();
|
||||
decorView = window.getDecorView();
|
||||
mView = decorView.getRootView();
|
||||
vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
||||
|
||||
|
||||
setStatusBar();
|
||||
if (isFullScreen()) {
|
||||
initFullScreen();
|
||||
}
|
||||
onCreateInit();
|
||||
onInitClick();
|
||||
}
|
||||
|
||||
protected abstract T getViewBinding();
|
||||
|
||||
|
||||
protected abstract void onCreateInit();
|
||||
|
||||
protected abstract void onInitClick();
|
||||
|
||||
public abstract boolean isFullScreen();
|
||||
|
||||
public abstract boolean statusBarLight();
|
||||
|
||||
|
||||
private void setStatusBar() {
|
||||
//深色模式
|
||||
WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(getWindow(), getWindow().getDecorView());
|
||||
insetsController.setAppearanceLightStatusBars(statusBarLight());
|
||||
}
|
||||
|
||||
private void initFullScreen() {
|
||||
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
// mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
mView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
|
||||
protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
|
||||
return mViewModelScope.getActivityScopeViewModel(this, modelClass);
|
||||
}
|
||||
|
||||
protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
|
||||
return mViewModelScope.getApplicationScopeViewModel(modelClass);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
package com.live.mylivewallpaper.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.live.mylivewallpaper.viewmode.VMApplication;
|
||||
import com.live.mylivewallpaper.viewmode.ViewModelScope;
|
||||
|
||||
|
||||
public abstract class BaseFragment<T extends ViewBinding> extends Fragment {
|
||||
private final ViewModelScope mViewModelScope = new ViewModelScope();
|
||||
protected T Vb;
|
||||
|
||||
protected AppCompatActivity mActivity;
|
||||
protected VMApplication vmApplication;
|
||||
public BaseFragment() {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
mActivity = (AppCompatActivity) context;
|
||||
}
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Vb = getFragmentVb();
|
||||
vmApplication = getApplicationScopeViewModel(VMApplication.class);
|
||||
initView();
|
||||
return Vb.getRoot();
|
||||
}
|
||||
|
||||
protected abstract T getFragmentVb();
|
||||
protected abstract void initView();
|
||||
|
||||
protected <K extends ViewModel> K getFragmentScopeViewModel(@NonNull Class<K> modelClass) {
|
||||
return mViewModelScope.getFragmentScopeViewModel(this, modelClass);
|
||||
}
|
||||
protected <K extends ViewModel> K getActivityScopeViewModel(@NonNull Class<K> modelClass) {
|
||||
return mViewModelScope.getActivityScopeViewModel(mActivity, modelClass);
|
||||
}
|
||||
|
||||
protected <K extends ViewModel> K getApplicationScopeViewModel(@NonNull Class<K> modelClass) {
|
||||
return mViewModelScope.getApplicationScopeViewModel(modelClass);
|
||||
}
|
||||
}
|
||||
100
app/src/main/java/com/live/mylivewallpaper/data/LikeData.java
Normal file
@ -0,0 +1,100 @@
|
||||
package com.live.mylivewallpaper.data;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.objectbox.annotation.Entity;
|
||||
import io.objectbox.annotation.Id;
|
||||
|
||||
|
||||
@Entity
|
||||
public class LikeData implements Serializable {
|
||||
|
||||
@Id
|
||||
private long objectId;
|
||||
|
||||
|
||||
private String description;
|
||||
|
||||
private int id;
|
||||
private String image;
|
||||
|
||||
|
||||
//0 :trending 1:dnamic 2:shift 3:explore
|
||||
private int wallpapertype;
|
||||
|
||||
private String thumbnail;
|
||||
|
||||
|
||||
public LikeData(String description, int id, String image, int wallpapertype,String thumbnail) {
|
||||
this.description = description;
|
||||
this.id = id;
|
||||
this.image = image;
|
||||
this.wallpapertype = wallpapertype;
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
|
||||
public LikeData(long objectId, String description, int id, String image, int wallpapertype, String thumbnail) {
|
||||
this.objectId = objectId;
|
||||
this.description = description;
|
||||
this.id = id;
|
||||
this.image = image;
|
||||
this.wallpapertype = wallpapertype;
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getObjectId() {
|
||||
return objectId;
|
||||
}
|
||||
|
||||
public void setObjectId(long objectId) {
|
||||
this.objectId = objectId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
|
||||
public int getWallpapertype() {
|
||||
return wallpapertype;
|
||||
}
|
||||
|
||||
public void setWallpapertype(int wallpapertype) {
|
||||
this.wallpapertype = wallpapertype;
|
||||
}
|
||||
|
||||
|
||||
public String getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public void setThumbnail(String thumbnail) {
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
}
|
||||
108
app/src/main/java/com/live/mylivewallpaper/data/ResultData.java
Normal file
@ -0,0 +1,108 @@
|
||||
package com.live.mylivewallpaper.data;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import io.objectbox.annotation.Entity;
|
||||
import io.objectbox.annotation.Id;
|
||||
|
||||
@Entity
|
||||
public class ResultData implements Serializable {
|
||||
|
||||
@Id
|
||||
private long objectId;
|
||||
|
||||
private String category;
|
||||
private String description;
|
||||
private String downloads;
|
||||
private int id;
|
||||
private String image;
|
||||
private int pro;
|
||||
|
||||
private String resolution;
|
||||
private String thumbnail;
|
||||
|
||||
//0 :trending 1:dnamic 2:shift 3:explore
|
||||
private int wallpapertype;
|
||||
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getObjectId() {
|
||||
return objectId;
|
||||
}
|
||||
|
||||
public void setObjectId(long objectId) {
|
||||
this.objectId = objectId;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDownloads() {
|
||||
return downloads;
|
||||
}
|
||||
|
||||
public void setDownloads(String downloads) {
|
||||
this.downloads = downloads;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public int getPro() {
|
||||
return pro;
|
||||
}
|
||||
|
||||
public void setPro(int pro) {
|
||||
this.pro = pro;
|
||||
}
|
||||
|
||||
public String getResolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
public void setResolution(String resolution) {
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
public String getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public void setThumbnail(String thumbnail) {
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
|
||||
public int getWallpapertype() {
|
||||
return wallpapertype;
|
||||
}
|
||||
|
||||
public void setWallpapertype(int wallpapertype) {
|
||||
this.wallpapertype = wallpapertype;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
package com.live.mylivewallpaper.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.paging.PagingData;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.live.mylivewallpaper.adapter.LikeAdapter;
|
||||
import com.live.mylivewallpaper.adapter.MainAdapter;
|
||||
import com.live.mylivewallpaper.base.BaseFragment;
|
||||
import com.live.mylivewallpaper.data.LikeData;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.databinding.FragmentMainBinding;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.help.Db;
|
||||
import com.live.mylivewallpaper.help.ItemDecoration;
|
||||
import com.live.mylivewallpaper.listener.OnLikeUpdateListener;
|
||||
import com.live.mylivewallpaper.viewmode.VmLikeFragment;
|
||||
|
||||
import io.objectbox.reactive.DataSubscription;
|
||||
|
||||
public class LikeFragment extends BaseFragment<FragmentMainBinding> {
|
||||
private DataSubscription dataSubscription;
|
||||
|
||||
private VmLikeFragment vmLikeFragment;
|
||||
|
||||
public LikeFragment() {
|
||||
|
||||
}
|
||||
|
||||
public static LikeFragment newInstance() {
|
||||
LikeFragment fragment = new LikeFragment();
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected FragmentMainBinding getFragmentVb() {
|
||||
return FragmentMainBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
LikeAdapter likeAdapter = new LikeAdapter(requireContext());
|
||||
Vb.recycler.setAdapter(likeAdapter);
|
||||
Vb.recycler.setLayoutManager(new GridLayoutManager(requireContext(), 2, RecyclerView.VERTICAL, false));
|
||||
Vb.recycler.addItemDecoration(new ItemDecoration(requireContext(), 5, 5, 0));
|
||||
vmLikeFragment = getFragmentScopeViewModel(VmLikeFragment.class);
|
||||
vmLikeFragment.getPagingData().observe(getViewLifecycleOwner(), resultDataPagingData -> {
|
||||
Common.logMsg("---onChanged-------------");
|
||||
likeAdapter.submitData(requireActivity().getLifecycle(), resultDataPagingData);
|
||||
});
|
||||
dataSubscription = Db.setLikeUpdateListener(new OnLikeUpdateListener() {
|
||||
@Override
|
||||
public void onLikeUpdate() {
|
||||
vmLikeFragment.getPagingData().observe(getViewLifecycleOwner(), resultDataPagingData -> {
|
||||
Common.logMsg("---onChanged-2------------");
|
||||
likeAdapter.submitData(requireActivity().getLifecycle(), resultDataPagingData);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
if (dataSubscription != null) {
|
||||
dataSubscription.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package com.live.mylivewallpaper.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.paging.PagingData;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.live.mylivewallpaper.R;
|
||||
import com.live.mylivewallpaper.adapter.MainAdapter;
|
||||
import com.live.mylivewallpaper.base.BaseFragment;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.databinding.FragmentMainBinding;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.help.Db;
|
||||
import com.live.mylivewallpaper.help.ItemDecoration;
|
||||
import com.live.mylivewallpaper.viewmode.VmMainFragment;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MainFragment extends BaseFragment<FragmentMainBinding> {
|
||||
|
||||
|
||||
private static final String ARG_PARAM1 = "param1";
|
||||
|
||||
|
||||
private int wallpaperType;
|
||||
|
||||
private VmMainFragment vmMainFragment;
|
||||
|
||||
public MainFragment() {
|
||||
|
||||
}
|
||||
public static MainFragment newInstance(int type) {
|
||||
MainFragment fragment = new MainFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_PARAM1, type);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
wallpaperType = getArguments().getInt(ARG_PARAM1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected FragmentMainBinding getFragmentVb() {
|
||||
return FragmentMainBinding.inflate(getLayoutInflater());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
MainAdapter mainAdapter = new MainAdapter(requireContext());
|
||||
Vb.recycler.setAdapter(mainAdapter);
|
||||
Vb.recycler.setLayoutManager(new GridLayoutManager(requireContext(),2, RecyclerView.VERTICAL, false));
|
||||
Vb.recycler.addItemDecoration(new ItemDecoration(requireContext(),5,5,0));
|
||||
vmMainFragment = getFragmentScopeViewModel(VmMainFragment.class);
|
||||
vmMainFragment.getPagingData(wallpaperType).observe(getViewLifecycleOwner(), new Observer<PagingData<ResultData>>() {
|
||||
@Override
|
||||
public void onChanged(PagingData<ResultData> resultDataPagingData) {
|
||||
mainAdapter.submitData(requireActivity().getLifecycle(),resultDataPagingData);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
97
app/src/main/java/com/live/mylivewallpaper/help/Common.java
Normal file
@ -0,0 +1,97 @@
|
||||
package com.live.mylivewallpaper.help;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import com.live.mylivewallpaper.App;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class Common {
|
||||
private static String TAG = "=============";
|
||||
|
||||
public static String getCovertStr(InputStream stream) {
|
||||
String covertStr = "";
|
||||
try {
|
||||
StringWriter writer = new StringWriter();
|
||||
char[] buffer = new char[stream.available()];
|
||||
Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
int a = 0;
|
||||
while ((a = reader.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, a);
|
||||
}
|
||||
covertStr = writer.toString();
|
||||
} catch (IOException e) {
|
||||
return covertStr;
|
||||
}
|
||||
return covertStr;
|
||||
}
|
||||
|
||||
public static void logMsg(String msg) {
|
||||
Log.d(TAG, msg);
|
||||
}
|
||||
|
||||
public static int dpToPx(Context context,int dp) {
|
||||
return Math.round(dp * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
|
||||
}
|
||||
|
||||
public static int pxToDp(Context context,int px) {
|
||||
return Math.round(px / (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static boolean writeFile(InputStream input, String filePath) {
|
||||
try {
|
||||
byte[] byteArray = new byte[4096];
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
int bytesRead;
|
||||
while ((bytesRead = input.read(byteArray)) != -1) {
|
||||
output.write(byteArray, 0, bytesRead);
|
||||
}
|
||||
|
||||
File file = new File(filePath);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
|
||||
fileOutputStream.write(output.toByteArray());
|
||||
output.close();
|
||||
fileOutputStream.close();
|
||||
Common.logMsg("-------------onSuccess return true");
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
Log.d("-----------", "---------ex=" + ex.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCachePath(int id){
|
||||
App application = App.getApplication();
|
||||
String s1 = application.getCacheDir() +"/"+ id+".mp4";
|
||||
return s1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static Uri getUriFromFilePath(Context context, String filePath) {
|
||||
File file = new File(filePath);
|
||||
|
||||
// 使用 FileProvider 获取 URI
|
||||
return FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
|
||||
}
|
||||
}
|
||||
189
app/src/main/java/com/live/mylivewallpaper/help/Db.java
Normal file
@ -0,0 +1,189 @@
|
||||
package com.live.mylivewallpaper.help;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.live.mylivewallpaper.data.LikeData;
|
||||
import com.live.mylivewallpaper.data.LikeData_;
|
||||
import com.live.mylivewallpaper.data.MyObjectBox;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.data.ResultData_;
|
||||
import com.live.mylivewallpaper.listener.OnLikeUpdateListener;
|
||||
import com.live.mylivewallpaper.paging.MyLikeSource;
|
||||
import com.live.mylivewallpaper.paging.MyPagingSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.objectbox.Box;
|
||||
import io.objectbox.BoxStore;
|
||||
import io.objectbox.android.AndroidScheduler;
|
||||
import io.objectbox.query.Query;
|
||||
import io.objectbox.reactive.DataObserver;
|
||||
import io.objectbox.reactive.DataSubscription;
|
||||
import io.objectbox.reactive.DataSubscriptionList;
|
||||
|
||||
public class Db {
|
||||
|
||||
private static BoxStore boxStore;
|
||||
|
||||
private static Box<ResultData> dataBox;
|
||||
private static Box<LikeData> likeBox;
|
||||
|
||||
private static DataSubscription observer;
|
||||
|
||||
|
||||
public static void init(Context context) {
|
||||
boxStore = MyObjectBox.builder().androidContext(context).build();
|
||||
}
|
||||
|
||||
public static Box<ResultData> getDataBox() {
|
||||
if (dataBox == null) {
|
||||
dataBox = boxStore.boxFor(ResultData.class);
|
||||
}
|
||||
|
||||
return dataBox;
|
||||
}
|
||||
|
||||
public static Box<LikeData> getLikeBox() {
|
||||
if (likeBox == null) {
|
||||
likeBox = boxStore.boxFor(LikeData.class);
|
||||
}
|
||||
|
||||
return likeBox;
|
||||
}
|
||||
|
||||
public static DataSubscription setLikeUpdateListener(OnLikeUpdateListener listener) {
|
||||
Box<LikeData> likeBox = getLikeBox();
|
||||
Query<LikeData> build = likeBox.query()
|
||||
.build();
|
||||
return build.subscribe(new DataSubscriptionList())
|
||||
.on(AndroidScheduler.mainThread())
|
||||
.observer(new DataObserver<List<LikeData>>() {
|
||||
@Override
|
||||
public void onData(@NonNull List<LikeData> data) {
|
||||
Common.logMsg("---OnLikeUpdateListener-------------" + data.size());
|
||||
listener.onLikeUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void insertDb(ResultData resultData) {
|
||||
Box<ResultData> objectBox = getDataBox();
|
||||
ResultData first = objectBox.query()
|
||||
.equal(ResultData_.wallpapertype, resultData.getWallpapertype())
|
||||
.equal(ResultData_.id, resultData.getId())
|
||||
.build()
|
||||
.findFirst();
|
||||
if (first == null) {
|
||||
// Common.logMsg("---insertDb------Wallpapertype------" + resultData.getWallpapertype() + "-------id=" + resultData.getId());
|
||||
objectBox.put(resultData);
|
||||
} else {
|
||||
// Common.logMsg("---insertDb-------------" + resultData.getWallpapertype() + "-------id=" + resultData.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void insertLike(LikeData likeData) {
|
||||
Box<LikeData> likeBox = getLikeBox();
|
||||
LikeData first = likeBox.query()
|
||||
.equal(LikeData_.id, likeData.getId())
|
||||
.build()
|
||||
.findFirst();
|
||||
if (first == null) {
|
||||
Common.logMsg("---insertLike-----------------id=" + likeData.getId());
|
||||
likeBox.put(likeData);
|
||||
} else {
|
||||
Common.logMsg("---insertLike-----------------id=" + likeData.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void deleteLike(int id) {
|
||||
Box<LikeData> likeBox = getLikeBox();
|
||||
LikeData first = likeBox.query()
|
||||
.equal(LikeData_.id, id)
|
||||
.build()
|
||||
.findFirst();
|
||||
if (first != null) {
|
||||
likeBox.remove(first);
|
||||
Common.logMsg("---deleteLike-----------------id=" + id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// public static void deleteDownload(Data downloadData) {
|
||||
// Box<Data> objectBoxLike = getObjectBox();
|
||||
// String imId = downloadData.getImId();
|
||||
// Data boxLike = objectBoxLike.query()
|
||||
// .equal(Data_.imId, imId, QueryBuilder.StringOrder.CASE_SENSITIVE)
|
||||
// .build()
|
||||
// .findFirst();
|
||||
// if (boxLike != null) {
|
||||
// if (boxLike.isLike()) {
|
||||
// boxLike.setDownload(false);
|
||||
// objectBoxLike.put(boxLike);
|
||||
// } else {
|
||||
// objectBoxLike.remove(boxLike);
|
||||
// }
|
||||
// Log.d(MyWallpaper.TAG, "--------deleteDownload imId=" + imId);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
public static boolean queryIsLike(int id) {
|
||||
Box<LikeData> likeBox = getLikeBox();
|
||||
LikeData first = likeBox.query()
|
||||
.equal(LikeData_.id, id)
|
||||
.build()
|
||||
.findFirst();
|
||||
if (first != null) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public static List<LikeData> queryAllLike() {
|
||||
Box<LikeData> likeBox = getLikeBox();
|
||||
return likeBox.query()
|
||||
.build()
|
||||
.find();
|
||||
}
|
||||
|
||||
public static List<ResultData> queryData(int wallpaperType, int currentPage) {
|
||||
int offset = (currentPage - 1) * MyPagingSource.pageSize;
|
||||
|
||||
Box<ResultData> objectBoxLike = getDataBox();
|
||||
List<ResultData> data = objectBoxLike.query()
|
||||
.equal(ResultData_.wallpapertype, wallpaperType)
|
||||
.build()
|
||||
.find(offset, MyPagingSource.pageSize);
|
||||
|
||||
return data;
|
||||
}
|
||||
public static List<LikeData> queryLike( int currentPage) {
|
||||
int offset = (currentPage - 1) * MyLikeSource.pageSize;
|
||||
Box<LikeData> likeBox = getLikeBox();
|
||||
List<LikeData> data = likeBox.query()
|
||||
.build()
|
||||
.find(offset, MyLikeSource.pageSize);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static List<ResultData> queryAllData(int wallpaperType) {
|
||||
Box<ResultData> objectBoxLike = getDataBox();
|
||||
List<ResultData> data = objectBoxLike.query()
|
||||
.equal(ResultData_.wallpapertype, wallpaperType)
|
||||
.build()
|
||||
.find();
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.live.mylivewallpaper.help;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||
|
||||
|
||||
|
||||
public class ItemDecoration extends RecyclerView.ItemDecoration {
|
||||
|
||||
private int v, h, ex;
|
||||
|
||||
public ItemDecoration(Context context,int v, int h, int ex) {
|
||||
this.v = Math.round(Common.dpToPx(context,v));
|
||||
this.h = Math.round(Common.dpToPx(context,h));
|
||||
this.ex = Math.round(Common.dpToPx(context,ex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
super.getItemOffsets(outRect, view, parent, state);
|
||||
int spanCount = 1;
|
||||
int spanSize = 1;
|
||||
int spanIndex = 0;
|
||||
|
||||
int childAdapterPosition = parent.getChildAdapterPosition(view);
|
||||
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
|
||||
if (layoutManager instanceof StaggeredGridLayoutManager) {
|
||||
StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
|
||||
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
|
||||
spanCount = staggeredGridLayoutManager.getSpanCount();
|
||||
if (layoutParams.isFullSpan()) {
|
||||
spanSize = spanCount;
|
||||
}
|
||||
spanIndex = layoutParams.getSpanIndex();
|
||||
} else if (layoutManager instanceof GridLayoutManager) {
|
||||
GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
|
||||
GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams();
|
||||
spanCount = gridLayoutManager.getSpanCount();
|
||||
spanSize = gridLayoutManager.getSpanSizeLookup().getSpanSize(childAdapterPosition);
|
||||
spanIndex = layoutParams.getSpanIndex();
|
||||
} else if (layoutManager instanceof LinearLayoutManager) {
|
||||
outRect.left = v;
|
||||
outRect.right = v;
|
||||
outRect.bottom = h;
|
||||
}
|
||||
|
||||
if (spanSize == spanCount) {
|
||||
outRect.left = v + ex;
|
||||
outRect.right = v + ex;
|
||||
outRect.bottom = h;
|
||||
|
||||
} else {
|
||||
int itemAllSpacing = (v * (spanCount + 1) + ex * 2) / spanCount;
|
||||
int left = v * (spanIndex + 1) - itemAllSpacing * spanIndex + ex;
|
||||
int right = itemAllSpacing - left;
|
||||
outRect.left = left;
|
||||
outRect.right = right;
|
||||
outRect.bottom = h;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,129 @@
|
||||
package com.live.mylivewallpaper.help
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.service.wallpaper.WallpaperService
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceHolder
|
||||
import androidx.annotation.OptIn
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.datasource.DefaultDataSourceFactory
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.exoplayer.source.ProgressiveMediaSource
|
||||
import com.live.mylivewallpaper.R
|
||||
import java.io.File
|
||||
|
||||
|
||||
class LiveWallpaperService : WallpaperService() {
|
||||
|
||||
|
||||
override fun onCreateEngine(): Engine {
|
||||
return VideoWallpaperEngine()
|
||||
}
|
||||
|
||||
inner class VideoWallpaperEngine : Engine() {
|
||||
private var exoPlayer: ExoPlayer? = null
|
||||
|
||||
@OptIn(UnstableApi::class)
|
||||
private fun initExoPlay() {
|
||||
exoPlayer = ExoPlayer.Builder(this@LiveWallpaperService).build()
|
||||
exoPlayer?.repeatMode = ExoPlayer.REPEAT_MODE_ONE
|
||||
val uri = getVideoUrl(this@LiveWallpaperService)
|
||||
// val test = "android.resource://" + packageName + "/" + R.raw.test1
|
||||
if (uri != null) {
|
||||
val fromUri = MediaItem.fromUri(uri)
|
||||
val mediaSource = ProgressiveMediaSource.Factory(
|
||||
DefaultDataSourceFactory(this@LiveWallpaperService, "user-agent")
|
||||
).createMediaSource(fromUri)
|
||||
exoPlayer?.setMediaSource(mediaSource)
|
||||
exoPlayer?.prepare()
|
||||
exoPlayer?.playWhenReady = true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onCreate(surfaceHolder: SurfaceHolder?) {
|
||||
super.onCreate(surfaceHolder)
|
||||
Common.logMsg("-----Engine-----onCreate")
|
||||
initExoPlay()
|
||||
}
|
||||
|
||||
override fun onSurfaceCreated(holder: SurfaceHolder?) {
|
||||
super.onSurfaceCreated(holder)
|
||||
val surface = holder?.surface
|
||||
if (surface != null) {
|
||||
exoPlayer?.setVideoSurface(surface)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onVisibilityChanged(visible: Boolean) {
|
||||
super.onVisibilityChanged(visible)
|
||||
Common.logMsg("-------Engine---onVisibilityChanged visible=$visible")
|
||||
if (visible) {
|
||||
exoPlayer?.play()
|
||||
} else {
|
||||
exoPlayer?.pause()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onSurfaceDestroyed(holder: SurfaceHolder?) {
|
||||
super.onSurfaceDestroyed(holder)
|
||||
Common.logMsg("------Engine----onSurfaceDestroyed---")
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Common.logMsg("-------Engine---onDestroy---")
|
||||
exoPlayer?.release()
|
||||
|
||||
}
|
||||
|
||||
override fun onSurfaceChanged(
|
||||
holder: SurfaceHolder?,
|
||||
format: Int,
|
||||
width: Int,
|
||||
height: Int
|
||||
) {
|
||||
super.onSurfaceChanged(holder, format, width, height)
|
||||
Common.logMsg("----------Engine---onSurfaceChanged")
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private fun adjustSurfaceViewSize(surface: Surface, containerWidth: Int, containerHeight: Int) {
|
||||
val videoWidth = 1920 // 假设视频宽度为 1920
|
||||
val videoHeight = 1080 // 假设视频高度为 1080
|
||||
|
||||
// 计算视频的宽高比
|
||||
val videoAspectRatio = videoWidth.toFloat() / videoHeight
|
||||
var newWidth = containerWidth
|
||||
var newHeight = (containerWidth / videoAspectRatio).toInt()
|
||||
|
||||
// 如果计算的高度大于容器高度,则调整为容器高度
|
||||
if (newHeight > containerHeight) {
|
||||
newHeight = containerHeight
|
||||
newWidth = (containerHeight * videoAspectRatio).toInt()
|
||||
}
|
||||
|
||||
// 更新 SurfaceView 的布局参数
|
||||
// this.setLayoutParams(FrameLayout.LayoutParams(newWidth, newHeight))
|
||||
}
|
||||
|
||||
private fun getVideoUrl(con: Context): Uri? {
|
||||
|
||||
val file = File(Shared.video_path)
|
||||
val uri = if (file.isFile && file.exists()) {
|
||||
Common.getUriFromFilePath(con, Shared.video_path)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
return uri
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
package com.live.mylivewallpaper.help;
|
||||
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.live.mylivewallpaper.App;
|
||||
import com.live.mylivewallpaper.R;
|
||||
|
||||
|
||||
public class MyTextView extends androidx.appcompat.widget.AppCompatTextView {
|
||||
|
||||
|
||||
public MyTextView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initAttrs(context,attrs);
|
||||
}
|
||||
|
||||
|
||||
private void initAttrs(Context context, AttributeSet attrs){
|
||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
|
||||
boolean aBoolean = typedArray.getBoolean(R.styleable.MyTextView_apply_font,false);
|
||||
if(aBoolean){
|
||||
setTypeface(App.getDefaultFont());
|
||||
}
|
||||
|
||||
typedArray.recycle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
45
app/src/main/java/com/live/mylivewallpaper/help/Shared.kt
Normal file
@ -0,0 +1,45 @@
|
||||
package com.live.mylivewallpaper.help
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.live.mylivewallpaper.App
|
||||
|
||||
object Shared {
|
||||
|
||||
val KEY_CURRENT_WAPPPAPER_PATH = "wallpaper_path"
|
||||
|
||||
private var shared: SharedPreferences? = null
|
||||
|
||||
var video_path: String
|
||||
get() = queryString(
|
||||
KEY_CURRENT_WAPPPAPER_PATH,
|
||||
""
|
||||
)
|
||||
set(value) {
|
||||
saveString(KEY_CURRENT_WAPPPAPER_PATH, value)
|
||||
}
|
||||
|
||||
|
||||
private fun getShared(): SharedPreferences {
|
||||
if (shared == null) {
|
||||
shared = App.getApplication().getSharedPreferences("", Context.MODE_PRIVATE)
|
||||
}
|
||||
return shared!!
|
||||
|
||||
}
|
||||
|
||||
|
||||
private const val defaultFile = "chat_mate"
|
||||
|
||||
|
||||
fun saveString(key: String, value: String) {
|
||||
getShared().edit()
|
||||
.putString(key, value).apply()
|
||||
}
|
||||
|
||||
fun queryString(key: String, defaultValue: String): String {
|
||||
return getShared()
|
||||
.getString(key, defaultValue).orEmpty()
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.live.mylivewallpaper.help;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.VideoView;
|
||||
|
||||
public class fullVideoView extends VideoView {
|
||||
|
||||
public fullVideoView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public fullVideoView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public fullVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public fullVideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
//这里可以看到是将其设为0,不走其他的逻辑。可以去看源码原生逻辑,是还有判断的。
|
||||
int width = getDefaultSize(0, widthMeasureSpec);
|
||||
int height = getDefaultSize(0, heightMeasureSpec);
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.live.mylivewallpaper.listener;
|
||||
|
||||
public interface OnLikeUpdateListener {
|
||||
void onLikeUpdate();
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.live.mylivewallpaper.listener;
|
||||
|
||||
public interface OnVideoResultListener {
|
||||
void onVideoResult(boolean success,String path);
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.live.mylivewallpaper.paging;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.paging.PagingSource;
|
||||
import androidx.paging.PagingState;
|
||||
|
||||
import com.live.mylivewallpaper.data.LikeData;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.help.Db;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import kotlin.coroutines.Continuation;
|
||||
|
||||
public class MyLikeSource extends PagingSource<Integer, LikeData> {
|
||||
public static int pageSize = 10;
|
||||
|
||||
|
||||
public MyLikeSource() {
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer getRefreshKey(@NonNull PagingState<Integer, LikeData> pagingState) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object load(@NonNull LoadParams<Integer> loadParams, @NonNull Continuation<? super LoadResult<Integer, LikeData>> continuation) {
|
||||
|
||||
try {
|
||||
int page = loadParams.getKey() != null ? loadParams.getKey() : 1;
|
||||
|
||||
List<LikeData> data = Db.queryLike(page);
|
||||
Common.logMsg("-----loadLIke---------page="+page+"'--data="+data.size());
|
||||
return new LoadResult.Page<>(
|
||||
data,
|
||||
page > 1 ? page - 1 : null,
|
||||
data.isEmpty() ? null : page + 1
|
||||
);
|
||||
} catch (Exception e) {
|
||||
return new LoadResult.Error<>(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
package com.live.mylivewallpaper.paging;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.paging.PagingSource;
|
||||
import androidx.paging.PagingState;
|
||||
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.help.Db;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import kotlin.coroutines.Continuation;
|
||||
|
||||
public class MyPagingSource extends PagingSource<Integer, ResultData> {
|
||||
public static int pageSize = 10;
|
||||
private int wallpaperType;
|
||||
|
||||
public MyPagingSource(int wallpaperType) {
|
||||
this.wallpaperType = wallpaperType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer getRefreshKey(@NonNull PagingState<Integer, ResultData> pagingState) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object load(@NonNull LoadParams<Integer> loadParams, @NonNull Continuation<? super LoadResult<Integer, ResultData>> continuation) {
|
||||
|
||||
try {
|
||||
int page = loadParams.getKey() != null ? loadParams.getKey() : 1;
|
||||
|
||||
List<ResultData> data = Db.queryData(wallpaperType,page);
|
||||
Common.logMsg("-----load---------"+wallpaperType+"----page="+page+"'--data="+data.size());
|
||||
return new LoadResult.Page<>(
|
||||
data,
|
||||
page > 1 ? page - 1 : null,
|
||||
data.isEmpty() ? null : page + 1
|
||||
);
|
||||
} catch (Exception e) {
|
||||
return new LoadResult.Error<>(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package com.live.mylivewallpaper.request;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.http.Field;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.POST;
|
||||
|
||||
public interface MusicApi {
|
||||
|
||||
|
||||
//首页数据
|
||||
@POST("LiveLoop/AppData/jmywall.php")
|
||||
@FormUrlEncoded
|
||||
Observable<ResponseBody> getMP4(@Field("pi") int pi,
|
||||
@Field("medium") String medium,
|
||||
@Field("alpha") String alpha,
|
||||
@Field("version") String version,
|
||||
@Field("quality") String quality);
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
package com.live.mylivewallpaper.request;
|
||||
import io.reactivex.Observer;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
|
||||
public class ObserverWrapper<T> implements Observer<T> {
|
||||
private OnRequestListener<T> requestListener;
|
||||
|
||||
public ObserverWrapper(OnRequestListener<T> requestListener) {
|
||||
this.requestListener = requestListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(T t) {
|
||||
// String responseBody = (String) t;
|
||||
// ResponseBody responseBody = (ResponseBody) t;
|
||||
// InputStream inputStream = responseBody.byteStream();
|
||||
// Utils.writeFile(inputStream,App.context.getCacheDir()+"/test.mp4");
|
||||
|
||||
|
||||
// JSONObject jsonObject = toJsonObject(responseBody);
|
||||
// try {
|
||||
// if (responseBody != null) {
|
||||
// if (jsonObject.has("playabilityStatus")) {
|
||||
// String status = jsonObject.getJSONObject("playabilityStatus").getString("status");
|
||||
// if (!status.equals("OK")) {
|
||||
// requestListener.onFail("");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
requestListener.onSuccess(t);
|
||||
// }
|
||||
|
||||
// } catch (JSONException e) {
|
||||
// requestListener.onFail(e.getMessage());
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
requestListener.onFail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
package com.live.mylivewallpaper.request;
|
||||
|
||||
public interface OnRequestListener<T> {
|
||||
|
||||
void onFail(String errorMsg);
|
||||
|
||||
void onSuccess(T data) ;
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
package com.live.mylivewallpaper.request;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.help.Common;
|
||||
import com.live.mylivewallpaper.listener.OnVideoResultListener;
|
||||
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||
//import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||
//import retrofit2.converter.gson.GsonConverterFactory;
|
||||
//import retrofit2.converter.scalars.ScalarsConverterFactory;
|
||||
|
||||
public class RetrofitManager {
|
||||
|
||||
private String base_Host = "https://neutrolabgames.com/";
|
||||
|
||||
private static volatile RetrofitManager REQUEST_MANAGER;
|
||||
|
||||
private Retrofit retrofit;
|
||||
public MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
||||
private MusicApi musicApi;
|
||||
|
||||
private List<ResultData> shiftList =new ArrayList<>();
|
||||
|
||||
private List<ResultData> ExploreList =new ArrayList<>();
|
||||
private List<ResultData> TrendingList =new ArrayList<>();
|
||||
private List<ResultData> DnamicList =new ArrayList<>();
|
||||
|
||||
|
||||
private RetrofitManager() {
|
||||
|
||||
musicApi = getRetrofit().create(MusicApi.class);
|
||||
}
|
||||
private synchronized Retrofit getRetrofit() {
|
||||
if (retrofit == null) {
|
||||
long DEFAULT_TIMEOUT = 5;
|
||||
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
|
||||
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
// .addNetworkInterceptor(new GzipInterceptor())
|
||||
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
|
||||
.addInterceptor(httpLoggingInterceptor)
|
||||
.build();
|
||||
retrofit = new Retrofit.Builder()
|
||||
.baseUrl(base_Host)
|
||||
.client(client)
|
||||
// .addConverterFactory(ScalarsConverterFactory.create()) // 支持返回 String 类型
|
||||
// .addConverterFactory(GsonConverterFactory.create())
|
||||
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
|
||||
.build();
|
||||
}
|
||||
return retrofit;
|
||||
}
|
||||
|
||||
public static RetrofitManager getInstance() {
|
||||
if (REQUEST_MANAGER == null) {
|
||||
synchronized (RetrofitManager.class) { //锁,防止线程问题
|
||||
if (REQUEST_MANAGER == null) {
|
||||
REQUEST_MANAGER = new RetrofitManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return REQUEST_MANAGER;
|
||||
}
|
||||
|
||||
|
||||
public void getMp4(int id, String image,String path, OnVideoResultListener listener) {
|
||||
musicApi.getMP4(id,"5eV6snEwfY7Yv6Ub",image,"DL8","ViewLive" )
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe(new ObserverWrapper<>(new OnRequestListener<ResponseBody>() {
|
||||
@Override
|
||||
public void onFail(String errorMsg) {
|
||||
listener.onVideoResult(false,null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(ResponseBody data) {
|
||||
boolean b = Common.writeFile(data.byteStream(), path);
|
||||
listener.onVideoResult(b,path);
|
||||
}
|
||||
|
||||
|
||||
}));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package com.live.mylivewallpaper.viewholder;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
public class MainViewHolder<T extends ViewBinding> extends RecyclerView.ViewHolder {
|
||||
|
||||
private T itemVb;
|
||||
|
||||
public MainViewHolder(@NonNull T itemView) {
|
||||
super(itemView.getRoot());
|
||||
itemVb = itemView;
|
||||
}
|
||||
|
||||
public T getItemVb() {
|
||||
return itemVb;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.live.mylivewallpaper.viewmode;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.ViewModelStore;
|
||||
import androidx.lifecycle.ViewModelStoreOwner;
|
||||
|
||||
public class BaseViewModelStoreOwner implements ViewModelStoreOwner {
|
||||
private final static BaseViewModelStoreOwner sInstance = new BaseViewModelStoreOwner();
|
||||
private ViewModelStore mAppViewModelStore;
|
||||
|
||||
private BaseViewModelStoreOwner() {
|
||||
}
|
||||
|
||||
public static BaseViewModelStoreOwner getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewModelStore getViewModelStore() {
|
||||
if (mAppViewModelStore == null) mAppViewModelStore = new ViewModelStore();
|
||||
return mAppViewModelStore;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.live.mylivewallpaper.viewmode;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
public class VMApplication extends ViewModel {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private MutableLiveData<Integer> _playStatus = new MutableLiveData<Integer>();
|
||||
public LiveData<Integer> playStatus = _playStatus;
|
||||
|
||||
public void setPlayStatus(int status) {
|
||||
_playStatus.setValue(status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.live.mylivewallpaper.viewmode;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
public class ViewModelScope {
|
||||
private ViewModelProvider mFragmentProvider;
|
||||
private ViewModelProvider mActivityProvider;
|
||||
private ViewModelProvider mApplicationProvider;
|
||||
|
||||
public <T extends ViewModel> T getFragmentScopeViewModel(@NonNull Fragment fragment, @NonNull Class<T> modelClass) {
|
||||
if (mFragmentProvider == null) mFragmentProvider = new ViewModelProvider(fragment);
|
||||
return mFragmentProvider.get(modelClass);
|
||||
}
|
||||
|
||||
public <T extends ViewModel> T getActivityScopeViewModel(@NonNull AppCompatActivity activity, @NonNull Class<T> modelClass) {
|
||||
if (mActivityProvider == null) mActivityProvider = new ViewModelProvider(activity);
|
||||
return mActivityProvider.get(modelClass);
|
||||
}
|
||||
|
||||
public <T extends ViewModel> T getApplicationScopeViewModel(@NonNull Class<T> modelClass) {
|
||||
if (mApplicationProvider == null)
|
||||
mApplicationProvider = new ViewModelProvider(BaseViewModelStoreOwner.getInstance());
|
||||
return mApplicationProvider.get(modelClass);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.live.mylivewallpaper.viewmode;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.paging.Pager;
|
||||
import androidx.paging.PagingConfig;
|
||||
import androidx.paging.PagingData;
|
||||
import androidx.paging.PagingLiveData;
|
||||
|
||||
import com.live.mylivewallpaper.data.LikeData;
|
||||
import com.live.mylivewallpaper.paging.MyLikeSource;
|
||||
|
||||
|
||||
public class VmLikeFragment extends ViewModel {
|
||||
|
||||
public Pager<Integer, LikeData> pager;
|
||||
|
||||
|
||||
|
||||
private MutableLiveData<PagingData<LikeData>> _playList = new MutableLiveData<>();
|
||||
public LiveData<PagingData<LikeData>> likeLiveData = _playList ;
|
||||
|
||||
public LiveData<PagingData<LikeData>> getPagingData() {
|
||||
Pager<Integer, LikeData> integerLikeDataPager = new Pager<>(
|
||||
new PagingConfig(10), // 每页加载 20 条数据
|
||||
MyLikeSource::new
|
||||
);
|
||||
|
||||
return PagingLiveData.getLiveData(integerLikeDataPager);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.live.mylivewallpaper.viewmode;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
import androidx.paging.Pager;
|
||||
import androidx.paging.PagingConfig;
|
||||
import androidx.paging.PagingData;
|
||||
import androidx.paging.PagingLiveData;
|
||||
|
||||
import com.live.mylivewallpaper.data.ResultData;
|
||||
import com.live.mylivewallpaper.paging.MyPagingSource;
|
||||
|
||||
|
||||
public class VmMainFragment extends ViewModel {
|
||||
|
||||
public LiveData<PagingData<ResultData>> getPagingData(int wallpaperType) {
|
||||
|
||||
return PagingLiveData.getLiveData(new Pager<>(
|
||||
new PagingConfig(10), // 每页加载 20 条数据
|
||||
() -> new MyPagingSource(wallpaperType)
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
6
app/src/main/res/color/tab_title.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/tab_selected_color" android:state_selected="true"/>
|
||||
<item android:color="@color/tab_normal_color" android:state_selected="false"/>
|
||||
|
||||
</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>
|
||||
7
app/src/main/res/drawable/bg_apply.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="14dp" />
|
||||
<solid android:color="@color/color_white_80" />
|
||||
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/bg_shape_apply.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="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<corners android:radius="16dp" />
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/bg_shape_favorite.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/white" />
|
||||
|
||||
</shape>
|
||||
12
app/src/main/res/drawable/explore.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="M998,348.1l-0,-0.2a109.1,109.1 0,0 0,-3.5 -22.6l-0.2,-0.6a98.9,98.9 0,0 0,-7.6 -19.7c-26.5,-51 -95.8,-74 -188.4,-70.8 -75.7,-82.8 -184.6,-134.7 -305.6,-134.7 -228.8,0 -414.2,185.5 -414.2,414.2 0,30.1 3.3,59.4 9.4,87.7 -51.7,67.2 -75,131.4 -60.6,181.3l-0.1,0c0.1,0.4 0.3,0.8 0.4,1.3 0.7,2.1 1.3,4.2 2.1,6.3 1.3,3.4 2.7,6.8 4.3,10.1 0.1,0.2 0.1,0.4 0.2,0.5 1.6,3.1 3.5,6.1 5.4,9.1 0.5,0.7 1,1.5 1.6,2.2 1.6,2.3 3.4,4.5 5.2,6.7 0.5,0.6 1,1.2 1.5,1.8 2.3,2.6 4.8,5.2 7.4,7.6 0.5,0.4 1,0.9 1.5,1.3a112.9,112.9 0,0 0,9.5 7.6c2.6,1.9 5.2,3.6 8,5.3 0.5,0.3 0.9,0.6 1.4,0.9 3.2,1.9 6.6,3.7 10,5.5 1,0.5 2.1,1 3.1,1.5 2.6,1.2 5.4,2.4 8.1,3.6 1.2,0.5 2.3,1 3.5,1.4 3.7,1.4 7.5,2.8 11.5,4.1l2.5,0.7a222.9,222.9 0,0 0,14.7 3.9c3,0.7 6,1.3 9.2,1.9 1.5,0.3 3,0.6 4.5,0.9 4.3,0.7 8.6,1.4 13.1,2 1.8,0.2 3.6,0.4 5.4,0.6a398.1,398.1 0,0 0,15.5 1.5,387.1 387.1,0 0,0 18.7,0.9c3.6,0.1 7.3,0.1 11,0.1a611.6,611.6 0,0 0,16.4 -0.3c2.7,-0.1 5.3,-0.2 8,-0.3 4.2,-0.2 8.4,-0.5 12.6,-0.8 3.6,-0.3 7.2,-0.6 10.8,-0.9a500.8,500.8 0,0 0,18.1 -1.9l4.2,-0.6a412.2,412.2 0,0 0,215.9 60.7c220.9,0 401.4,-173 413.5,-390.9 3,-3.3 5.9,-6.6 8.7,-9.9l2.6,-3.1a577.1,577.1 0,0 0,12.3 -15.1c2.5,-3.2 5,-6.4 7.4,-9.6 0.9,-1.2 1.8,-2.4 2.7,-3.6 3.2,-4.4 6.3,-8.7 9.3,-13.1l1.3,-2c2.6,-3.8 5,-7.6 7.4,-11.3l2,-3.3c2.4,-3.9 4.7,-7.7 6.8,-11.5l0.8,-1.5c2.5,-4.5 4.9,-9 7.1,-13.4 0.2,-0.4 0.4,-0.8 0.6,-1.2 2,-4 3.8,-8 5.6,-11.9l0.9,-2c3.8,-8.8 6.9,-17.4 9.4,-25.9l0.2,-0.8c1.2,-4 2.2,-8 3.1,-12l0.2,-1c1.8,-8.4 2.9,-16.6 3.3,-24.6l0,-0.6c0.2,-4 0.2,-7.8 -0,-11.6zM492.6,174.5c78.2,0 150.3,26.7 207.7,71.3L700.3,245.8a342.9,342.9 0,0 1,34.5 30.7l0.4,0.4c4.9,5 9.6,10.1 14.1,15.4 0.7,0.8 1.4,1.6 2.1,2.4a337.4,337.4 0,0 1,80.3 212.1v0c-56.9,58.4 -140.3,122.9 -251.3,180.6 -108.3,56.4 -206.9,87.6 -286.3,101.2a340.6,340.6 0,0 1,-123.9 -169.2,337.2 337.2,0 0,1 -11.1,-43.5l-0.4,-1.9a334.9,334.9 0,0 1,-3.1 -21.2l-0.1,-1a336.6,336.6 0,0 1,-1.8 -23.1c-0.2,-5 -0.4,-9.9 -0.4,-14.9 0,-187.1 152.2,-339.3 339.3,-339.3zM189.1,796.9a330,330 0,0 1,-12.8 -0.8l-1.1,-0.1a253.2,253.2 0,0 1,-12.4 -1.3l-0.2,-0a185.5,185.5 0,0 1,-22.5 -4.4l-0.7,-0.2a127.8,127.8 0,0 1,-8.3 -2.5c-0.8,-0.3 -1.6,-0.6 -2.4,-0.9a95.1,95.1 0,0 1,-8.2 -3.5,74.3 74.3,0 0,1 -6.8,-3.8 48.2,48.2 0,0 1,-3.5 -2.5c-0.7,-0.5 -1.4,-1.1 -2.1,-1.6a34.5,34.5 0,0 1,-2.8 -2.8c-0.5,-0.5 -1.1,-1 -1.5,-1.6a27.3,27.3 0,0 1,-2.8 -4.1c-0.1,-0.2 -0.2,-0.3 -0.3,-0.5a28.1,28.1 0,0 1,-2.3 -6.7h-0c-3.6,-15.6 2.9,-39.8 19.6,-69.2a414.7,414.7 0,0 0,72.5 106.4h-0.2c-0.4,0 -0.8,-0 -1.1,-0zM492.6,853.1c-31.6,0 -62.1,-4.4 -91.1,-12.5 68.2,-19.8 140.7,-48.7 213.6,-86.6 74.8,-39 141.8,-83.1 198,-128.9 -46.2,132.6 -172.3,228 -320.5,228zM923.4,360.1a62.1,62.1 0,0 1,-1 7.7c-0.3,1.8 -0.8,3.7 -1.3,5.6 -0.2,0.9 -0.4,1.8 -0.7,2.7 -0.6,2.1 -1.3,4.3 -2.1,6.5 -0.3,0.8 -0.5,1.6 -0.8,2.4 -1,2.7 -2.1,5.6 -3.4,8.4 -0.2,0.4 -0.3,0.7 -0.4,1a224.8,224.8 0,0 1,-10.8 21.3c-0.3,0.5 -0.6,1 -0.9,1.5 -1.5,2.6 -3.1,5.2 -4.7,7.8a411.3,411.3 0,0 0,-43.6 -114.4c29.7,3.5 50.8,11.3 61.3,21.9 1,1 1.9,2 2.8,3.1 0.9,1.2 1.8,2.5 2.5,3.8 0.8,1.6 1.5,3.4 2,5.2 0.1,0.5 0.2,1 0.3,1.5 0.3,1.4 0.6,2.9 0.8,4.5 0.1,0.7 0.1,1.4 0.1,2.1 0.1,1.5 0.1,3 0.1,4.6 -0,0.8 -0.1,1.7 -0.2,2.5z"
|
||||
android:fillColor="@color/tab_normal_color"/>
|
||||
<path
|
||||
android:pathData="M562.2,371.1m-72.7,0a72.7,72.7 0,1 0,145.4 0,72.7 72.7,0 1,0 -145.4,0Z"
|
||||
android:fillColor="@color/tab_normal_color"/>
|
||||
</vector>
|
||||
12
app/src/main/res/drawable/explore_selected.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="M998,348.1l-0,-0.2a109.1,109.1 0,0 0,-3.5 -22.6l-0.2,-0.6a98.9,98.9 0,0 0,-7.6 -19.7c-26.5,-51 -95.8,-74 -188.4,-70.8 -75.7,-82.8 -184.6,-134.7 -305.6,-134.7 -228.8,0 -414.2,185.5 -414.2,414.2 0,30.1 3.3,59.4 9.4,87.7 -51.7,67.2 -75,131.4 -60.6,181.3l-0.1,0c0.1,0.4 0.3,0.8 0.4,1.3 0.7,2.1 1.3,4.2 2.1,6.3 1.3,3.4 2.7,6.8 4.3,10.1 0.1,0.2 0.1,0.4 0.2,0.5 1.6,3.1 3.5,6.1 5.4,9.1 0.5,0.7 1,1.5 1.6,2.2 1.6,2.3 3.4,4.5 5.2,6.7 0.5,0.6 1,1.2 1.5,1.8 2.3,2.6 4.8,5.2 7.4,7.6 0.5,0.4 1,0.9 1.5,1.3a112.9,112.9 0,0 0,9.5 7.6c2.6,1.9 5.2,3.6 8,5.3 0.5,0.3 0.9,0.6 1.4,0.9 3.2,1.9 6.6,3.7 10,5.5 1,0.5 2.1,1 3.1,1.5 2.6,1.2 5.4,2.4 8.1,3.6 1.2,0.5 2.3,1 3.5,1.4 3.7,1.4 7.5,2.8 11.5,4.1l2.5,0.7a222.9,222.9 0,0 0,14.7 3.9c3,0.7 6,1.3 9.2,1.9 1.5,0.3 3,0.6 4.5,0.9 4.3,0.7 8.6,1.4 13.1,2 1.8,0.2 3.6,0.4 5.4,0.6a398.1,398.1 0,0 0,15.5 1.5,387.1 387.1,0 0,0 18.7,0.9c3.6,0.1 7.3,0.1 11,0.1a611.6,611.6 0,0 0,16.4 -0.3c2.7,-0.1 5.3,-0.2 8,-0.3 4.2,-0.2 8.4,-0.5 12.6,-0.8 3.6,-0.3 7.2,-0.6 10.8,-0.9a500.8,500.8 0,0 0,18.1 -1.9l4.2,-0.6a412.2,412.2 0,0 0,215.9 60.7c220.9,0 401.4,-173 413.5,-390.9 3,-3.3 5.9,-6.6 8.7,-9.9l2.6,-3.1a577.1,577.1 0,0 0,12.3 -15.1c2.5,-3.2 5,-6.4 7.4,-9.6 0.9,-1.2 1.8,-2.4 2.7,-3.6 3.2,-4.4 6.3,-8.7 9.3,-13.1l1.3,-2c2.6,-3.8 5,-7.6 7.4,-11.3l2,-3.3c2.4,-3.9 4.7,-7.7 6.8,-11.5l0.8,-1.5c2.5,-4.5 4.9,-9 7.1,-13.4 0.2,-0.4 0.4,-0.8 0.6,-1.2 2,-4 3.8,-8 5.6,-11.9l0.9,-2c3.8,-8.8 6.9,-17.4 9.4,-25.9l0.2,-0.8c1.2,-4 2.2,-8 3.1,-12l0.2,-1c1.8,-8.4 2.9,-16.6 3.3,-24.6l0,-0.6c0.2,-4 0.2,-7.8 -0,-11.6zM492.6,174.5c78.2,0 150.3,26.7 207.7,71.3L700.3,245.8a342.9,342.9 0,0 1,34.5 30.7l0.4,0.4c4.9,5 9.6,10.1 14.1,15.4 0.7,0.8 1.4,1.6 2.1,2.4a337.4,337.4 0,0 1,80.3 212.1v0c-56.9,58.4 -140.3,122.9 -251.3,180.6 -108.3,56.4 -206.9,87.6 -286.3,101.2a340.6,340.6 0,0 1,-123.9 -169.2,337.2 337.2,0 0,1 -11.1,-43.5l-0.4,-1.9a334.9,334.9 0,0 1,-3.1 -21.2l-0.1,-1a336.6,336.6 0,0 1,-1.8 -23.1c-0.2,-5 -0.4,-9.9 -0.4,-14.9 0,-187.1 152.2,-339.3 339.3,-339.3zM189.1,796.9a330,330 0,0 1,-12.8 -0.8l-1.1,-0.1a253.2,253.2 0,0 1,-12.4 -1.3l-0.2,-0a185.5,185.5 0,0 1,-22.5 -4.4l-0.7,-0.2a127.8,127.8 0,0 1,-8.3 -2.5c-0.8,-0.3 -1.6,-0.6 -2.4,-0.9a95.1,95.1 0,0 1,-8.2 -3.5,74.3 74.3,0 0,1 -6.8,-3.8 48.2,48.2 0,0 1,-3.5 -2.5c-0.7,-0.5 -1.4,-1.1 -2.1,-1.6a34.5,34.5 0,0 1,-2.8 -2.8c-0.5,-0.5 -1.1,-1 -1.5,-1.6a27.3,27.3 0,0 1,-2.8 -4.1c-0.1,-0.2 -0.2,-0.3 -0.3,-0.5a28.1,28.1 0,0 1,-2.3 -6.7h-0c-3.6,-15.6 2.9,-39.8 19.6,-69.2a414.7,414.7 0,0 0,72.5 106.4h-0.2c-0.4,0 -0.8,-0 -1.1,-0zM492.6,853.1c-31.6,0 -62.1,-4.4 -91.1,-12.5 68.2,-19.8 140.7,-48.7 213.6,-86.6 74.8,-39 141.8,-83.1 198,-128.9 -46.2,132.6 -172.3,228 -320.5,228zM923.4,360.1a62.1,62.1 0,0 1,-1 7.7c-0.3,1.8 -0.8,3.7 -1.3,5.6 -0.2,0.9 -0.4,1.8 -0.7,2.7 -0.6,2.1 -1.3,4.3 -2.1,6.5 -0.3,0.8 -0.5,1.6 -0.8,2.4 -1,2.7 -2.1,5.6 -3.4,8.4 -0.2,0.4 -0.3,0.7 -0.4,1a224.8,224.8 0,0 1,-10.8 21.3c-0.3,0.5 -0.6,1 -0.9,1.5 -1.5,2.6 -3.1,5.2 -4.7,7.8a411.3,411.3 0,0 0,-43.6 -114.4c29.7,3.5 50.8,11.3 61.3,21.9 1,1 1.9,2 2.8,3.1 0.9,1.2 1.8,2.5 2.5,3.8 0.8,1.6 1.5,3.4 2,5.2 0.1,0.5 0.2,1 0.3,1.5 0.3,1.4 0.6,2.9 0.8,4.5 0.1,0.7 0.1,1.4 0.1,2.1 0.1,1.5 0.1,3 0.1,4.6 -0,0.8 -0.1,1.7 -0.2,2.5z"
|
||||
android:fillColor="@color/tab_selected_color"/>
|
||||
<path
|
||||
android:pathData="M562.2,371.1m-72.7,0a72.7,72.7 0,1 0,145.4 0,72.7 72.7,0 1,0 -145.4,0Z"
|
||||
android:fillColor="@color/tab_selected_color"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/favorite_false.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="M908.8,214.4c-9.6,-12.8 -19.2,-22.4 -28.8,-32 -112,-115.2 -230.4,-105.6 -342.4,-16 -9.6,6.4 -19.2,16 -28.8,25.6 -9.6,-9.6 -19.2,-16 -28.8,-25.6 -112,-86.4 -230.4,-99.2 -342.4,16 -9.6,9.6 -19.2,19.2 -25.6,32 -134.4,195.2 -60.8,387.2 137.6,560 44.8,38.4 89.6,73.6 137.6,102.4 16,9.6 32,19.2 44.8,28.8 9.6,6.4 12.8,9.6 19.2,9.6 3.2,3.2 6.4,3.2 12.8,6.4 3.2,3.2 9.6,3.2 16,6.4 25.6,6.4 64,3.2 89.6,-12.8 3.2,0 9.6,-3.2 16,-9.6 12.8,-6.4 28.8,-16 44.8,-28.8 48,-28.8 92.8,-64 137.6,-102.4 201.6,-176 275.2,-368 140.8,-560zM736,732.8c-41.6,35.2 -86.4,70.4 -131.2,99.2 -16,9.6 -28.8,19.2 -44.8,25.6 -6.4,3.2 -12.8,6.4 -16,9.6 -6.4,3.2 -16,6.4 -25.6,9.6h-28.8s-3.2,0 -3.2,-3.2c-3.2,0 -6.4,-3.2 -9.6,-3.2 -3.2,-3.2 -9.6,-6.4 -16,-9.6 -12.8,-6.4 -28.8,-16 -44.8,-25.6 -44.8,-28.8 -89.6,-60.8 -131.2,-99.2C105.6,576 41.6,412.8 153.6,246.4c6.4,-9.6 16,-16 22.4,-25.6 89.6,-96 182.4,-86.4 275.2,-12.8 9.6,6.4 16,12.8 22.4,19.2l28.8,32 6.4,6.4 16,-16c12.8,-12.8 25.6,-25.6 41.6,-38.4C659.2,137.6 752,128 841.6,224c6.4,9.6 16,16 22.4,25.6 118.4,156.8 54.4,323.2 -128,483.2z"
|
||||
android:fillColor="@color/black"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/favorite_true.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="M910.9,364.8l-1.3,-10.1a237,237 0,0 0,-6.2 -28,201.4 201.4,0 0,0 -42.6,-80 46.1,46.1 0,0 0,-3.8 -4.5,212 212,0 0,0 -160,-71.7c-75.7,0 -146.7,29.8 -185.1,74.1 -38.4,-44.3 -109.6,-74.1 -185.1,-74.1a212,212 0,0 0,-160 71.7,46.1 46.1,0 0,0 -3.8,4.5 201.4,201.4 0,0 0,-42.6 80,237 237,0 0,0 -6.2,28l-1.3,10.1A186.4,186.4 0,0 0,112 385.9a205.3,205.3 0,0 0,1.1 21.3c16,194.1 368,423.2 382.9,433l16,10.4 16,-10.4c15,-9.6 367,-238.7 382.9,-433a205.3,205.3 0,0 0,1.1 -21.3,186.4 186.4,0 0,0 -1.1,-21.1z"
|
||||
android:fillColor="@color/color_red"/>
|
||||
</vector>
|
||||
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/im_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="M395.2,513.6l323.1,-312.4c19.1,-18.4 19.1,-48.3 0,-66.7 -19.1,-18.4 -49.9,-18.4 -69,0L291.8,480.3c-19.1,18.4 -19.1,48.3 0,66.7l357.6,345.7c9.5,9.2 22,13.8 34.5,13.8 12.5,0 25,-4.6 34.5,-13.8 19.1,-18.4 19.1,-48.2 0,-66.7L395.2,513.6z"
|
||||
android:fillColor="@color/black"/>
|
||||
</vector>
|
||||
21
app/src/main/res/drawable/progress_bar_horizontal.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="#D3D3D3" /> <!-- 背景颜色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<corners android:radius="20dp" />
|
||||
<gradient
|
||||
android:startColor="#1CC8EE"
|
||||
android:centerColor="#69FE73"
|
||||
android:endColor="#CBD64B"
|
||||
android:angle="0" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
||||
5
app/src/main/res/drawable/selector_favorite.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true" android:drawable="@drawable/favorite_true"/>
|
||||
<item android:state_selected="false" android:drawable="@drawable/favorite_false"/>
|
||||
</selector>
|
||||
15
app/src/main/res/drawable/shift.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<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="M256,682.7a85.3,85.3 0,1 1,-170.7 0,85.3 85.3,0 0,1 170.7,0zM938.7,682.7a85.3,85.3 0,1 1,-170.7 0,85.3 85.3,0 0,1 170.7,0z"
|
||||
android:fillColor="@color/tab_normal_color"/>
|
||||
<path
|
||||
android:pathData="M512,298.7c-118.2,0 -219.2,74 -259.1,178.3l-7.6,19.9 -39.9,-15.2 7.6,-19.9C259,341.5 375.5,256 512,256c136.5,0 253,85.5 299,205.7l7.6,19.9 -39.9,15.2 -7.6,-19.9C731.2,372.7 630.2,298.7 512,298.7z"
|
||||
android:fillColor="@color/tab_normal_color"/>
|
||||
<path
|
||||
android:pathData="M797.1,277.4l-6.6,188.3 -166.4,-88.4 -20.1,37.7 196.6,104.5A21.3,21.3 0,0 0,832 501.3l7.8,-222.4 -42.6,-1.5z"
|
||||
android:fillColor="@color/tab_normal_color"/>
|
||||
</vector>
|
||||
15
app/src/main/res/drawable/shift_selected.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<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="M256,682.7a85.3,85.3 0,1 1,-170.7 0,85.3 85.3,0 0,1 170.7,0zM938.7,682.7a85.3,85.3 0,1 1,-170.7 0,85.3 85.3,0 0,1 170.7,0z"
|
||||
android:fillColor="@color/tab_selected_color"/>
|
||||
<path
|
||||
android:pathData="M512,298.7c-118.2,0 -219.2,74 -259.1,178.3l-7.6,19.9 -39.9,-15.2 7.6,-19.9C259,341.5 375.5,256 512,256c136.5,0 253,85.5 299,205.7l7.6,19.9 -39.9,15.2 -7.6,-19.9C731.2,372.7 630.2,298.7 512,298.7z"
|
||||
android:fillColor="@color/tab_selected_color"/>
|
||||
<path
|
||||
android:pathData="M797.1,277.4l-6.6,188.3 -166.4,-88.4 -20.1,37.7 196.6,104.5A21.3,21.3 0,0 0,832 501.3l7.8,-222.4 -42.6,-1.5z"
|
||||
android:fillColor="@color/tab_selected_color"/>
|
||||
</vector>
|
||||
6
app/src/main/res/drawable/tab_explore.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/explore" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/explore_selected" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
||||
9
app/src/main/res/drawable/tab_icon_like.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="M512,850.4 L220.1,538.8c-55.7,-60 -82.4,-121.2 -79.4,-182.2 4,-78.9 57.2,-126.9 59.5,-128.9 42.2,-36 87.2,-54.1 134.3,-54.1 81.1,0 146,53.4 177.4,85.4 31.6,-32 96.2,-85.4 177.6,-85.4 47.1,0 92.2,18.1 134.1,53.8 2.6,2.2 55.8,50.2 59.8,129.2 3.1,60.9 -23.7,122.2 -79.4,182.1L512,850.4 512,850.4M233.9,266.6c0,0 -39.4,36.1 -41.8,93.2C190.1,406.3 212.2,454.7 257.8,503.6L512,775l254.3,-271.4c45.4,-49.1 67.7,-97.4 65.5,-143.7 -2.5,-57.2 -41.8,-93.3 -42.3,-93.6 -31.7,-27.2 -65.5,-41.2 -100,-41.2 -86.8,0 -156.5,87.5 -157.2,88.3L511.4,340 491.2,312.9C490.9,312.5 421.7,225.2 334.5,225.2 300,225.2 266.2,239.1 233.9,266.6L233.9,266.6 233.9,266.6M233.9,266.6 L233.9,266.6z"
|
||||
android:fillColor="@color/tab_normal_color"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/tab_icon_like_true.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="M512,850.4 L220.1,538.8c-55.7,-60 -82.4,-121.2 -79.4,-182.2 4,-78.9 57.2,-126.9 59.5,-128.9 42.2,-36 87.2,-54.1 134.3,-54.1 81.1,0 146,53.4 177.4,85.4 31.6,-32 96.2,-85.4 177.6,-85.4 47.1,0 92.2,18.1 134.1,53.8 2.6,2.2 55.8,50.2 59.8,129.2 3.1,60.9 -23.7,122.2 -79.4,182.1L512,850.4 512,850.4M233.9,266.6c0,0 -39.4,36.1 -41.8,93.2C190.1,406.3 212.2,454.7 257.8,503.6L512,775l254.3,-271.4c45.4,-49.1 67.7,-97.4 65.5,-143.7 -2.5,-57.2 -41.8,-93.3 -42.3,-93.6 -31.7,-27.2 -65.5,-41.2 -100,-41.2 -86.8,0 -156.5,87.5 -157.2,88.3L511.4,340 491.2,312.9C490.9,312.5 421.7,225.2 334.5,225.2 300,225.2 266.2,239.1 233.9,266.6L233.9,266.6 233.9,266.6M233.9,266.6 L233.9,266.6z"
|
||||
android:fillColor="@color/tab_selected_color"/>
|
||||
</vector>
|
||||
6
app/src/main/res/drawable/tab_like.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/tab_icon_like" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/tab_icon_like_true" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
||||
6
app/src/main/res/drawable/tab_shift.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/shift" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/shift_selected" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
||||
6
app/src/main/res/drawable/tab_trending.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/trending" android:state_selected="false"/>
|
||||
<item android:drawable="@drawable/trending_selected" android:state_selected="true"/>
|
||||
|
||||
</selector>
|
||||
12
app/src/main/res/drawable/trending.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:fillColor="@color/tab_normal_color"
|
||||
android:pathData="M774.9,545.2c0,-29.2 22.3,-74.3 22.3,-104 0,-38.1 -14.8,-72.7 -50.9,-116.9 7.7,63.7 -34.6,129.6 -80.5,185.7 -5.2,-47.3 38.5,-123.6 38.5,-161.7 0,-98.5 -66.9,-93.9 -66.9,-161.7 0,-42.7 14.7,-68.5 36.7,-122.1 -75.5,31.7 -118.4,110.9 -118.4,164.8 0,9.3 11.2,65 11.2,74.3 0,12.5 -2.4,25.7 -9.1,35.3 -9.7,-21.3 -25.3,-44.4 -44.8,-66.3 -32.5,-36.7 -79.8,-72.6 -79.8,-110.2 0,-25.5 12.3,-66.4 25.3,-94.3 -86.8,58 -136.8,106.8 -136.8,176 0,49.3 63.2,141.2 63.2,165.4 0,9.3 -3.5,27 -9.1,40.9 -9.1,-62.1 -105.3,-121.2 -150.6,-117.8 32.3,38.6 66.7,90.3 66.7,127 0,66.9 -89.2,83.6 -89.2,200.7 0,188.6 170.5,299.1 328.8,299.1 46.5,0 116.6,-11.4 157.1,-35.1 98,-58 153.2,-144.2 153.2,-215.7 0,-76.2 -66.9,-70.1 -66.9,-163.5zM642.1,907.8c-22.3,6.5 -85.1,20 -119.4,20 -148.1,0 -291.7,-118.9 -291.7,-275 0,-75.2 92.9,-128.2 92.9,-184 0,-9.3 -3.7,-33 -6.4,-53.6 34.7,34.3 21.8,80.5 24.8,119.8l6,6.4c41.3,-37.2 68.6,-84.5 68.6,-128.2 0,-67.8 -63.2,-102.7 -63.2,-170.9 0,-29.3 14.9,-60.7 43.4,-90.9 1.2,16.6 0.4,36.9 9.2,49 28.4,39.9 71,77.4 101.6,115 29.7,36.3 22.2,75.1 29.9,110.9 32.5,-58.6 61.1,-73.9 61.1,-128.2 0,-9.3 -11.2,-61.3 -11.2,-70.7 0,-9.3 3.8,-30.2 9.3,-46.4 17.6,84.2 72.4,94.3 72.4,165.4 0,9.3 -44.6,170.9 -44.6,180.2 0,32.9 23.7,103.9 53,122.8 10.6,-73.9 7,-146.9 83.4,-215.5 -2.7,39 -21.3,111.3 -21.3,120.6 0,78.1 66.9,86.4 66.9,150.5 0,75.3 -80.3,177.3 -164.8,202.9z"/>
|
||||
<path
|
||||
android:fillColor="@color/tab_normal_color"
|
||||
android:pathData="M616.5,758.9c-27.3,-17.5 -45.9,-78.6 -45.9,-102.3 0,-9.3 7.4,-57.6 7.4,-66.9 0,-11.1 -16.1,-63.8 -20.8,-68.7 -5.1,23.8 -12.4,49.3 -21.7,70.6 -10.9,-46.5 -53.8,-71.9 -82.4,-126.3 -1.4,5.5 -5.1,9.2 -5.1,18.6 0,34.8 29.8,56.6 29.8,96.6 0,24.1 -38,86.9 -65.4,111.9 -15.8,14.4 -15.9,37.2 -25.7,47.8 -6.1,-6.8 -5.6,-11.1 -5.6,-20.4 0,-9.3 14.9,-44.5 14.9,-53.9 0,-19.5 -22.4,-46.4 -51.4,-51.6 -0.7,8.9 6.8,20 6.8,29.3 0,34.4 -26,40.9 -26,94.8 0,95.2 111,135.6 180.2,135.6 9.3,0 51.9,-5 74.3,-8.8 57.6,-9.8 147.2,-65.5 146.8,-125l3.7,-66.9c-59.4,52.1 -87.1,34.5 -113.8,85.6z"/>
|
||||
</vector>
|
||||
12
app/src/main/res/drawable/trending_selected.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:fillColor="@color/tab_selected_color"
|
||||
android:pathData="M774.9,545.2c0,-29.2 22.3,-74.3 22.3,-104 0,-38.1 -14.8,-72.7 -50.9,-116.9 7.7,63.7 -34.6,129.6 -80.5,185.7 -5.2,-47.3 38.5,-123.6 38.5,-161.7 0,-98.5 -66.9,-93.9 -66.9,-161.7 0,-42.7 14.7,-68.5 36.7,-122.1 -75.5,31.7 -118.4,110.9 -118.4,164.8 0,9.3 11.2,65 11.2,74.3 0,12.5 -2.4,25.7 -9.1,35.3 -9.7,-21.3 -25.3,-44.4 -44.8,-66.3 -32.5,-36.7 -79.8,-72.6 -79.8,-110.2 0,-25.5 12.3,-66.4 25.3,-94.3 -86.8,58 -136.8,106.8 -136.8,176 0,49.3 63.2,141.2 63.2,165.4 0,9.3 -3.5,27 -9.1,40.9 -9.1,-62.1 -105.3,-121.2 -150.6,-117.8 32.3,38.6 66.7,90.3 66.7,127 0,66.9 -89.2,83.6 -89.2,200.7 0,188.6 170.5,299.1 328.8,299.1 46.5,0 116.6,-11.4 157.1,-35.1 98,-58 153.2,-144.2 153.2,-215.7 0,-76.2 -66.9,-70.1 -66.9,-163.5zM642.1,907.8c-22.3,6.5 -85.1,20 -119.4,20 -148.1,0 -291.7,-118.9 -291.7,-275 0,-75.2 92.9,-128.2 92.9,-184 0,-9.3 -3.7,-33 -6.4,-53.6 34.7,34.3 21.8,80.5 24.8,119.8l6,6.4c41.3,-37.2 68.6,-84.5 68.6,-128.2 0,-67.8 -63.2,-102.7 -63.2,-170.9 0,-29.3 14.9,-60.7 43.4,-90.9 1.2,16.6 0.4,36.9 9.2,49 28.4,39.9 71,77.4 101.6,115 29.7,36.3 22.2,75.1 29.9,110.9 32.5,-58.6 61.1,-73.9 61.1,-128.2 0,-9.3 -11.2,-61.3 -11.2,-70.7 0,-9.3 3.8,-30.2 9.3,-46.4 17.6,84.2 72.4,94.3 72.4,165.4 0,9.3 -44.6,170.9 -44.6,180.2 0,32.9 23.7,103.9 53,122.8 10.6,-73.9 7,-146.9 83.4,-215.5 -2.7,39 -21.3,111.3 -21.3,120.6 0,78.1 66.9,86.4 66.9,150.5 0,75.3 -80.3,177.3 -164.8,202.9z"/>
|
||||
<path
|
||||
android:fillColor="@color/tab_selected_color"
|
||||
android:pathData="M616.5,758.9c-27.3,-17.5 -45.9,-78.6 -45.9,-102.3 0,-9.3 7.4,-57.6 7.4,-66.9 0,-11.1 -16.1,-63.8 -20.8,-68.7 -5.1,23.8 -12.4,49.3 -21.7,70.6 -10.9,-46.5 -53.8,-71.9 -82.4,-126.3 -1.4,5.5 -5.1,9.2 -5.1,18.6 0,34.8 29.8,56.6 29.8,96.6 0,24.1 -38,86.9 -65.4,111.9 -15.8,14.4 -15.9,37.2 -25.7,47.8 -6.1,-6.8 -5.6,-11.1 -5.6,-20.4 0,-9.3 14.9,-44.5 14.9,-53.9 0,-19.5 -22.4,-46.4 -51.4,-51.6 -0.7,8.9 6.8,20 6.8,29.3 0,34.4 -26,40.9 -26,94.8 0,95.2 111,135.6 180.2,135.6 9.3,0 51.9,-5 74.3,-8.8 57.6,-9.8 147.2,-65.5 146.8,-125l3.7,-66.9c-59.4,52.1 -87.1,34.5 -113.8,85.6z"/>
|
||||
</vector>
|
||||
21
app/src/main/res/drawable/welcom_pb.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<corners android:radius="5dp" />
|
||||
<solid android:color="#D3D3D3" /> <!-- 背景颜色 -->
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<corners android:radius="20dp" />
|
||||
<gradient
|
||||
android:startColor="#1CC8EE"
|
||||
android:centerColor="#69FE73"
|
||||
android:endColor="#CBD64B"
|
||||
android:angle="0" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
||||
9
app/src/main/res/layout/activity_base.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/frameLayout"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
</FrameLayout>
|
||||
37
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?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:paddingTop="34dp"
|
||||
tools:context=".activity.MainActivity">
|
||||
|
||||
<com.live.mylivewallpaper.help.MyTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:text="@string/app_name"
|
||||
android:padding="8dp"
|
||||
android:id="@+id/title"
|
||||
app:apply_font="true"
|
||||
android:textColor="@color/tab_selected_color"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/vp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_above="@id/tab" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
app:tabBackground="@color/transparent"
|
||||
app:tabIndicatorHeight="0dp"
|
||||
app:tabRippleColor="@null" />
|
||||
|
||||
</RelativeLayout>
|
||||
139
app/src/main/res/layout/activity_video.xml
Normal file
@ -0,0 +1,139 @@
|
||||
<?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:id="@+id/top_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/white"
|
||||
tools:context=".activity.VideoActivity">
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/surfaceVideo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.media3.ui.PlayerView
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
app:resize_mode="zoom"
|
||||
app:show_buffering="never"
|
||||
app:show_shuffle_button="false"
|
||||
app:show_subtitle_button="false"
|
||||
app:show_vr_button="false"
|
||||
app:use_controller="false" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="34dp"
|
||||
android:background="@drawable/bg_shape_favorite"
|
||||
android:padding="11dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/im_back" />
|
||||
</FrameLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="120dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:background="@drawable/bg_apply"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="10dp">
|
||||
|
||||
<com.live.mylivewallpaper.help.MyTextView
|
||||
android:id="@+id/tv_describe"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:text="Eternal hues dance in the void's embrace 🎗️"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
app:apply_font="true"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_describe">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_set"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_shape_apply"
|
||||
android:padding="6dp">
|
||||
|
||||
<com.live.mylivewallpaper.help.MyTextView
|
||||
android:id="@+id/i_favorite"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="25dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/set"
|
||||
android:textSize="17sp"
|
||||
app:apply_font="true" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_favorite"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:background="@drawable/bg_shape_favorite"
|
||||
android:padding="11dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/im_favorite"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/selector_favorite" />
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/relative_loading"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/color_white_80"
|
||||
android:visibility="gone">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="6dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:progressDrawable="@drawable/progress_bar_horizontal" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
48
app/src/main/res/layout/activity_welcome.xml
Normal file
@ -0,0 +1,48 @@
|
||||
<?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:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/splash_image"
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="150dp"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
app:layout_constraintBottom_toTopOf="@+id/splash_title"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/splash_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/black"
|
||||
android:textSize="25sp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="191dp"
|
||||
android:layout_height="6dp"
|
||||
android:layout_marginBottom="80dp"
|
||||
android:max="100"
|
||||
android:progress="0"
|
||||
android:progressDrawable="@drawable/welcom_pb"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
15
app/src/main/res/layout/fragment_main.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?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="wrap_content"
|
||||
tools:context=".fragment.MainFragment">
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello_blank_fragment" />
|
||||
|
||||
</FrameLayout>
|
||||
11
app/src/main/res/layout/item_main.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_thumb"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="180dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
31
app/src/main/res/layout/item_tab.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_tab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/tab_im"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/tab_explore" />
|
||||
</FrameLayout>
|
||||
|
||||
<com.live.mylivewallpaper.help.MyTextView
|
||||
android:id="@+id/tab_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textSize="11sp"
|
||||
app:apply_font="true"
|
||||
android:textColor="@color/tab_title"
|
||||
android:text="@string/app_name" />
|
||||
|
||||
</LinearLayout>
|
||||
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/raw/test1.mp4
Normal file
BIN
app/src/main/res/raw/test2.mp4
Normal file
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.MyLiveWallpaper" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Customize your dark theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||
</style>
|
||||
</resources>
|
||||
6
app/src/main/res/values/attrs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="MyTextView">
|
||||
<attr name="apply_font" format="boolean"/>
|
||||
</declare-styleable>
|
||||
</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="transparent">#00000000</color>
|
||||
<color name="tab_normal_color">#878080</color>
|
||||
<color name="tab_selected_color">#DDB94D</color>
|
||||
<color name="color_white_80">#80FFFFFF</color>
|
||||
<color name="color_red">#BA2828</color>
|
||||
</resources>
|
||||
10
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<resources>
|
||||
<string name="app_name">MyLiveWallpaper</string>
|
||||
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
<string name="tab_title_1">Trending</string>
|
||||
<string name="tab_title_2">Explore</string>
|
||||
<string name="tab_title_3">Shift</string>
|
||||
<string name="tab_title_4">Favorites</string>
|
||||
<string name="set">Set</string>
|
||||
</resources>
|
||||
9
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Base.Theme.MyLiveWallpaper" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Customize your light theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.MyLiveWallpaper" parent="Base.Theme.MyLiveWallpaper" />
|
||||
</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>
|
||||
8
app/src/main/res/xml/file_paths.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- 允许访问应用的内部存储文件 -->
|
||||
<files-path name="internal_files" path="." />
|
||||
<cache-path name="inner_app_cache" path="." />
|
||||
<!-- 允许访问应用的外部存储文件(如果有的话) -->
|
||||
<external-path name="external_files" path="." />
|
||||
</paths>
|
||||