This commit is contained in:
litingting 2024-12-21 11:03:46 +08:00
commit 3dab1d77c9
109 changed files with 16938 additions and 0 deletions

15
.gitignore vendored Normal file
View 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
View File

@ -0,0 +1 @@
/build

69
app/build.gradle.kts Normal file
View 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")
}

View 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
View 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

View File

@ -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());
}
}

View 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>

View 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, its 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
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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());
}
});
}
}
}

View File

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

View File

@ -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);
// }
}
}

View File

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

View File

@ -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();
}
};
}

View File

@ -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();
}
};
}

View File

@ -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();
}
}

View File

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

View File

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

View 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;
}
}

View 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;
}
}

View File

@ -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();
}
}
}

View File

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

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

View 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;
}
}

View File

@ -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;
}
}
}

View File

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

View File

@ -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();
}
}

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

View File

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

View File

@ -0,0 +1,5 @@
package com.live.mylivewallpaper.listener;
public interface OnLikeUpdateListener {
void onLikeUpdate();
}

View File

@ -0,0 +1,5 @@
package com.live.mylivewallpaper.listener;
public interface OnVideoResultListener {
void onVideoResult(boolean success,String path);
}

View File

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

View File

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

View File

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

View File

@ -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() {
}
}

View File

@ -0,0 +1,8 @@
package com.live.mylivewallpaper.request;
public interface OnRequestListener<T> {
void onFail(String errorMsg);
void onSuccess(T data) ;
}

View File

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

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

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

View File

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

View File

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

View File

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

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Binary file not shown.

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

Some files were not shown because too many files have changed in this diff Show More