完成版
BIN
app/PureWallpaper.jks
Normal file
@ -1,24 +1,31 @@
|
|||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
}
|
}
|
||||||
|
val timestamp: String = SimpleDateFormat("MM_dd_HH_mm").format(Date())
|
||||||
android {
|
android {
|
||||||
namespace = "com.pure.wallpaper.purewallpaper"
|
namespace = "com.pure.wallpaper.purewallpaper"
|
||||||
compileSdk = 35
|
compileSdk = 35
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.pure.wallpaper.purewallpaper"
|
applicationId = "com.pure.wallpaper.purewallpaper"
|
||||||
minSdk = 23
|
minSdk = 24
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
|
setProperty("archivesBaseName", "Pure Wallpaper_V" + versionName + "(${versionCode})_$timestamp")
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = true
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
@ -40,4 +47,10 @@ dependencies {
|
|||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.ext.junit)
|
androidTestImplementation(libs.ext.junit)
|
||||||
androidTestImplementation(libs.espresso.core)
|
androidTestImplementation(libs.espresso.core)
|
||||||
|
|
||||||
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
|
annotationProcessor("com.github.bumptech.glide:compiler:4.16.0")
|
||||||
|
|
||||||
|
implementation ("androidx.room:room-runtime:2.7.1")
|
||||||
|
annotationProcessor ("androidx.room:room-compiler:2.7.1")
|
||||||
}
|
}
|
||||||
16
app/proguard-rules.pro
vendored
@ -18,4 +18,18 @@
|
|||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
# If you keep the line number information, uncomment this to
|
||||||
# hide the original source file name.
|
# hide the original source file name.
|
||||||
#-renamesourcefileattribute SourceFile
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
-keepclassmembers class com.pure.wallpaper.purewallpaper.MyApplication {
|
||||||
|
public static final java.lang.String DATABASE_FILE_NAME;
|
||||||
|
public static final int DATABASE_VERSION_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@androidx.room.Query <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class com.pure.wallpaper.purewallpaper.sqlite.database.AppDatabase { *; }
|
||||||
|
-keep class com.pure.wallpaper.purewallpaper.sqlite.database.dao.PureWallpaperDao { *; }
|
||||||
|
-keep class com.pure.wallpaper.purewallpaper.sqlite.database.data.ImageSet { *; }
|
||||||
|
-keep class com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper { *; }
|
||||||
@ -2,18 +2,34 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.SET_WALLPAPER" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".MyApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.PureWallpaper"
|
android:theme="@style/Theme.PureWallpaper"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".ui.activity.MainActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activity.CategoryActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activity.PureActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activity.SplashActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|||||||
9473
app/src/main/assets/pure_wallpaper.json
Normal file
@ -1,24 +0,0 @@
|
|||||||
package com.pure.wallpaper.purewallpaper;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.activity.EdgeToEdge;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.core.graphics.Insets;
|
|
||||||
import androidx.core.view.ViewCompat;
|
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
EdgeToEdge.enable(this);
|
|
||||||
setContentView(R.layout.activity_main);
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
|
||||||
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
|
||||||
return insets;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.AppDatabase;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.dao.PureWallpaperDao;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.ImageSet;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.JsonDataParser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class MyApplication extends Application {
|
||||||
|
public static MyApplication application;
|
||||||
|
public static final int DATABASE_VERSION_CODE = 1;
|
||||||
|
public static final String DATABASE_FILE_NAME = "art_collection";
|
||||||
|
private static final String PREFERENCES_FILE = "app_settings";
|
||||||
|
private static final String KEY_FIRST_RUN = "is_first_launch";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
application = this;
|
||||||
|
|
||||||
|
SharedPreferences appPrefs = getSharedPreferences(PREFERENCES_FILE, MODE_PRIVATE);
|
||||||
|
|
||||||
|
if (!appPrefs.getBoolean(KEY_FIRST_RUN, false)) {
|
||||||
|
initializeData();
|
||||||
|
appPrefs.edit().putBoolean(KEY_FIRST_RUN, true).apply();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Context getContext() {
|
||||||
|
return application.getApplicationContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeData() {
|
||||||
|
ExecutorService backgroundExec = Executors.newFixedThreadPool(2);
|
||||||
|
backgroundExec.execute(() -> {
|
||||||
|
List<ImageSet> imageData = retrieveImageData();
|
||||||
|
|
||||||
|
List<PureWallpaper> pureWallpaperList = new ArrayList<>();
|
||||||
|
AppDatabase db = AppDatabase.getInstance(getContext());
|
||||||
|
PureWallpaperDao pureWallpaperDao = db.pureWallpaperDao();
|
||||||
|
|
||||||
|
for (ImageSet category : imageData) {
|
||||||
|
pureWallpaperList.addAll(category.getList());
|
||||||
|
}
|
||||||
|
|
||||||
|
pureWallpaperDao.insertAll(pureWallpaperList);
|
||||||
|
backgroundExec.shutdown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ImageSet> retrieveImageData() {
|
||||||
|
return JsonDataParser.extractJsonData("pure_wallpaper.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.sqlite.database;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.room.Database;
|
||||||
|
import androidx.room.Room;
|
||||||
|
import androidx.room.RoomDatabase;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.MyApplication;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.dao.PureWallpaperDao;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
|
||||||
|
|
||||||
|
@Database(entities = {PureWallpaper.class}, version = MyApplication.DATABASE_VERSION_CODE, exportSchema = false)
|
||||||
|
public abstract class AppDatabase extends RoomDatabase {
|
||||||
|
|
||||||
|
public abstract PureWallpaperDao pureWallpaperDao();
|
||||||
|
private static volatile AppDatabase INSTANCE;
|
||||||
|
|
||||||
|
public static AppDatabase getInstance(Context context) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
synchronized (AppDatabase.class) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
|
||||||
|
AppDatabase.class, MyApplication.DATABASE_FILE_NAME)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.sqlite.database.dao;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.room.Dao;
|
||||||
|
import androidx.room.Insert;
|
||||||
|
import androidx.room.Query;
|
||||||
|
import androidx.room.Update;
|
||||||
|
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
public interface PureWallpaperDao {
|
||||||
|
@Insert
|
||||||
|
void insertAll(List<PureWallpaper> paletteData);
|
||||||
|
|
||||||
|
@Update
|
||||||
|
void update(PureWallpaper pureWallpaper);
|
||||||
|
|
||||||
|
@Query("SELECT * FROM PureWallpaper WHERE isLike = 1 ")
|
||||||
|
LiveData<List<PureWallpaper>> getFavorite();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM PureWallpaper WHERE id IN (SELECT MAX(id) FROM PureWallpaper GROUP BY name) ORDER BY id ASC")
|
||||||
|
LiveData<List<PureWallpaper>> getCategory();
|
||||||
|
|
||||||
|
@Query("SELECT * FROM PureWallpaper WHERE name = :name ORDER BY id DESC")
|
||||||
|
LiveData<List<PureWallpaper>> getAllCategory(String name);
|
||||||
|
|
||||||
|
@Query("SELECT isLIKE FROM PureWallpaper WHERE source = :source AND name = :name")
|
||||||
|
LiveData<Boolean> getCollection(String source, String name);
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.sqlite.database.data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageSet {
|
||||||
|
private String name;
|
||||||
|
private List<PureWallpaper> list;
|
||||||
|
|
||||||
|
public ImageSet(String name, List<PureWallpaper> list) {
|
||||||
|
this.name = name;
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PureWallpaper> getList() {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setList(List<PureWallpaper> list) {
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.sqlite.database.data;
|
||||||
|
|
||||||
|
import androidx.room.Entity;
|
||||||
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class PureWallpaper implements Serializable {
|
||||||
|
|
||||||
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
private int id;
|
||||||
|
private String original;
|
||||||
|
private String previewThumb;
|
||||||
|
private String source;
|
||||||
|
private String name;
|
||||||
|
private Boolean isLike;
|
||||||
|
|
||||||
|
public PureWallpaper(String original, String previewThumb, String source, String name, Boolean isLike) {
|
||||||
|
this.original = original;
|
||||||
|
this.previewThumb = previewThumb;
|
||||||
|
this.source = source;
|
||||||
|
this.name = name;
|
||||||
|
this.isLike = isLike;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOriginal() {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOriginal(String original) {
|
||||||
|
this.original = original;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPreviewThumb() {
|
||||||
|
return previewThumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreviewThumb(String previewThumb) {
|
||||||
|
this.previewThumb = previewThumb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSource() {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSource(String source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getLike() {
|
||||||
|
return isLike;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLike(Boolean like) {
|
||||||
|
isLike = like;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.activity;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.LayoutAnimationController;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.activity.EdgeToEdge;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.graphics.Insets;
|
||||||
|
import androidx.core.view.ViewCompat;
|
||||||
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.ActivityCategoryBinding;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.adapter.JumpToPureAdapter;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.PaletteViewModel;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.StaggeredGridItemDecoration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class CategoryActivity extends AppCompatActivity {
|
||||||
|
private ActivityCategoryBinding layoutBinding;
|
||||||
|
private JumpToPureAdapter dataAdapter;
|
||||||
|
private PaletteViewModel dataModel;
|
||||||
|
private String groupTitle;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedState) {
|
||||||
|
super.onCreate(savedState);
|
||||||
|
EdgeToEdge.enable(this);
|
||||||
|
|
||||||
|
layoutBinding = ActivityCategoryBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(layoutBinding.getRoot());
|
||||||
|
|
||||||
|
View mainView = findViewById(R.id.main);
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(mainView, (v, windowInsets) -> {
|
||||||
|
Insets bars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
|
v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
|
||||||
|
return windowInsets;
|
||||||
|
});
|
||||||
|
|
||||||
|
setupComponents();
|
||||||
|
bindListeners();
|
||||||
|
monitorDataUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupComponents() {
|
||||||
|
groupTitle = getIntent().getStringExtra("name");
|
||||||
|
if (groupTitle == null) {
|
||||||
|
Toast.makeText(this, "Data not found", Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataModel = new ViewModelProvider(this).get(PaletteViewModel.class);
|
||||||
|
|
||||||
|
dataAdapter = new JumpToPureAdapter(this, new ArrayList<>());
|
||||||
|
layoutBinding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
|
||||||
|
layoutBinding.recyclerView.setAdapter(dataAdapter);
|
||||||
|
|
||||||
|
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_animation_fall_down);
|
||||||
|
layoutBinding.recyclerView.setLayoutAnimation(animation);
|
||||||
|
|
||||||
|
StaggeredGridItemDecoration decoration = new StaggeredGridItemDecoration(20, 10);
|
||||||
|
layoutBinding.recyclerView.addItemDecoration(decoration);
|
||||||
|
|
||||||
|
layoutBinding.title.setText(groupTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindListeners() {
|
||||||
|
layoutBinding.back.setOnClickListener(v -> finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void monitorDataUpdates() {
|
||||||
|
dataModel.getAllCategory(groupTitle).observe(this, items -> {
|
||||||
|
if (items != null) {
|
||||||
|
dataAdapter.updateDataSet(items);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
layoutBinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.activity;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.activity.EdgeToEdge;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.core.graphics.Insets;
|
||||||
|
import androidx.core.view.ViewCompat;
|
||||||
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.tabs.TabLayout;
|
||||||
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.ActivityMainBinding;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.CustomTabBinding;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.adapter.ViewPager2Adapter;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
private ActivityMainBinding layoutBinding;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedState) {
|
||||||
|
super.onCreate(savedState);
|
||||||
|
EdgeToEdge.enable(this);
|
||||||
|
layoutBinding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(layoutBinding.getRoot());
|
||||||
|
|
||||||
|
View mainView = findViewById(R.id.main);
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(mainView, (v, windowInsets) -> {
|
||||||
|
Insets systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
|
return windowInsets;
|
||||||
|
});
|
||||||
|
|
||||||
|
configurePagerAndTabs();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configurePagerAndTabs() {
|
||||||
|
ViewPager2Adapter adapter = new ViewPager2Adapter(this);
|
||||||
|
layoutBinding.viewPager.setAdapter(adapter);
|
||||||
|
|
||||||
|
TabLayoutMediator mediator = new TabLayoutMediator(layoutBinding.tabLayout, layoutBinding.viewPager, (tab, position) -> {
|
||||||
|
CustomTabBinding tabView = CustomTabBinding.inflate(LayoutInflater.from(this));
|
||||||
|
tab.setCustomView(tabView.getRoot());
|
||||||
|
setupTabContent(tabView, position);
|
||||||
|
});
|
||||||
|
mediator.attach();
|
||||||
|
|
||||||
|
layoutBinding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onTabSelected(TabLayout.Tab tab) {
|
||||||
|
updateTabAppearance(tab, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTabUnselected(TabLayout.Tab tab) {
|
||||||
|
updateTabAppearance(tab, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTabReselected(TabLayout.Tab tab) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupTabContent(CustomTabBinding tabBinding, int index) {
|
||||||
|
tabBinding.text.setText(index == 0 ? "CATEGORY" : "COLLECTION");
|
||||||
|
tabBinding.image.setImageResource(selectIcon(index, false, 1));
|
||||||
|
int colorRes = index == 0 ? R.color.black : R.color.gray;
|
||||||
|
tabBinding.text.setTextColor(ContextCompat.getColor(this, colorRes));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTabAppearance(TabLayout.Tab tab, boolean isActive) {
|
||||||
|
View customView = tab.getCustomView();
|
||||||
|
if (customView == null) return;
|
||||||
|
|
||||||
|
CustomTabBinding tabBinding = CustomTabBinding.bind(customView);
|
||||||
|
int tabIndex = tab.getPosition();
|
||||||
|
|
||||||
|
tabBinding.image.setImageResource(selectIcon(tabIndex, isActive, 0));
|
||||||
|
int colorRes = isActive ? R.color.black : R.color.gray;
|
||||||
|
tabBinding.text.setTextColor(ContextCompat.getColor(this, colorRes));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int selectIcon(int index, boolean isActive, int mode) {
|
||||||
|
if (index == 0 && mode == 1) return R.drawable.main;
|
||||||
|
if (index == 1) return isActive ? R.drawable.collection : R.drawable.un_collection;
|
||||||
|
return isActive ? R.drawable.main : R.drawable.un_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
layoutBinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,261 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.activity;
|
||||||
|
|
||||||
|
import static com.pure.wallpaper.purewallpaper.util.PureUtils.PERMISSION_CODE_STORAGE;
|
||||||
|
|
||||||
|
import android.app.WallpaperManager;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.activity.EdgeToEdge;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.request.target.CustomTarget;
|
||||||
|
import com.bumptech.glide.request.transition.Transition;
|
||||||
|
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.ActivityPureBinding;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.PaletteViewModel;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.PureListener;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.PureUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class PureActivity extends AppCompatActivity implements PureListener {
|
||||||
|
private ActivityPureBinding displayBinding;
|
||||||
|
private String mainImageLink;
|
||||||
|
private String imageOrigin;
|
||||||
|
private PureWallpaper imageData;
|
||||||
|
private PaletteViewModel dataHandler;
|
||||||
|
private String displayTitle;
|
||||||
|
private Bitmap loadedBitmap;
|
||||||
|
private PureUtils imageProcessor;
|
||||||
|
private ExecutorService taskRunner;
|
||||||
|
private Handler mainThreadHandler;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedState) {
|
||||||
|
super.onCreate(savedState);
|
||||||
|
EdgeToEdge.enable(this);
|
||||||
|
displayBinding = ActivityPureBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(displayBinding.getRoot());
|
||||||
|
|
||||||
|
initData();
|
||||||
|
setupControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
imageData = (PureWallpaper) getIntent().getSerializableExtra("entry");
|
||||||
|
if (imageData == null) {
|
||||||
|
Toast.makeText(this, "Load failure", Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainImageLink = imageData.getOriginal();
|
||||||
|
imageOrigin = imageData.getSource();
|
||||||
|
displayTitle = imageData.getName();
|
||||||
|
|
||||||
|
imageProcessor = new PureUtils();
|
||||||
|
dataHandler = new ViewModelProvider(this).get(PaletteViewModel.class);
|
||||||
|
|
||||||
|
mainThreadHandler = new Handler(Looper.getMainLooper());
|
||||||
|
taskRunner = Executors.newFixedThreadPool(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupControls() {
|
||||||
|
showProgress();
|
||||||
|
|
||||||
|
displayBinding.back.setOnClickListener(v -> finish());
|
||||||
|
|
||||||
|
displayBinding.like.setOnClickListener(v -> {
|
||||||
|
boolean newState = !imageData.getLike();
|
||||||
|
imageData.setLike(newState);
|
||||||
|
taskRunner.execute(() -> dataHandler.update(imageData));
|
||||||
|
});
|
||||||
|
|
||||||
|
displayBinding.set.setOnClickListener(v -> launchOptionsMenu());
|
||||||
|
|
||||||
|
displayBinding.down.setOnClickListener(v -> {
|
||||||
|
showProgress();
|
||||||
|
imageProcessor.setWallpaper(this, imageOrigin, this);
|
||||||
|
});
|
||||||
|
|
||||||
|
loadImageContent();
|
||||||
|
trackLikeStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int code, @NonNull String[] perms, @NonNull int[] results) {
|
||||||
|
super.onRequestPermissionsResult(code, perms, results);
|
||||||
|
if (code == PERMISSION_CODE_STORAGE) {
|
||||||
|
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
imageProcessor.setWallpaper(this, imageOrigin, this);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Permission rejected", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchOptionsMenu() {
|
||||||
|
BottomSheetDialog menu = new BottomSheetDialog(this);
|
||||||
|
View menuLayout = LayoutInflater.from(this).inflate(R.layout.detail_dialog, null);
|
||||||
|
|
||||||
|
menuLayout.findViewById(R.id.both).setOnClickListener(v -> {
|
||||||
|
toggleOptions(menuLayout, false);
|
||||||
|
applyImageAsWallpaper(loadedBitmap, WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK, menu, menuLayout);
|
||||||
|
});
|
||||||
|
|
||||||
|
menuLayout.findViewById(R.id.lock).setOnClickListener(v -> {
|
||||||
|
toggleOptions(menuLayout, false);
|
||||||
|
applyImageAsWallpaper(loadedBitmap, WallpaperManager.FLAG_LOCK, menu, menuLayout);
|
||||||
|
});
|
||||||
|
|
||||||
|
menuLayout.findViewById(R.id.desktop).setOnClickListener(v -> {
|
||||||
|
toggleOptions(menuLayout, false);
|
||||||
|
applyImageAsWallpaper(loadedBitmap, WallpaperManager.FLAG_SYSTEM, menu, menuLayout);
|
||||||
|
});
|
||||||
|
|
||||||
|
menu.setContentView(menuLayout);
|
||||||
|
menu.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleOptions(View menuLayout, boolean enable) {
|
||||||
|
menuLayout.findViewById(R.id.both).setEnabled(enable);
|
||||||
|
menuLayout.findViewById(R.id.lock).setEnabled(enable);
|
||||||
|
menuLayout.findViewById(R.id.desktop).setEnabled(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyImageAsWallpaper(Bitmap bitmap, int flagSet, BottomSheetDialog menu, View menuLayout) {
|
||||||
|
showProgress();
|
||||||
|
|
||||||
|
taskRunner.execute(() -> {
|
||||||
|
boolean success = false;
|
||||||
|
try {
|
||||||
|
success = processWallpaper(bitmap, flagSet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
boolean outcome = success;
|
||||||
|
mainThreadHandler.post(() -> {
|
||||||
|
clearProgress();
|
||||||
|
String text = outcome ? "Wallpaper applied" : "Failed to apply wallpaper";
|
||||||
|
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
|
||||||
|
toggleOptions(menuLayout, true); // 确保在 Toast 显示后重新启用按钮
|
||||||
|
menu.dismiss(); // 如果您希望在设置成功/失败后关闭菜单
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean processWallpaper(Bitmap bitmap, int flagSet) {
|
||||||
|
WallpaperManager manager = WallpaperManager.getInstance(this);
|
||||||
|
try {
|
||||||
|
displayBinding.imageView.setDrawingCacheEnabled(true);
|
||||||
|
manager.setBitmap(bitmap, null, true, flagSet);
|
||||||
|
return true;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
displayBinding.imageView.setDrawingCacheEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadImageContent() {
|
||||||
|
Glide.with(this)
|
||||||
|
.asBitmap()
|
||||||
|
.load(mainImageLink)
|
||||||
|
.error(ContextCompat.getDrawable(this, R.mipmap.placeholder))
|
||||||
|
.override(1080, 1920)
|
||||||
|
.centerInside()
|
||||||
|
.into(new CustomTarget<Bitmap>() {
|
||||||
|
@Override
|
||||||
|
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||||
|
displayBinding.imageView.setImageBitmap(resource);
|
||||||
|
loadedBitmap = resource;
|
||||||
|
clearProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadCleared(Drawable fallback) {
|
||||||
|
displayBinding.imageView.setImageDrawable(fallback != null ? fallback : fetchPlaceholder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFailed(Drawable error) {
|
||||||
|
displayBinding.imageView.setImageDrawable(error != null ? error : fetchPlaceholder());
|
||||||
|
clearProgress();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable fetchPlaceholder() {
|
||||||
|
return ContextCompat.getDrawable(this, R.mipmap.placeholder);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void trackLikeStatus() {
|
||||||
|
dataHandler.getLike(imageOrigin, displayTitle).observe(this, item -> refreshLikeButton());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshLikeButton() {
|
||||||
|
displayBinding.like.setImageResource(
|
||||||
|
imageData.getLike() ? R.drawable.favorite : R.drawable.un_favorite
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearProgress() {
|
||||||
|
if (displayBinding != null) {
|
||||||
|
displayBinding.progressBar.setVisibility(View.GONE);
|
||||||
|
displayBinding.view.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showProgress() {
|
||||||
|
displayBinding.progressBar.setVisibility(View.VISIBLE);
|
||||||
|
displayBinding.view.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrepare() {
|
||||||
|
showProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Uri uri) {
|
||||||
|
clearProgress();
|
||||||
|
Toast.makeText(this, "Download successful", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError() {
|
||||||
|
clearProgress();
|
||||||
|
Toast.makeText(this, "Download failed", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (mainThreadHandler != null) {
|
||||||
|
mainThreadHandler.removeCallbacksAndMessages(null);
|
||||||
|
}
|
||||||
|
if (taskRunner != null) {
|
||||||
|
taskRunner.shutdown();
|
||||||
|
}
|
||||||
|
displayBinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.activity;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.CountDownTimer;
|
||||||
|
|
||||||
|
import androidx.activity.EdgeToEdge;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.graphics.Insets;
|
||||||
|
import androidx.core.view.ViewCompat;
|
||||||
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.ActivitySplashBinding;
|
||||||
|
|
||||||
|
public class SplashActivity extends AppCompatActivity {
|
||||||
|
private ActivitySplashBinding binding;
|
||||||
|
private static final long TOTAL_TIME = 1000;
|
||||||
|
private CountDownTimer countDownTimer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
EdgeToEdge.enable(this);
|
||||||
|
|
||||||
|
binding = ActivitySplashBinding.inflate(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
||||||
|
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
|
return insets;
|
||||||
|
});
|
||||||
|
|
||||||
|
Glide.with(this)
|
||||||
|
.load(R.mipmap.placeholder)
|
||||||
|
.transform(new CenterCrop(), new RoundedCorners(32))
|
||||||
|
.into(binding.image);
|
||||||
|
|
||||||
|
countDownTimer = new CountDownTimer(TOTAL_TIME, 100) {
|
||||||
|
@Override
|
||||||
|
public void onTick(long millisUntilFinished) {
|
||||||
|
int percentage = (int) (100 - (float) millisUntilFinished / TOTAL_TIME * 100);
|
||||||
|
binding.progressBar.setProgress(percentage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
jumpToMain();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
countDownTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void jumpToMain() {
|
||||||
|
binding.progressBar.setProgress(100);
|
||||||
|
|
||||||
|
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
if (countDownTimer != null) {
|
||||||
|
countDownTimer.cancel();
|
||||||
|
}
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,88 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.adapter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.activity.CategoryActivity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class JumpToFragmentAdapter extends RecyclerView.Adapter<JumpToFragmentAdapter.GalleryViewHolder> {
|
||||||
|
private List<PureWallpaper> itemCollection;
|
||||||
|
private final Context appContext;
|
||||||
|
|
||||||
|
public JumpToFragmentAdapter(Context ctx, List<PureWallpaper> startingData) {
|
||||||
|
this.appContext = ctx;
|
||||||
|
this.itemCollection = startingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void swapData(List<PureWallpaper> newItems) {
|
||||||
|
this.itemCollection = newItems;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public GalleryViewHolder onCreateViewHolder(@NonNull ViewGroup container, int type) {
|
||||||
|
View layout = LayoutInflater.from(appContext).inflate(R.layout.item_to_fragment, container, false);
|
||||||
|
return new GalleryViewHolder(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull GalleryViewHolder holder, int index) {
|
||||||
|
holder.fillContent(itemCollection.get(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return itemCollection.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class GalleryViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final ImageView previewImage;
|
||||||
|
private final TextView caption;
|
||||||
|
|
||||||
|
GalleryViewHolder(View layout) {
|
||||||
|
super(layout);
|
||||||
|
previewImage = layout.findViewById(R.id.imageview);
|
||||||
|
caption = layout.findViewById(R.id.category_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillContent(PureWallpaper data) {
|
||||||
|
caption.setText(data.getName());
|
||||||
|
renderImage(data.getOriginal());
|
||||||
|
bindClickAction(data.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderImage(String imageUrl) {
|
||||||
|
Glide.with(previewImage.getContext())
|
||||||
|
.load(imageUrl)
|
||||||
|
.thumbnail(0.15f)
|
||||||
|
.transform(new CenterCrop(), new RoundedCorners(32))
|
||||||
|
.placeholder(R.mipmap.placeholder)
|
||||||
|
.error(R.mipmap.placeholder)
|
||||||
|
.into(previewImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void bindClickAction(String groupName) {
|
||||||
|
previewImage.setOnClickListener(v -> {
|
||||||
|
Intent navigate = new Intent(v.getContext(), CategoryActivity.class);
|
||||||
|
navigate.putExtra("name", groupName);
|
||||||
|
v.getContext().startActivity(navigate);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,117 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.adapter;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.bumptech.glide.Glide;
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.AppDatabase;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.activity.PureActivity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class JumpToPureAdapter extends RecyclerView.Adapter<JumpToPureAdapter.ArtHolder> {
|
||||||
|
private final List<PureWallpaper> dataCollection;
|
||||||
|
private final Context appContext;
|
||||||
|
private final Executor taskQueue = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
|
public JumpToPureAdapter(Context ctx, List<PureWallpaper> startingData) {
|
||||||
|
this.appContext = ctx;
|
||||||
|
this.dataCollection = startingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
public void updateDataSet(List<PureWallpaper> freshData) {
|
||||||
|
dataCollection.clear();
|
||||||
|
dataCollection.addAll(freshData);
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ArtHolder onCreateViewHolder(@NonNull ViewGroup container, int type) {
|
||||||
|
View view = LayoutInflater.from(appContext).inflate(R.layout.item_to_pure, container, false);
|
||||||
|
return new ArtHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ArtHolder holder, int index) {
|
||||||
|
holder.renderItem(dataCollection.get(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return dataCollection.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ArtHolder extends RecyclerView.ViewHolder {
|
||||||
|
private final ImageView artViewer;
|
||||||
|
private final ImageView favButton;
|
||||||
|
|
||||||
|
ArtHolder(View layout) {
|
||||||
|
super(layout);
|
||||||
|
artViewer = layout.findViewById(R.id.image_view);
|
||||||
|
favButton = layout.findViewById(R.id.favorite);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderItem(PureWallpaper entry) {
|
||||||
|
showImage(entry.getOriginal());
|
||||||
|
updateFavoriteIcon(entry);
|
||||||
|
attachListeners(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showImage(String url) {
|
||||||
|
Glide.with(artViewer.getContext())
|
||||||
|
.load(url)
|
||||||
|
.dontAnimate()
|
||||||
|
.transform(new CenterCrop(), new RoundedCorners(32))
|
||||||
|
.placeholder(R.mipmap.placeholder)
|
||||||
|
.error(R.mipmap.placeholder)
|
||||||
|
.into(artViewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFavoriteIcon(PureWallpaper entry) {
|
||||||
|
favButton.setImageResource(entry.getLike() ? R.drawable.favorite : R.drawable.un_favorite);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachListeners(PureWallpaper entry) {
|
||||||
|
artViewer.setOnClickListener(v -> {
|
||||||
|
Intent detailIntent = new Intent(v.getContext(), PureActivity.class);
|
||||||
|
detailIntent.putExtra("entry", entry);
|
||||||
|
v.getContext().startActivity(detailIntent);
|
||||||
|
});
|
||||||
|
|
||||||
|
favButton.setOnClickListener(v -> switchFavorite(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchFavorite(PureWallpaper entry) {
|
||||||
|
boolean newValue = !entry.getLike();
|
||||||
|
entry.setLike(newValue);
|
||||||
|
favButton.setImageResource(newValue ? R.drawable.favorite : R.drawable.un_favorite);
|
||||||
|
notifyItemChanged(getAdapterPosition());
|
||||||
|
persistData(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void persistData(PureWallpaper entry) {
|
||||||
|
taskQueue.execute(() -> {
|
||||||
|
AppDatabase
|
||||||
|
.getInstance(appContext.getApplicationContext())
|
||||||
|
.pureWallpaperDao()
|
||||||
|
.update(entry);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.adapter;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.fragment.CollectionFragment;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.fragment.HomeFragment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ViewPager2Adapter extends FragmentStateAdapter {
|
||||||
|
|
||||||
|
private final List<Fragment> fragmentList = new ArrayList<>();
|
||||||
|
|
||||||
|
public ViewPager2Adapter(@NonNull FragmentActivity fragmentActivity) {
|
||||||
|
super(fragmentActivity);
|
||||||
|
fragmentList.add(new HomeFragment());
|
||||||
|
fragmentList.add(new CollectionFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Fragment createFragment(int position) {
|
||||||
|
return fragmentList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return fragmentList.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.fragment;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.LayoutAnimationController;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.FragmentCollectionBinding;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.adapter.JumpToPureAdapter;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.PaletteViewModel;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.StaggeredGridItemDecoration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CollectionFragment extends Fragment {
|
||||||
|
private FragmentCollectionBinding binding;
|
||||||
|
private JumpToPureAdapter jumpToPureAdapter;
|
||||||
|
private PaletteViewModel paletteViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
binding = FragmentCollectionBinding.inflate(inflater, container, false);
|
||||||
|
|
||||||
|
initializeData();
|
||||||
|
fetchFavoriteItems();
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeData() {
|
||||||
|
paletteViewModel = new ViewModelProvider(this).get(PaletteViewModel.class);
|
||||||
|
|
||||||
|
jumpToPureAdapter = new JumpToPureAdapter(requireContext(), new ArrayList<>());
|
||||||
|
binding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
|
||||||
|
binding.recyclerView.setAdapter(jumpToPureAdapter);
|
||||||
|
|
||||||
|
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(requireContext(), R.anim.layout_animation_fall_down);
|
||||||
|
binding.recyclerView.setLayoutAnimation(animation);
|
||||||
|
|
||||||
|
StaggeredGridItemDecoration decoration = new StaggeredGridItemDecoration(20, 10);
|
||||||
|
binding.recyclerView.addItemDecoration(decoration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchFavoriteItems() {
|
||||||
|
paletteViewModel.getAllFavorite()
|
||||||
|
.observe(getViewLifecycleOwner(), new Observer<List<PureWallpaper>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PureWallpaper> updatedList) {
|
||||||
|
jumpToPureAdapter.updateDataSet(updatedList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
binding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.ui.fragment;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.LayoutAnimationController;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.R;
|
||||||
|
import com.pure.wallpaper.purewallpaper.databinding.FragmentHomeBinding;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
import com.pure.wallpaper.purewallpaper.ui.adapter.JumpToFragmentAdapter;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.PaletteViewModel;
|
||||||
|
import com.pure.wallpaper.purewallpaper.util.StaggeredGridItemDecoration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class HomeFragment extends Fragment {
|
||||||
|
private FragmentHomeBinding fragmentHomeBinding;
|
||||||
|
private JumpToFragmentAdapter jumpToFragmentAdapter;
|
||||||
|
private PaletteViewModel paletteViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
fragmentHomeBinding = FragmentHomeBinding.inflate(inflater, container, false);
|
||||||
|
|
||||||
|
initData();
|
||||||
|
getFirstByName();
|
||||||
|
return fragmentHomeBinding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
|
||||||
|
paletteViewModel = new ViewModelProvider(this).get(PaletteViewModel.class);
|
||||||
|
|
||||||
|
fragmentHomeBinding.recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
|
||||||
|
|
||||||
|
jumpToFragmentAdapter = new JumpToFragmentAdapter(requireContext(), new ArrayList<>());
|
||||||
|
fragmentHomeBinding.recyclerView.setAdapter(jumpToFragmentAdapter);
|
||||||
|
|
||||||
|
LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(requireContext(), R.anim.layout_animation_fall_down);
|
||||||
|
fragmentHomeBinding.recyclerView.setLayoutAnimation(animation);
|
||||||
|
|
||||||
|
StaggeredGridItemDecoration decoration = new StaggeredGridItemDecoration(20, 10);
|
||||||
|
fragmentHomeBinding.recyclerView.addItemDecoration(decoration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getFirstByName() {
|
||||||
|
paletteViewModel
|
||||||
|
.getFirstByName()
|
||||||
|
.observe(getViewLifecycleOwner(), new Observer<List<PureWallpaper>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PureWallpaper> coolEntities) {
|
||||||
|
jumpToFragmentAdapter.swapData(coolEntities);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
fragmentHomeBinding = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.util;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.MyApplication;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.ImageSet;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class JsonDataParser {
|
||||||
|
|
||||||
|
private static String retrieveJsonFromFile(String assetName) {
|
||||||
|
StringBuilder dataBuilder = new StringBuilder();
|
||||||
|
try (InputStream is = MyApplication.getContext().getAssets().open(assetName);
|
||||||
|
BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
|
||||||
|
int charCode;
|
||||||
|
while ((charCode = br.read()) != -1) {
|
||||||
|
dataBuilder.append((char) charCode);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Log.d("JsonLoad", "Retrieved JSON: " + dataBuilder.toString());
|
||||||
|
return dataBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ImageSet> extractJsonData(String assetName) {
|
||||||
|
List<ImageSet> resultList = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
String jsonData = retrieveJsonFromFile(assetName);
|
||||||
|
if (jsonData.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Empty or invalid JSON content.");
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray dataArray = new JSONArray(jsonData);
|
||||||
|
for (int idx = 0; idx < dataArray.length(); idx++) {
|
||||||
|
JSONObject groupItem = dataArray.getJSONObject(idx);
|
||||||
|
String categoryName = groupItem.getString("name");
|
||||||
|
|
||||||
|
JSONArray itemsArray = groupItem.getJSONArray("data");
|
||||||
|
List<PureWallpaper> imageItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int k = 0; k < itemsArray.length(); k++) {
|
||||||
|
JSONObject entry = itemsArray.getJSONObject(k);
|
||||||
|
String fullImage = entry.getString("original");
|
||||||
|
String thumbImage = entry.getString("previewThumb");
|
||||||
|
String origin = entry.getString("source");
|
||||||
|
|
||||||
|
imageItems.add(new PureWallpaper(fullImage, thumbImage, origin, categoryName, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
resultList.add(new ImageSet(categoryName, imageItems));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.util;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.AppDatabase;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.dao.PureWallpaperDao;
|
||||||
|
import com.pure.wallpaper.purewallpaper.sqlite.database.data.PureWallpaper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PaletteViewModel extends AndroidViewModel {
|
||||||
|
|
||||||
|
private final PureWallpaperDao pureWallpaperDao;
|
||||||
|
|
||||||
|
public PaletteViewModel(Application application) {
|
||||||
|
super(application);
|
||||||
|
AppDatabase db = AppDatabase.getInstance(application);
|
||||||
|
pureWallpaperDao = db.pureWallpaperDao();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<PureWallpaper>> getAllFavorite() {
|
||||||
|
return pureWallpaperDao.getFavorite();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<PureWallpaper>> getFirstByName() {
|
||||||
|
return pureWallpaperDao.getCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<PureWallpaper>> getAllCategory(String name) {
|
||||||
|
return pureWallpaperDao.getAllCategory(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Boolean> getLike(String source, String name) {
|
||||||
|
return pureWallpaperDao.getCollection(source, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(PureWallpaper pureWallpaper) {
|
||||||
|
pureWallpaperDao.update(pureWallpaper);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.util;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
public interface PureListener {
|
||||||
|
void onPrepare();
|
||||||
|
void onSuccess(Uri uri);
|
||||||
|
void onError();
|
||||||
|
}
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.util;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
public class PureUtils {
|
||||||
|
public static final int PERMISSION_CODE_STORAGE = 302;
|
||||||
|
private final ExecutorService taskExecutor = Executors.newFixedThreadPool(1);
|
||||||
|
|
||||||
|
public void setWallpaper(Activity activity, String imageUrl, PureListener callback) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
initiateDownload(activity, imageUrl, callback);
|
||||||
|
} else {
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
activity,
|
||||||
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
PERMISSION_CODE_STORAGE
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
initiateDownload(activity, imageUrl, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initiateDownload(Activity activity, String sourceUrl, PureListener callback) {
|
||||||
|
callback.onPrepare();
|
||||||
|
|
||||||
|
taskExecutor.submit(() -> {
|
||||||
|
Uri savedUri = saveMediaImage(activity, sourceUrl);
|
||||||
|
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
|
if (savedUri != null) {
|
||||||
|
callback.onSuccess(savedUri);
|
||||||
|
} else {
|
||||||
|
callback.onError();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uri saveMediaImage(Activity activity, String imageUrl) {
|
||||||
|
String name = "photo_" + System.nanoTime() + ".jpeg";
|
||||||
|
|
||||||
|
ContentValues metadata = new ContentValues();
|
||||||
|
metadata.put(MediaStore.Images.Media.DISPLAY_NAME, name);
|
||||||
|
metadata.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
metadata.put(MediaStore.Images.Media.IS_PENDING, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri destinationUri = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
|
||||||
|
? MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
|
||||||
|
: MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||||
|
|
||||||
|
Uri imageUri = activity.getContentResolver().insert(destinationUri, metadata);
|
||||||
|
if (imageUri == null) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
URL url = new URL(imageUrl);
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
conn.connect();
|
||||||
|
|
||||||
|
try (InputStream inStream = conn.getInputStream();
|
||||||
|
OutputStream outStream = activity.getContentResolver().openOutputStream(imageUri)) {
|
||||||
|
if (outStream == null) return null;
|
||||||
|
|
||||||
|
byte[] data = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inStream.read(data)) > 0) {
|
||||||
|
outStream.write(data, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
metadata.clear();
|
||||||
|
metadata.put(MediaStore.Images.Media.IS_PENDING, 0);
|
||||||
|
activity.getContentResolver().update(imageUri, metadata, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageUri;
|
||||||
|
} catch (IOException e) {
|
||||||
|
activity.getContentResolver().delete(imageUri, null, null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.pure.wallpaper.purewallpaper.util;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
|
||||||
|
|
||||||
|
public class StaggeredGridItemDecoration extends RecyclerView.ItemDecoration {
|
||||||
|
private final int spacing;
|
||||||
|
private final int spanCount;
|
||||||
|
|
||||||
|
public StaggeredGridItemDecoration(int spacing, int spanCount) {
|
||||||
|
this.spacing = spacing;
|
||||||
|
this.spanCount = spanCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, @NonNull View view, RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||||
|
int position = parent.getChildAdapterPosition(view);
|
||||||
|
StaggeredGridLayoutManager.LayoutParams params = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
|
||||||
|
int spanIndex = params.getSpanIndex();
|
||||||
|
|
||||||
|
outRect.left = spacing - (spanIndex * spacing) / spanCount;
|
||||||
|
outRect.right = ((spanIndex + 1) * spacing) / spanCount;
|
||||||
|
|
||||||
|
if (position < spanCount) {
|
||||||
|
outRect.top = spacing;
|
||||||
|
}
|
||||||
|
outRect.bottom = spacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
app/src/main/res/anim/item_fall_down.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!-- res/anim/item_fall_down.xml -->
|
||||||
|
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<translate
|
||||||
|
android:fromYDelta="-50%"
|
||||||
|
android:toYDelta="0%"
|
||||||
|
android:duration="500" />
|
||||||
|
<alpha
|
||||||
|
android:fromAlpha="0.0"
|
||||||
|
android:toAlpha="1.0"
|
||||||
|
android:duration="500" />
|
||||||
|
</set>
|
||||||
5
app/src/main/res/anim/layout_animation_fall_down.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<!-- res/anim/layout_animation_fall_down.xml -->
|
||||||
|
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:animation="@anim/item_fall_down"
|
||||||
|
android:animationOrder="normal"
|
||||||
|
android:delay="15%" />
|
||||||
15
app/src/main/res/drawable/apply_to.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M912.2,637.2a30.7,30.7 0,0 0,-22.9 9.5,32.9 32.9,0 0,0 -9.4,22.9v59.7L258.9,729.4L258.9,141.8h116.5a32.6,32.6 0,0 0,32.4 -32.4,32.2 32.2,0 0,0 -31.9,-31.9L226,77.5a30.7,30.7 0,0 0,-30.7 30.7v121.7h-85.8a30.7,30.7 0,0 0,-30.7 30.7v654.3a30.7,30.7 0,0 0,30.7 30.7h687.7a30.7,30.7 0,0 0,30.7 -30.7L827.9,793.6h85.7a30.7,30.7 0,0 0,30.7 -30.7v-92.2a33.2,33.2 0,0 0,-32.4 -32.9zM225.3,792.7h537.5L762.8,880.6L141.8,880.6L141.8,293.2L194.6,293.2v468.6a30.7,30.7 0,0 0,30.7 30.7zM225.3,792.7"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M457,571.6a282.7,282.7 0,1 0,-82.6 -199.8,277.2 277.2,0 0,0 82.6,199.8zM439.1,371.8a217.6,217.6 0,1 1,217.6 217.7,217.8 217.8,0 0,1 -217.6,-217.7zM439.1,371.8"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M614.4,457a38.9,38.9 0,0 0,26.8 11.5,36 36,0 0,0 26.9,-11.5l117.6,-117.6a37.7,37.7 0,0 0,11.5 -26.8,36.9 36.9,0 0,0 -11.5,-26.9 37.9,37.9 0,0 0,-26.9 -11.5,36.4 36.4,0 0,0 -26.9,11.5l-90.6,90.6 -40.2,-41a37.8,37.8 0,0 0,-26.9 -11.4,37 37,0 0,0 -26.9,11.4 37.9,37.9 0,0 0,-11.5 26.9A36.1,36.1 0,0 0,547.1 389.1zM614.4,457"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/back.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M800,480H268.8l233.6,-233.6c12.8,-12.8 12.8,-32 0,-44.8 -12.8,-12.8 -32,-12.8 -44.8,0l-284.8,288c-12.8,12.8 -12.8,32 0,44.8h3.2l284.8,288c6.4,6.4 16,9.6 22.4,9.6 9.6,0 16,-3.2 22.4,-9.6 12.8,-12.8 12.8,-32 0,-44.8L272,544h528c19.2,0 32,-12.8 32,-32s-16,-32 -32,-32z"/>
|
||||||
|
</vector>
|
||||||
18
app/src/main/res/drawable/collection.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M42.7,469.3C42.7,233.7 233.7,42.7 469.3,42.7s426.7,191 426.7,426.7a42.7,42.7 0,1 1,-85.3 0,341.3 341.3,0 1,0 -341.3,341.3 42.7,42.7 0,1 1,0 85.3C233.7,896 42.7,705 42.7,469.3z"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:fillAlpha="0.85"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M597.3,722C597.3,659.5 642,597.3 710.4,597.3c21.6,0 41.1,6.5 57.6,17.3A104.5,104.5 0,0 1,825.6 597.3c68.4,0 113.1,62.2 113.1,124.7 0,55.1 -27.5,103.8 -57.3,138.9 -29.7,35 -67.2,63 -97.9,74.9a42.7,42.7 0,0 1,-30.8 0c-30.7,-11.9 -68.2,-39.9 -97.9,-74.9 -29.8,-35.1 -57.3,-83.8 -57.3,-138.8zM710.4,682.7c-9.4,0 -27.7,11.3 -27.7,39.4 0,26.9 14.1,56.6 37,83.6 16.3,19.1 34.2,33.6 48.3,42.5a217.8,217.8 0,0 0,48.3 -42.5c23,-27 37,-56.7 37,-83.6 0,-28.1 -18.3,-39.3 -27.7,-39.3 -6.4,0 -14.7,3.6 -21.1,14.3a42.7,42.7 0,0 1,-73 0c-6.4,-10.6 -14.7,-14.3 -21.1,-14.3zM469.3,320a149.3,149.3 0,1 0,0 298.7,149.3 149.3,0 0,0 0,-298.7zM405.3,469.3a64,64 0,1 1,128 0,64 64,0 0,1 -128,0z"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:fillAlpha="0.85"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M469.3,405.3a64,64 0,1 0,0 128,64 64,0 0,0 0,-128z"
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:fillAlpha="0.85"/>
|
||||||
|
</vector>
|
||||||
8
app/src/main/res/drawable/dialog_background.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/gray" />
|
||||||
|
<corners android:radius="6dp" />
|
||||||
|
</shape>
|
||||||
9
app/src/main/res/drawable/download.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M469.3,570.2v-256h85.4v256h128L512,756.3 341.3,570.2h128zM1024,640.1C1024,782.9 919.9,896 787.6,896h-512C123.9,896 0,761.6 0,597.5 0,452 94.7,331.5 226.4,303 284.2,195.5 391.8,128 512,128c152.3,0 282.1,108.4 323.4,261.1C941.9,413.4 1024,519 1024,640.2zM764.8,434.8c-24.4,-129 -128.9,-222.7 -252.8,-222.7 -97.3,0 -183,57.3 -224.6,147.5l-9.3,20.2 -20.9,2.9c-103.4,14.4 -178.4,104.3 -178.4,214.7 0,118 88.8,214.4 196.9,214.4h512c88.3,0 157.5,-75.1 157.5,-171.7 0,-88.1 -65.9,-164.9 -145,-171.8l-29.5,-2.6 -5.9,-31z"
|
||||||
|
android:fillColor="@color/gray"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/favorite.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="56.9dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1821"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF0000"
|
||||||
|
android:pathData="M596.5,402.5h-65.6c-34,0 -63.1,29.1 -63.1,63.1v398.1c0,36.4 26.7,65.6 63.1,65.6h65.6c21.9,0 41.2,-12.1 41.2,-26.7L637.7,429.3c0,-14.7 -19.5,-26.8 -41.2,-26.8zM1264,385.6L1067.3,385.6c-14.5,-2.4 -19.5,-16.9 -21.9,-24.3L1045.5,184.1c0,-48.5 -38.8,-87.3 -87.3,-87.3 -43.7,0 -80.1,34 -87.3,75.2 -26.7,167.5 -128.7,223.3 -194.1,240.3 2.4,7.3 2.4,12.1 2.4,16.9v470.9c0,9.7 -2.4,19.5 -7.3,29.1h475.7c46.1,-9.7 77.7,-26.7 99.5,-72.8l99.5,-349.5c19.5,-63.1 -12,-123.7 -82.4,-121.3zM1150.3,682.4l-24,24 0.3,0.3 -131.7,131.7 -0.3,-0.3 -0.3,0.3 -131.7,-131.7 0.3,-0.3 -24,-24c-36.1,-36.1 -36.1,-95.2 0,-131.3l0.3,-0.3c36.1,-36.1 95.2,-36.1 131.3,0l24,24 24,-24c36.1,-36.1 95.2,-36.1 131.3,0l0.3,0.3c36.4,36 36.4,95.2 0.3,131.3z"/>
|
||||||
|
</vector>
|
||||||
7
app/src/main/res/drawable/gradient_overlay.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<!-- res/drawable/gradient_overlay.xml -->
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:startColor="#00000000"
|
||||||
|
android:endColor="#CC000000"
|
||||||
|
android:angle="270" />
|
||||||
|
</shape>
|
||||||
18
app/src/main/res/drawable/main.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M148.4,107l282.2,0c22.3,0 40.3,18 40.3,40.3l0,282.2c0,22.3 -18,40.3 -40.3,40.3L148.4,469.8c-22.3,0 -40.3,-18 -40.3,-40.3L108.1,147.3C108.1,125 126.1,107 148.4,107z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M147.6,553.5 L429.7,553.5c22.3,0 40.3,18 40.3,40.3l0,282.2c0,22.3 -18,40.3 -40.3,40.3L147.6,916.3c-22.3,0 -40.3,-18 -40.3,-40.3L107.2,593.8C107.2,571.5 125.3,553.5 147.6,553.5z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M593.9,107l282.2,0c22.3,0 40.3,18 40.3,40.3l0,282.2c0,22.3 -18,40.3 -40.3,40.3L593.9,469.8c-22.3,0 -40.3,-18 -40.3,-40.3L553.6,147.3C553.6,125 571.7,107 593.9,107z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M730.2,920.5 L623.9,920.5c-40.9,0 -74.2,-33.4 -74.2,-74.4L549.7,624c0,-41 33.4,-74.4 74.4,-74.4l222.1,0c41,0 74.4,33.2 74.4,74.1L920.6,737.9c0,10.2 -8.3,18.5 -18.5,18.5s-18.5,-8.3 -18.5,-18.5L883.5,623.6c0,-20.4 -16.7,-37 -37.3,-37L624.1,586.7c-20.6,0 -37.3,16.7 -37.3,37.3l0,222.1c0,20.6 16.7,37.3 37.1,37.3l106.3,0c10.2,0 18.5,8.3 18.5,18.5C748.8,912.2 740.5,920.5 730.2,920.5z"/>
|
||||||
|
</vector>
|
||||||
30
app/src/main/res/drawable/progress_color.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!-- res/drawable/seekbar_progress_drawable.xml -->
|
||||||
|
<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/secondaryProgress">
|
||||||
|
<clip>
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
<solid android:color="#FFD700" />
|
||||||
|
</shape>
|
||||||
|
</clip>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:id="@android:id/progress">
|
||||||
|
<clip>
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="5dp" />
|
||||||
|
<gradient
|
||||||
|
android:startColor="#4891FF"
|
||||||
|
android:endColor="#6CE89E"
|
||||||
|
android:angle="0" />
|
||||||
|
</shape>
|
||||||
|
</clip>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
9
app/src/main/res/drawable/rounded_gradient.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<gradient
|
||||||
|
android:angle="45"
|
||||||
|
android:endColor="#BBDEFB"
|
||||||
|
android:startColor="#F5F5F5"
|
||||||
|
android:type="linear"
|
||||||
|
android:useLevel="false" />
|
||||||
|
<corners android:radius="16sp" />
|
||||||
|
</shape>
|
||||||
18
app/src/main/res/drawable/un_collection.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M42.7,469.3C42.7,233.7 233.7,42.7 469.3,42.7s426.7,191 426.7,426.7a42.7,42.7 0,1 1,-85.3 0,341.3 341.3,0 1,0 -341.3,341.3 42.7,42.7 0,1 1,0 85.3C233.7,896 42.7,705 42.7,469.3z"
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:fillAlpha="0.85"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M597.3,722C597.3,659.5 642,597.3 710.4,597.3c21.6,0 41.1,6.5 57.6,17.3A104.5,104.5 0,0 1,825.6 597.3c68.4,0 113.1,62.2 113.1,124.7 0,55.1 -27.5,103.8 -57.3,138.9 -29.7,35 -67.2,63 -97.9,74.9a42.7,42.7 0,0 1,-30.8 0c-30.7,-11.9 -68.2,-39.9 -97.9,-74.9 -29.8,-35.1 -57.3,-83.8 -57.3,-138.8zM710.4,682.7c-9.4,0 -27.7,11.3 -27.7,39.4 0,26.9 14.1,56.6 37,83.6 16.3,19.1 34.2,33.6 48.3,42.5a217.8,217.8 0,0 0,48.3 -42.5c23,-27 37,-56.7 37,-83.6 0,-28.1 -18.3,-39.3 -27.7,-39.3 -6.4,0 -14.7,3.6 -21.1,14.3a42.7,42.7 0,0 1,-73 0c-6.4,-10.6 -14.7,-14.3 -21.1,-14.3zM469.3,320a149.3,149.3 0,1 0,0 298.7,149.3 149.3,0 0,0 0,-298.7zM405.3,469.3a64,64 0,1 1,128 0,64 64,0 0,1 -128,0z"
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:fillAlpha="0.85"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M469.3,405.3a64,64 0,1 0,0 128,64 64,0 0,0 0,-128z"
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:fillAlpha="0.85"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/un_favorite.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="56.9dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1821"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M596.5,402.5h-65.6c-34,0 -63.1,29.1 -63.1,63.1v398.1c0,36.4 26.7,65.6 63.1,65.6h65.6c21.9,0 41.2,-12.1 41.2,-26.7L637.7,429.3c0,-14.7 -19.5,-26.8 -41.2,-26.8zM1264,385.6L1067.3,385.6c-14.5,-2.4 -19.5,-16.9 -21.9,-24.3L1045.5,184.1c0,-48.5 -38.8,-87.3 -87.3,-87.3 -43.7,0 -80.1,34 -87.3,75.2 -26.7,167.5 -128.7,223.3 -194.1,240.3 2.4,7.3 2.4,12.1 2.4,16.9v470.9c0,9.7 -2.4,19.5 -7.3,29.1h475.7c46.1,-9.7 77.7,-26.7 99.5,-72.8l99.5,-349.5c19.5,-63.1 -12,-123.7 -82.4,-121.3zM1150.3,682.4l-24,24 0.3,0.3 -131.7,131.7 -0.3,-0.3 -0.3,0.3 -131.7,-131.7 0.3,-0.3 -24,-24c-36.1,-36.1 -36.1,-95.2 0,-131.3l0.3,-0.3c36.1,-36.1 95.2,-36.1 131.3,0l24,24 24,-24c36.1,-36.1 95.2,-36.1 131.3,0l0.3,0.3c36.4,36 36.4,95.2 0.3,131.3z"/>
|
||||||
|
</vector>
|
||||||
18
app/src/main/res/drawable/un_main.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M148.4,107l282.2,0c22.3,0 40.3,18 40.3,40.3l0,282.2c0,22.3 -18,40.3 -40.3,40.3L148.4,469.8c-22.3,0 -40.3,-18 -40.3,-40.3L108.1,147.3C108.1,125 126.1,107 148.4,107z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M147.6,553.5 L429.7,553.5c22.3,0 40.3,18 40.3,40.3l0,282.2c0,22.3 -18,40.3 -40.3,40.3L147.6,916.3c-22.3,0 -40.3,-18 -40.3,-40.3L107.2,593.8C107.2,571.5 125.3,553.5 147.6,553.5z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M593.9,107l282.2,0c22.3,0 40.3,18 40.3,40.3l0,282.2c0,22.3 -18,40.3 -40.3,40.3L593.9,469.8c-22.3,0 -40.3,-18 -40.3,-40.3L553.6,147.3C553.6,125 571.7,107 593.9,107z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray"
|
||||||
|
android:pathData="M730.2,920.5 L623.9,920.5c-40.9,0 -74.2,-33.4 -74.2,-74.4L549.7,624c0,-41 33.4,-74.4 74.4,-74.4l222.1,0c41,0 74.4,33.2 74.4,74.1L920.6,737.9c0,10.2 -8.3,18.5 -18.5,18.5s-18.5,-8.3 -18.5,-18.5L883.5,623.6c0,-20.4 -16.7,-37 -37.3,-37L624.1,586.7c-20.6,0 -37.3,16.7 -37.3,37.3l0,222.1c0,20.6 16.7,37.3 37.1,37.3l106.3,0c10.2,0 18.5,8.3 18.5,18.5C748.8,912.2 740.5,920.5 730.2,920.5z"/>
|
||||||
|
</vector>
|
||||||
41
app/src/main/res/layout/activity_category.xml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?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"
|
||||||
|
tools:context=".ui.activity.CategoryActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/title"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/title" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/title" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -5,15 +5,37 @@
|
|||||||
android:id="@+id/main"
|
android:id="@+id/main"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".ui.activity.MainActivity">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Hello World!"
|
android:layout_marginTop="16dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:gravity="center"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tab_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="75dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||||
|
app:tabIndicatorHeight="0dp"
|
||||||
|
app:tabRippleColor="@android:color/transparent" />
|
||||||
|
|
||||||
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
|
android:id="@+id/view_pager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tab_layout" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
123
app/src/main/res/layout/activity_pure.xml
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<?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"
|
||||||
|
tools:context=".ui.activity.PureActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/back"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:background="@drawable/dialog_background"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:src="@drawable/back"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/top_action_bar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginEnd="32dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/like"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:src="@drawable/un_favorite" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/down"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="6dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:src="@drawable/download" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/down_progress"
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminateTint="@android:color/white"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/set"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="6dp"
|
||||||
|
android:src="@drawable/apply_to" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/bottom_hint"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:alpha="0.7"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingVertical="8dp"
|
||||||
|
android:text="双击屏幕点赞,滑动切换壁纸"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/gray"
|
||||||
|
android:focusable="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
49
app/src/main/res/layout/activity_splash.xml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?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"
|
||||||
|
tools:context=".ui.activity.SplashActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="150dp"
|
||||||
|
android:layout_height="150dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.388" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textSize="25sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/image" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="10dp"
|
||||||
|
android:layout_marginStart="53dp"
|
||||||
|
android:layout_marginEnd="53dp"
|
||||||
|
android:layout_marginBottom="80dp"
|
||||||
|
android:max="100"
|
||||||
|
android:progress="0"
|
||||||
|
android:progressDrawable="@drawable/progress_color"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
31
app/src/main/res/layout/custom_tab.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingTop="5dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="32dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/text"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/image" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
98
app/src/main/res/layout/detail_dialog.xml
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<?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"
|
||||||
|
android:layout_width="250dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="@drawable/rounded_gradient">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:text="@string/set_as_wallpaper"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/both"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
android:background="@drawable/dialog_background"
|
||||||
|
android:padding="12dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/title">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="BOTH"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/lock"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:background="@drawable/dialog_background"
|
||||||
|
android:padding="12dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/both">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/lock_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="LOCK"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/desktop"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="24dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:background="@drawable/dialog_background"
|
||||||
|
android:padding="12dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/lock">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="DESKTOP"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
16
app/src/main/res/layout/fragment_collection.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ui.fragment.CollectionFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
17
app/src/main/res/layout/fragment_home.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ui.fragment.HomeFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
40
app/src/main/res/layout/item_to_fragment.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="8dp"
|
||||||
|
app:cardUseCompatPadding="true">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="250dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/gradient_overlay"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
android:background="@drawable/gradient_overlay"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/category_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
30
app/src/main/res/layout/item_to_pure.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="16dp"
|
||||||
|
app:cardElevation="8dp"
|
||||||
|
app:cardUseCompatPadding="true">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="250dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:scaleType="centerCrop" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/favorite"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:src="@drawable/un_favorite"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
|
||||||
</adaptive-icon>
|
|
||||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/placeholder.png
Normal file
|
After Width: | Height: | Size: 463 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
@ -2,4 +2,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<color name="black">#FF000000</color>
|
<color name="black">#FF000000</color>
|
||||||
<color name="white">#FFFFFFFF</color>
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
<color name="gray">#9C979D</color>
|
||||||
</resources>
|
</resources>
|
||||||
@ -1,3 +1,4 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Pure Wallpaper</string>
|
<string name="app_name">Pure Wallpaper</string>
|
||||||
|
<string name="set_as_wallpaper">Set as Wallpaper</string>
|
||||||
</resources>
|
</resources>
|
||||||
@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp = "8.9.1"
|
agp = "8.10.1"
|
||||||
junit = "4.13.2"
|
junit = "4.13.2"
|
||||||
junitVersion = "1.2.1"
|
junitVersion = "1.2.1"
|
||||||
espressoCore = "3.6.1"
|
espressoCore = "3.6.1"
|
||||||
|
|||||||
6
keystore.properties
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
app_name=Pure Wallpaper
|
||||||
|
package_name=com.pure.wallpaper.purewallpaper
|
||||||
|
keystoreFile=app/PureWallpaper.jks
|
||||||
|
key_alias=PureWallpaperkey0
|
||||||
|
key_store_password=PureWallpaper
|
||||||
|
key_password=PureWallpaper
|
||||||