V1.0.0(1)

This commit is contained in:
litingting 2024-12-25 17:14:21 +08:00
commit ce9c7fd2be
115 changed files with 86972 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

1
app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

BIN
app/HavenWallpapers.jks Normal file

Binary file not shown.

68
app/build.gradle.kts Normal file
View File

@ -0,0 +1,68 @@
import java.util.Date
import java.text.SimpleDateFormat
plugins {
alias(libs.plugins.android.application)
id ("org.jetbrains.kotlin.android")
kotlin("kapt")
}
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
android {
namespace = "com.haven.wallpapers"
compileSdk = 34
defaultConfig {
applicationId = "com.haven.photo.wallpapers"
minSdk = 23
//noinspection OldTargetApi
targetSdk = 34
versionCode = 2
versionName = "1.0.1"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
setProperty("archivesBaseName", "Haven Wallpapers_V" + versionName + "(${versionCode})_$timestamp")
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
buildFeatures {
viewBinding = true
}
}
dependencies {
//noinspection UseTomlInstead
kapt( "androidx.room:room-compiler:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
androidTestImplementation("androidx.room:room-testing:2.6.1")
//noinspection GradleDependency
implementation("androidx.viewpager2:viewpager2:1.0.0")
implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("com.google.code.gson:gson:2.10.1")
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
implementation ("jp.wasabeef:glide-transformations:4.3.0")
}

41
app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,41 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keepclassmembers class com.haven.wallpapers.MyApp {
public static final java.lang.String dadgsfgsf;
public static final int aadasdasd;
}
-keepclassmembers class * {
@androidx.room.Query <methods>;
}
-keep class com.haven.wallpapers.room.AppDatabase { *; }
-keep class com.haven.wallpapers.jsonbean.Info { *; }
-keep class com.google.gson.** { *; }
-keepattributes Signature
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken
-keepattributes AnnotationDefault,RuntimeVisibleAnnotations

View File

@ -0,0 +1,26 @@
package com.haven.wallpapers;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.lh.wallpaper2", appContext.getPackageName());
}
}

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<application
android:name=".MyApp"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher_foreground"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_foreground"
android:supportsRtl="true"
android:theme="@style/Theme.Wallpaper2"
tools:targetApi="31">
<activity
android:name=".activity.MainActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name=".activity.DetailsActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name=".activity.ViewActivity"
android:screenOrientation="portrait"
android:exported="false" />
<activity
android:name=".activity.InitialActivity"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

File diff suppressed because it is too large Load Diff

20702
app/src/main/assets/film.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

View File

@ -0,0 +1,96 @@
package com.haven.wallpapers;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.haven.wallpapers.Utils.ReadFile;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.jsonbean.Info;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class MyApp extends Application {
public static Context mAppContext;
private static List<Info> userList = new ArrayList<Info>();
public static final String dadgsfgsf = "app_database";
public static final int aadasdasd = 1;
private static MultiTransformation<Bitmap> multiTransformation;
public static String TAG = "-------Wallpaper----------";
private static int placeImg;
@Override
public void onCreate() {
super.onCreate();
mAppContext = this;
placeImg = R.drawable.im_placeholder;
multiTransformation = new MultiTransformation<>(
new CenterCrop(),
new RoundedCornersTransformation(ReadFile.dp2Px(12), 0)
);
String name[] = {"animals.json", "film.json", "nature.json", "textures-patterns.json"};
ExecutorService cachedThreadPool = Executors.newFixedThreadPool(4);
for (int i = 0; i < name.length; i++) {
int task = i;
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
InputStream open = getAssets().open(name[task]);
String covertStr = ReadFile.getCovertStr(open);
if (!covertStr.isEmpty()) {
List<Data> list = ReadFile.getData( covertStr);
Info info = new Info();
int index = name[task].indexOf(".json");
String substring = name[task].substring(0, index);
info.setName(substring);
info.setList(list);
userList.add(info);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
if (task == 3) {
Log.d("------------", "-------------shutdownNow");
cachedThreadPool.shutdownNow();
}
}
});
}
}
public static int getPlaceImg() {
return placeImg;
}
public static MultiTransformation<Bitmap> getMultiTransformation() {
return multiTransformation;
}
public static Context getmAppContext() {
return mAppContext;
}
public static List<Info> getUserList() {
Log.d("------------", "-------------userList=" + userList.size());
return userList;
}
}

View File

@ -0,0 +1,71 @@
package com.haven.wallpapers.Utils;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log;
import com.haven.wallpapers.listener.OnDownloadListener;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class DownloadTask extends AsyncTask<String, Void, Boolean> {
private OnDownloadListener listener;
private Context context;
public DownloadTask(OnDownloadListener listener, Context context) {
this.listener = listener;
this.context = context;
}
@Override
protected Boolean doInBackground(String... params) {
String imageUrl = params[0];
String type = params[1];
HttpURLConnection connection = null;
try {
URL url = new URL(imageUrl);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream inputStream = connection.getInputStream();
Uri uri = Save.saveToGallery(context, inputStream);
if (uri == null) {
listener.onDownloadResult(false,inputStream,type);
return false;
}
listener.onDownloadResult(true,inputStream,type);
return true;
} else {
Log.e("ImageDownloadTask", "Server returned HTTP " + responseCode + " " + connection.getResponseMessage());
}
} catch (Exception e) {
Log.e("ImageDownloadTask", "Error downloading image", e);
} finally {
if (connection != null) {
Log.e("--------------", "disconnect");
connection.disconnect();
}
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
// if (activity != null && !activity.isFinishing() && !activity.isDestroyed()) {
// activity.findViewById(R.id.progressbar).setVisibility(View.GONE);
// if (result) {
// Toast.makeText(context, "Image downloaded successfully", Toast.LENGTH_SHORT).show();
// } else {
// Toast.makeText(context, "Failed to download image", Toast.LENGTH_SHORT).show();
// }
// }
}
}

View File

@ -0,0 +1,54 @@
package com.haven.wallpapers.Utils;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class MyItemSpace extends RecyclerView.ItemDecoration {
private int ex_space = 0;
private int v_space = 0;
private int h_space = 0;
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
int spanSize = 1;
int spanIndex = 0;
int spanCount = 1;
RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
if (layoutManager instanceof GridLayoutManager) {
GridLayoutManager layoutManager1 = (GridLayoutManager) layoutManager;
GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams();
spanCount = layoutManager1.getSpanCount();
spanSize = layoutManager1.getSpanSizeLookup().getSpanSize(position);
spanIndex = layoutParams.getSpanIndex();
}
if (spanSize == spanCount) {
outRect.left = v_space + ex_space;
outRect.right = v_space + ex_space;
outRect.bottom = h_space;
} else {
int itemAllSpacing = (v_space * (spanCount + 1) + ex_space * 2) / spanCount;
int left = v_space * (spanIndex + 1) - itemAllSpacing * spanIndex + ex_space;
int right = itemAllSpacing - left;
outRect.left = left;
outRect.right = right;
outRect.bottom = h_space;
}
}
public MyItemSpace(int v_space, int h_space, int ex_space) {
this.ex_space = ex_space;
this.h_space = h_space;
this.v_space = v_space;
}
}

View File

@ -0,0 +1,11 @@
package com.haven.wallpapers.Utils;
public class MyValue {
public static final String key_info = "key_info";
public static final String key_source = "key_source";
public static final String key_Import = "key_import";
public static final String key_like = "key_like";
public static final String key_data = "key_data";
}

View File

@ -0,0 +1,138 @@
package com.haven.wallpapers.Utils;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.jsonbean.Data;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class ReadFile {
public static String getCovertStr(InputStream stream) {
String covertStr = "";
try {
StringWriter writer = new StringWriter();
char[] buffer = new char[stream.available()];
Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
int a = 0;
while ((a = reader.read(buffer)) != -1) {
writer.write(buffer, 0, a);
}
covertStr = writer.toString();
} catch (IOException e) {
return covertStr;
}
return covertStr;
}
public static int dp2Px(int dp) {
float scale = MyApp.mAppContext.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
public static List<Data> getData( String jsonStr) {
try {
JSONArray jsonArray = new JSONArray(jsonStr);
List<Data> data = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject get = jsonArray.getJSONObject(i);
String textDescription = get.optString("alt_description");
// Extract links object and its properties
JSONObject links = get.optJSONObject("links");
String download = links.optString("download");
String downloadLocation = links.optString("download_location");
String html = links.optString("html");
// Extract urls object and its properties
JSONObject urls = get.optJSONObject("urls");
String full = urls.optString("full");
String raw = urls.optString("raw");
String regular = urls.optString("regular");
String small = urls.optString("small");
String thumb = urls.optString("thumb");
// Extract user object and its properties
JSONObject users = get.optJSONObject("user");
String portfolioUrl = users.optString("portfolio_url");
String name = users.optString("name");
String headerLarge = users.optString("header_large");
String headerMedium = users.optString("header_medium");
String headerSmall = users.optString("header_small");
String userHtml = users.optString("authorHtml");
String host = "https://unsplash.com/photos/";
// Extract the ID from the download URL
int indexOf = download.indexOf("/download");
String substring = download.substring(host.length(), indexOf);
// Create a new Data object and populate it with the extracted values
Data bean = new Data();
bean.setImId(substring);
bean.setDescription(textDescription);
bean.setFullUrl(download);
bean.setPreviewUrl1080(regular);
bean.setPreviewUrl400(small);
bean.setPreviewUrl200(thumb);
// Add the Data object to the result list
data.add(bean);
} catch (Exception e) {
e.printStackTrace();
}
}
return data;
}catch (JSONException exception){
return null;
}
// Initialize a new JSON array from the input string
// Loop through the JSON array and extract data
// Return the list of Data objects
}
public static void initFull(Activity activity, boolean light) {
Window window = activity.getWindow();
View decorView = window.getDecorView();
View rootView = decorView.getRootView();
if (light) {
} else {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
}
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}

View File

@ -0,0 +1,165 @@
package com.haven.wallpapers.Utils;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.util.Log;
import com.haven.wallpapers.MyApp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Save {
public static Uri saveToGallery(Context context, InputStream photoFile) {
String displayName = System.currentTimeMillis()+".jpg";
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, displayName);
contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.put(MediaStore.Images.Media.IS_PENDING, 1);
}
Uri collectionUri;
ContentResolver contentResolver = context.getContentResolver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collectionUri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
} else {
collectionUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
Uri imageUri = contentResolver.insert(collectionUri, contentValues);
if (imageUri == null) {
return null;
}
OutputStream outputStream = null;
try {
int byteLength = 0;
byte[] bytes = new byte[4096];
outputStream = contentResolver.openOutputStream(imageUri);
while ((byteLength = photoFile.read(bytes)) != -1) {
outputStream.write(bytes, 0, byteLength);
}
photoFile.close();
outputStream.close();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.clear();
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0);
contentResolver.update(imageUri, contentValues, null, null);
}
return imageUri;
} catch (Exception exception) {
return null;
}
}
public static boolean writeFile(InputStream input, String filePath) {
try {
// Create a buffer for reading bytes from the input stream
byte[] byteArray = new byte[4096];
ByteArrayOutputStream output = new ByteArrayOutputStream();
int bytesRead;
// Read from the input stream and write to the output stream
while ((bytesRead = input.read(byteArray)) != -1) {
output.write(byteArray, 0, bytesRead);
}
// Create a File object for the given file path
File fileDe = new File(filePath);
// Check if file doesn't exist, create a new file
if (!fileDe.exists()) {
fileDe.createNewFile();
}
// Write the content to the file
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
fileOutputStream.write(output.toByteArray());
// Close streams
output.close();
fileOutputStream.close();
return true;
} catch (IOException ex) {
// Log the error message
Log.d("-----------", "---------ex=" + ex.getMessage());
return false;
}
}
public static String getSaveFilePath( String imId) {
// Return the file path by concatenating cache directory and image ID with the .jpg extension
return MyApp.getmAppContext().getCacheDir().getAbsolutePath() + "/" + imId + ".jpg";
}
public static String saveDrawableToFile(Drawable drawable, String saveFilePath) {
// Drawable 转换为 Bitmap
Bitmap bitmap = getMyBitmap(drawable);
// 创建要保存的文件
File file = new File(saveFilePath);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
// Bitmap 写入文件 (使用 PNG 格式可改为 JPEG)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file.getAbsolutePath();
}
private static Bitmap getMyBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
// 创建一个空白的 Bitmap
Bitmap bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
// Canvas 上绘制 Drawable
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}

View File

@ -0,0 +1,75 @@
package com.haven.wallpapers.activity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.MyValue;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.listener.UrlListener;
import com.haven.wallpapers.adapter.DetailsAdapter;
import com.haven.wallpapers.Utils.MyItemSpace;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.jsonbean.Info;
import java.util.List;
public class DetailsActivity extends AppCompatActivity implements UrlListener {
private TextView textView;
private String name;
private RecyclerView recyclerView;
private ImageView imageView;
private List<Data> dataList;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_details);
textView = findViewById(R.id.details_text);
recyclerView = findViewById(R.id.details_recyclerView);
name = getIntent().getStringExtra(MyValue.key_info);
textView.setText(name); // 如果 name null 或空直接设置
setRecyclerView();
imageView = findViewById(R.id.imageview_back);
imageView.setOnClickListener(v -> finish());
}
private void setRecyclerView() {
for (Info info : MyApp.getUserList()) {
if(info.getName().equals(name)){
dataList = info.getList();
break;
}
}
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
DetailsAdapter detailsAdapter = new DetailsAdapter(dataList, this);
detailsAdapter.setUrlWallpaperListener(this);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(detailsAdapter);
MyItemSpace myItemSpace = new MyItemSpace(30, 50, 40);
recyclerView.addItemDecoration(myItemSpace);
}
@Override
public void onItemClickAction(Data dataInfo) {
startActivity(new Intent(this, ViewActivity.class).putExtra(MyValue.key_data, dataInfo));
}
}

View File

@ -0,0 +1,68 @@
package com.haven.wallpapers.activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.ReadFile;
public class InitialActivity extends AppCompatActivity {
private ProgressBar progressBar;
private CountDownTimer countDownTimer;
private static final long totalTime = 3000; // 倒计时总时间
private static final String TAG = "InitialActivity"; // 日志标签
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_initial);
ReadFile.initFull(InitialActivity.this,false);
progressBar = findViewById(R.id.progressBar);
// 重置进度条到初始状态
progressBar.setProgress(0);
countDownTimer = new CountDownTimer(totalTime,100) {
@Override
public void onTick(long millisUntilFinished) {
int percentage = (int) (100 - (float) millisUntilFinished / totalTime * 100);
progressBar.setProgress(percentage);
}
@Override
public void onFinish() {
startMain();
}
};
countDownTimer.start();
}
// 跳转到主界面的方法
private void startMain() {
// 确保进度条更新至满值
progressBar.setProgress(100);
// 跳转到主界面
Intent intent = new Intent(InitialActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 在页面销毁时清理倒计时资源
if (countDownTimer != null) {
countDownTimer.cancel();
Log.d(TAG, "onDestroy: Countdown timer cancelled");
}
}
}

View File

@ -0,0 +1,108 @@
package com.haven.wallpapers.activity;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.MenuItem;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationBarView;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.ReadFile;
import com.haven.wallpapers.fragment.FavoriteFragment;
import com.haven.wallpapers.fragment.HomeFragment;
import com.haven.wallpapers.fragment.ImportFragment;
import com.haven.wallpapers.adapter.viewpagerAdapter;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private BottomNavigationView navigationView;
private ViewPager viewPager;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
EdgeToEdge.enable(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
navigationView = findViewById(R.id.bottomNavigation);
viewPager = findViewById(R.id.viewPager);
ReadFile.initFull(MainActivity.this,false);
List<Fragment> fragments = new ArrayList<>();
fragments.add(new HomeFragment());
fragments.add(new ImportFragment());
fragments.add(new FavoriteFragment());
//若跳转多个界面添加多个fragment
viewpagerAdapter adapter = new viewpagerAdapter(getSupportFragmentManager(), fragments);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(2);
navigationView.setSelectedItemId(R.id.navigation_home);
// getNavigationBarHeight(this);
navigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.navigation_home) {
viewPager.setCurrentItem(0);
} if (item.getItemId() == R.id.navigation_import){
viewPager.setCurrentItem(1);
} if (item.getItemId() == R.id.navigation_favorite) {
viewPager.setCurrentItem(2);
}
return true;
}
});
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 0:
navigationView.setSelectedItemId(R.id.navigation_home);
break;
case 1:
navigationView.setSelectedItemId(R.id.navigation_import);
break;
case 2:
navigationView.setSelectedItemId(R.id.navigation_favorite);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
checkPermission(this,1);
}
private boolean checkPermission(Activity mActivity, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return true;
} else {
if (mActivity.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
mActivity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
requestCode
);
return false;
} else {
return true;
}
}
}
}

View File

@ -0,0 +1,334 @@
package com.haven.wallpapers.activity;
import android.annotation.SuppressLint;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.MyValue;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.listener.OnDownloadListener;
import com.haven.wallpapers.listener.OnSelectTypeListener;
import com.haven.wallpapers.Utils.DownloadTask;
import com.haven.wallpapers.Utils.Save;
import com.haven.wallpapers.fragment.DialogSelectType;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.room.AppDatabase;
import com.haven.wallpapers.room.LikeDao;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ViewActivity extends AppCompatActivity implements OnSelectTypeListener, OnDownloadListener {
private ImageView imagePreview;
private String resourceImgUrl;
private ImageView BackimageView;
private CardView setBtn;
private FrameLayout share;
private FrameLayout download;
private ImageView collect;
private TextView textViewLoading;
private WallpaperManager wallpaperManager;
private LikeDao dao;
private Data data;
private String importurl;
private DownloadTask downloadTask;
private ProgressBar process;
private DialogSelectType dialogSelectType;
private Drawable fullDrawable;
private File downloadFile;
private String saveFilePath;
//-1 保存到相册
private String Type = "-1";
private ExecutorService executorServiceLike;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_view);
wallpaperManager = WallpaperManager.getInstance(this);
imagePreview = findViewById(R.id.preview);
BackimageView = findViewById(R.id.imageview_back);
setBtn = findViewById(R.id.cardView);
share = findViewById(R.id.share);
download = findViewById(R.id.download);
collect = findViewById(R.id.collection);
textViewLoading = findViewById(R.id.textview_loading);
process = findViewById(R.id.progressbar);
FrameLayout likeLayout = findViewById(R.id.collection_layout);
//初始化db
initDb();
data = (Data) getIntent().getSerializableExtra(MyValue.key_data);
importurl = (String) getIntent().getSerializableExtra(MyValue.key_Import);
downloadTask = new DownloadTask(this, this);
//判断数据源
if (importurl != null) {
saveFilePath = Save.getSaveFilePath("import");
download.setVisibility(View.GONE);
likeLayout.setVisibility(View.GONE);
resourceImgUrl = importurl;
loadImport(importurl);
} else if (data != null) {
saveFilePath = Save.getSaveFilePath(data.getImId());
downloadFile = new File(saveFilePath);
resourceImgUrl = data.getPreviewUrl1080();
loadPreview();
judge();
}
BackimageView.setOnClickListener(v -> {
finish();
});
download.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
process.setVisibility(View.VISIBLE);
downloadTask.execute(resourceImgUrl, "-1");
}
});
setBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (dialogSelectType == null) {
dialogSelectType = new DialogSelectType();
dialogSelectType.setListener(ViewActivity.this);
}
if (!dialogSelectType.isAdded()) {
dialogSelectType.show(getSupportFragmentManager(), "");
}
}
});
share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, resourceImgUrl);
startActivity(intent);
}
});
collect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
collect.setSelected(!collect.isSelected());
executorServiceLike = Executors.newSingleThreadExecutor();
executorServiceLike.submit(new Runnable() {
@Override
public void run() {
if (collect.isSelected()) {
dao.insertTask(data);
} else {
dao.deleteTaskByUrl(data.getImId());
}
}
});
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
if (executorServiceLike != null) {
executorServiceLike.shutdown();
}
}
private void initDb() {
//初始化db
AppDatabase db = AppDatabase.getInstance(this);
dao = db.taskDao();
}
private void judge() {
new Thread(new Runnable() {
@Override
public void run() {
if (dao.getTaskByUrl(data.getImId()) != null) {
collect.setSelected(true);
}
}
}).start();
}
private void loadPreview() {
Glide.with(this)
.load(data.getPreviewUrl1080())
.thumbnail(
Glide.with(this)
.load(data.getPreviewUrl400())
.centerCrop()
)
.transition(DrawableTransitionOptions.withCrossFade(500)) // 500ms 淡入效果
.centerCrop()
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
Log.d(MyApp.TAG, "-----------onLoadFailed e" + e.getMessage());
return false;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
fullDrawable = resource;
return false;
}
})
.into(imagePreview);
}
private void loadImport(String resourceImgUrl) {
Glide.with(this)
.load(resourceImgUrl)
.transition(DrawableTransitionOptions.withCrossFade(500)) // 500ms 淡入效果
.centerCrop()
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
Log.d(MyApp.TAG, "-----------onLoadFailed e" + e.getMessage());
return false;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
fullDrawable = resource;
return false;
}
})
.into(imagePreview);
}
@Override
public void onSelectType(int type) {
textViewLoading.setVisibility(View.VISIBLE);
if (downloadFile != null && downloadFile.exists()) {
setWallpaper(downloadFile, type);
} else if (fullDrawable != null) {
File file = new File(Save.saveDrawableToFile(fullDrawable, saveFilePath));
setWallpaper(file, type);
} else {
downloadTask.execute(resourceImgUrl, "" + type);
}
}
private void setWallpaper(File file, int type) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
FileInputStream fileInputStream = new FileInputStream(file);
switch (type) {
case DialogSelectType.type_home:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
wallpaperManager.setStream(fileInputStream);
} else {
wallpaperManager.setStream(
fileInputStream,
null,
true,
WallpaperManager.FLAG_SYSTEM
);
}
break;
case DialogSelectType.type_lock:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
wallpaperManager.setStream(fileInputStream);
} else {
wallpaperManager.setStream(
fileInputStream,
null,
true,
WallpaperManager.FLAG_LOCK
);
}
break;
case DialogSelectType.type_both:
wallpaperManager.setStream(fileInputStream);
break;
}
textViewLoading.setVisibility(View.GONE);
Toast.makeText(ViewActivity.this, getString(R.string.set_success), Toast.LENGTH_SHORT).show();
} catch (Exception exception) {
textViewLoading.setVisibility(View.GONE);
Toast.makeText(ViewActivity.this, getString(R.string.set_fail), Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onDownloadResult(boolean saveGalleryOk, InputStream inputStream, String type) {
if (type.equals("-1")) {
boolean b = Save.writeFile(inputStream, saveFilePath);
Log.e("--------------", "saveToGallery" + downloadFile.exists());
runOnUiThread(new Runnable() {
@Override
public void run() {
process.setVisibility(View.GONE);
if (saveGalleryOk) {
Toast.makeText(ViewActivity.this, "Image downloaded successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ViewActivity.this, "Failed to download image", Toast.LENGTH_SHORT).show();
}
}
});
} else {
boolean b = Save.writeFile(inputStream, saveFilePath);
if (b) {
setWallpaper(downloadFile, Integer.parseInt(type));
} else {
textViewLoading.setVisibility(View.GONE);
Toast.makeText(ViewActivity.this, getString(R.string.set_fail), Toast.LENGTH_SHORT).show();
}
}
}
}

View File

@ -0,0 +1,66 @@
package com.haven.wallpapers.adapter;
import android.annotation.SuppressLint;
import android.content.Context;
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.haven.wallpapers.R;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.listener.UrlListener;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.myviewholder.DetailsVH;
import java.util.List;
public class DetailsAdapter extends RecyclerView.Adapter<DetailsVH> {
private List<Data> dataInfo ;
private Context myContext;
private UrlListener urlListener;
@NonNull
@Override
public DetailsVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(myContext).inflate(R.layout.details_vh, parent, false);
return new DetailsVH(itemView);
}
public DetailsAdapter(List<Data> dataInfo, Context myContext) {
this.dataInfo = dataInfo;
this.myContext = myContext;
}
public void setUrlWallpaperListener(UrlListener urlListener) {
this.urlListener = urlListener;
}
@Override
public void onBindViewHolder(@NonNull DetailsVH holder, @SuppressLint("RecyclerView") int position) {
Data info = dataInfo.get(position);
ImageView imageView = holder.getImageView();
Glide.with(myContext)
.load(info.getPreviewUrl400())
.placeholder(MyApp.getPlaceImg())
.transform(MyApp.getMultiTransformation())
.into(imageView);
holder.getItemRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (urlListener != null) {
urlListener.onItemClickAction(info);
}
}
});
}
@Override
public int getItemCount() {
return dataInfo.size();
}
}

View File

@ -0,0 +1,111 @@
package com.haven.wallpapers.adapter;
import android.app.Activity;
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.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.MyValue;
import com.haven.wallpapers.activity.ViewActivity;
import com.haven.wallpapers.MyApp;
import java.util.List;
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ViewHolder> {
private List<String> imagePaths;
private final Activity context;
private OnImageDeleteListener onImageDeleteListener; // 删除监听器
public ImageAdapter(List<String> imagePaths, Activity context) {
this.imagePaths = imagePaths;
this.context = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_import, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
String imagePath = imagePaths.get(position);
RequestOptions requestOptions = new RequestOptions()
.transform(new CenterCrop(), new RoundedCorners(20)); // 20 是圆角半径
if (imagePath.startsWith("/data/user/")) {
Glide.with(context)
.load(imagePath)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.apply(requestOptions)
.placeholder(MyApp.getPlaceImg())
.into(holder.imageView);
} else {
Glide.with(context)
.load("file:///android_asset/" + imagePath)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.apply(requestOptions)
.placeholder(MyApp.getPlaceImg())
.into(holder.imageView);
}
holder.imageView.setOnClickListener(v -> {
Intent intent = new Intent(context, ViewActivity.class);
intent.putExtra(MyValue.key_Import, imagePath);
context.startActivity(intent);
});
// 设置删除按钮的点击事件
holder.delete.setOnClickListener(v -> {
int adapterPosition = holder.getAdapterPosition(); // 动态获取当前位置
if (adapterPosition != RecyclerView.NO_POSITION && onImageDeleteListener != null) {
onImageDeleteListener.onImageDelete(imagePaths.get(adapterPosition)); // 调用删除回调
}
});
}
@Override
public int getItemCount() {
return imagePaths.size();
}
// 更新数据并通知数据集更改
public void updateImagePaths(List<String> newImagePaths) {
this.imagePaths = newImagePaths;
notifyDataSetChanged();
}
// 设置删除监听器
public void setOnImageDeleteListener(OnImageDeleteListener listener) {
this.onImageDeleteListener = listener;
}
public interface OnImageDeleteListener {
void onImageDelete(String imagePath);
}
static class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
ImageView delete;
ViewHolder(View view) {
super(view);
imageView = view.findViewById(R.id.imageView_wallpaper);
delete = view.findViewById(R.id.delete);
}
}
}

View File

@ -0,0 +1,100 @@
package com.haven.wallpapers.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.haven.wallpapers.R;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.listener.InfoListener;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.jsonbean.Info;
import com.haven.wallpapers.myviewholder.InfoVH;
import java.util.Collections;
import java.util.List;
public class InfoAdapter extends RecyclerView.Adapter<InfoVH> {
private List<Info> dataInfo;
private Context myContext;
private InfoListener infoListener;
public void setInfoWallpaperListener(InfoListener infoListener) {
this.infoListener = infoListener;
}
public InfoAdapter(List<Info> infoList, Context myCon) {
dataInfo = infoList;
myContext = myCon;
}
@NonNull
@Override
public InfoVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(myContext).inflate(R.layout.home_wallpaper_adapter_list, parent, false);
return new InfoVH(itemView);
}
@Override
public void onBindViewHolder(@NonNull InfoVH holder, int position) {
Info info = dataInfo.get(position);
List<Data> list = info.getList();
Collections.shuffle(list);
String name = info.getName();
holder.getText().setText(name);
ImageView leftImage = holder.getLeftImage();
ImageView rightImage = holder.getRightImage();
Data data = list.get(0);
Data data1 = list.get(1);
Glide.with(myContext)
.load(data.getPreviewUrl400())
.placeholder(MyApp.getPlaceImg())
.transform(MyApp.getMultiTransformation())
.skipMemoryCache(true)
.placeholder(MyApp.getPlaceImg())
.into(leftImage);
Glide.with(myContext)
.load(data1.getPreviewUrl400())
.placeholder(MyApp.getPlaceImg())
.transform(MyApp.getMultiTransformation())
.skipMemoryCache(true)
.placeholder(MyApp.getPlaceImg())
.into(rightImage);
RelativeLayout seeAll = holder.getSeeAll();
leftImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
infoListener.onHomeInfoClickAction(data);
}
});
rightImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
infoListener.onHomeInfoClickAction(data1);
}
});
seeAll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
infoListener.onItemClickAction(name);
}
});
}
@Override
public int getItemCount() {
return dataInfo.size();
}
}

View File

@ -0,0 +1,62 @@
package com.haven.wallpapers.adapter;
import android.content.Context;
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.haven.wallpapers.R;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.listener.LIkeListener;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.myviewholder.DetailsVH;
import java.util.List;
public class LikeAdapter extends RecyclerView.Adapter<DetailsVH> {
private List<Data> dataInfo ;
private Context myContext;
private LIkeListener infoWallpaperListener;
public void setInfoWallpaperListener(LIkeListener infoWallpaperListener) {
this.infoWallpaperListener = infoWallpaperListener;
}
public LikeAdapter(List<Data> infoList, Context myCon) {
dataInfo = infoList;
myContext = myCon;
}
@NonNull
@Override
public DetailsVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(myContext).inflate(R.layout.details_vh, parent, false);
return new DetailsVH(itemView);
}
@Override
public void onBindViewHolder(@NonNull DetailsVH holder, int position) {
Data info = dataInfo.get(position);
ImageView imageView = holder.getImageView();
Glide.with(myContext)
.load(info.getPreviewUrl400())
.placeholder(MyApp.getPlaceImg())
.transform(MyApp.getMultiTransformation())
.into(imageView);
holder.getItemRoot().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (infoWallpaperListener != null) {
infoWallpaperListener.onItemClickAction(info);
}
}
});
}
@Override
public int getItemCount() {
return dataInfo.size();
}
}

View File

@ -0,0 +1,28 @@
package com.haven.wallpapers.adapter;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import java.util.List;
public class viewpagerAdapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragments;
public viewpagerAdapter(@NonNull FragmentManager fragmentManager, List<Fragment> fragments) {
super(fragmentManager);
mFragments = fragments;
}
@NonNull
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
}

View File

@ -0,0 +1,91 @@
package com.haven.wallpapers.fragment;
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.haven.wallpapers.listener.OnSelectTypeListener;
import com.haven.wallpapers.databinding.DialogSetTypeBinding;
public class DialogSelectType extends DialogFragment {
private DialogSetTypeBinding vb;
private OnSelectTypeListener listener;
public static final int type_home =0;
public static final int type_lock =1;
public static final int type_both =2;
public void setListener(OnSelectTypeListener listener) {
this.listener = listener;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
vb = DialogSetTypeBinding.inflate(getLayoutInflater());
init();
return vb.getRoot();
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.setCanceledOnTouchOutside(true);
Window window = dialog.getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
}
private void init(){
vb.layoutHome.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener!= null){
dismiss();
listener.onSelectType(type_home);
}
}
});
vb.layoutLock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener!= null){
dismiss();
listener.onSelectType(type_lock);
}
}
});
vb.layoutBoth.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener!= null){
dismiss();
listener.onSelectType(type_both);
}
}
});
}
}

View File

@ -0,0 +1,103 @@
package com.haven.wallpapers.fragment;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.MyValue;
import com.haven.wallpapers.activity.ViewActivity;
import com.haven.wallpapers.listener.LIkeListener;
import com.haven.wallpapers.adapter.LikeAdapter;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.room.LikeDao;
import com.haven.wallpapers.room.AppDatabase;
import com.haven.wallpapers.Utils.MyItemSpace;
import java.util.ArrayList;
import java.util.List;
public class FavoriteFragment extends Fragment implements LIkeListener {
private RecyclerView recyclerviewWallpaper;
private LikeDao dao;
private List<Data> favoriteList= new ArrayList<>();
private AppDatabase db;
private LikeAdapter likeAdapter;
private RelativeLayout likeText;
@SuppressLint("MissingInflatedId")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("mmmmmmmmmmmmmmmmmm", "onCreateView: ");
View view = inflater.inflate(R.layout.fragment_favorite, container, false);
recyclerviewWallpaper = view.findViewById(R.id.like_recyclerview);
likeText = view.findViewById(R.id.like_text);
db = AppDatabase.getInstance(requireContext());
dao = db.taskDao();
setRecyclerviewWallpaper();
loadFavoriteImages();
return view;
}
@SuppressLint("NotifyDataSetChanged")
private void loadFavoriteImages() {
new Thread(new Runnable() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void run() {
List<Data> favorites = db.taskDao().getAllTasks();
requireActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (favorites.isEmpty()){
likeText.setVisibility(View.VISIBLE);
}else {
likeText.setVisibility(View.GONE);
}
favoriteList.clear();
favoriteList.addAll(favorites);
likeAdapter.notifyDataSetChanged();
}
});
}
}).start();
}
private void setRecyclerviewWallpaper() {
likeAdapter = new LikeAdapter(favoriteList, requireContext());
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 2);
recyclerviewWallpaper.setLayoutManager(gridLayoutManager);
likeAdapter.setInfoWallpaperListener(this);
MyItemSpace myItemSpace = new MyItemSpace(10, 10, 4);
recyclerviewWallpaper.addItemDecoration(myItemSpace);
recyclerviewWallpaper.setAdapter(likeAdapter);
}
@Override
public void onItemClickAction(Data info) {
Intent intent = new Intent(requireContext(), ViewActivity.class);
intent.putExtra(MyValue.key_data, info);
startActivity(intent);
}
@Override
public void onResume() {
super.onResume();
loadFavoriteImages();
}
}

View File

@ -0,0 +1,95 @@
package com.haven.wallpapers.fragment;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.haven.wallpapers.activity.DetailsActivity;
import com.haven.wallpapers.R;
import com.haven.wallpapers.Utils.MyValue;
import com.haven.wallpapers.activity.ViewActivity;
import com.haven.wallpapers.MyApp;
import com.haven.wallpapers.listener.InfoListener;
import com.haven.wallpapers.adapter.InfoAdapter;
import com.haven.wallpapers.jsonbean.Data;
import com.haven.wallpapers.jsonbean.Info;
import java.util.Collections;
import java.util.List;
public class HomeFragment extends Fragment implements InfoListener {
private RecyclerView recyclerView;
private RelativeLayout relativeLayout;
private ImageView imageView;
private List<Info> list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@SuppressLint("MissingInflatedId")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("-------------","------------onCreateView");
View view = inflater.inflate(R.layout.fragment_home, container, false);
recyclerView = view.findViewById(R.id.home_recyclerView);
relativeLayout = view.findViewById(R.id.top_info);
list = MyApp.getUserList();
Collections.shuffle(list);
Data data = list.get(0).getList().get(25);
setRecyclerView();
imageView = view.findViewById(R.id.top_image);
Glide.with(requireContext())
.load(data.getPreviewUrl400())
.placeholder(MyApp.getPlaceImg())
.into(imageView);
relativeLayout.setOnClickListener(v -> {
Intent intent = new Intent(requireContext(), ViewActivity.class);
intent.putExtra(MyValue.key_data, data);
startActivity(intent);
});
return view;
}
private void setRecyclerView() {
GridLayoutManager gridLayoutManager = new GridLayoutManager(requireContext(), 1);
InfoAdapter infoAdapter = new InfoAdapter(list, requireContext());
infoAdapter.setInfoWallpaperListener(this);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(infoAdapter);
}
@Override
public void onItemClickAction(String name) {
Intent intent = new Intent(requireContext(), DetailsActivity.class);
intent.putExtra(MyValue.key_info, name);
startActivity(intent);
}
@Override
public void onHomeInfoClickAction(Data info) {
Intent intent = new Intent(requireContext(), ViewActivity.class);
intent.putExtra(MyValue.key_data, info);
startActivity(intent);
}
}

View File

@ -0,0 +1,231 @@
package com.haven.wallpapers.fragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.haven.wallpapers.R;
import com.haven.wallpapers.adapter.ImageAdapter;
import com.haven.wallpapers.Utils.MyItemSpace;
import com.haven.wallpapers.room.AppDatabase;
import com.haven.wallpapers.room.ImportEntry;
import com.haven.wallpapers.room.ImportDao;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class ImportFragment extends Fragment {
private static final int PICK_IMAGE_REQUEST_CODE = 202; // 请求码用于标识图片选择
private ImageView btnSelectImage; // 选择图片按钮
private RecyclerView recyclerView; // 显示图片的 RecyclerView
private ImageAdapter adapter; // 图片适配器
private List<String> imagePaths = new ArrayList<>(); // 图片路径列表
private AppDatabase appDatabase; // 数据库实例
private ImportDao importDao; // 图片条目 DAO
private LinearLayout linearLayout; // 空视图
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// 加载 Fragment 的布局
View view = inflater.inflate(R.layout.fragment_import, container, false);
// 初始化控件
btnSelectImage = view.findViewById(R.id.btn_select_image);
recyclerView = view.findViewById(R.id.recycler_view);
linearLayout = view.findViewById(R.id.empty);
// 设置 RecyclerView 的布局管理器和适配器
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2)); // 网格布局每行显示两个图片
MyItemSpace itemDecoration = new MyItemSpace(30, 50, 40);
recyclerView.addItemDecoration(itemDecoration);
adapter = new ImageAdapter(imagePaths, requireActivity());
recyclerView.setAdapter(adapter);
// 设置选择图片按钮的点击事件
btnSelectImage.setOnClickListener(v -> openImagePicker());
// 初始化数据库和 DAO
appDatabase = AppDatabase.getInstance(requireContext());
importDao = appDatabase.imageEntryDao();
// 加载图片路径
loadImagePaths();
// 设置图片删除监听器
adapter.setOnImageDeleteListener(imagePath -> {
// 从数据库中删除图片记录
new Thread(() -> {
// 删除本地存储中的图片文件
File imageFile = new File(imagePath);
if (imageFile.exists() && imageFile.delete()) { // 删除文件成功返回 true
// 文件删除成功后再删除数据库中的图片记录和更新列表
importDao.deleteByPath(imagePath); // 删除数据库中的图片记录
imagePaths.remove(imagePath); // 从列表中删除图片路径
requireActivity().runOnUiThread(() -> {
adapter.updateImagePaths(imagePaths); // 更新 RecyclerView
setView(!imagePaths.isEmpty()); // 更新视图
Toast.makeText(getContext(), "Image deleted", Toast.LENGTH_SHORT).show();
});
} else {
// 文件删除失败时的处理
requireActivity().runOnUiThread(() -> {
Toast.makeText(getContext(), "Failed to delete image file", Toast.LENGTH_SHORT).show();
});
}
}).start();
});
return view;
}
@Override
public void onResume() {
super.onResume();
adapter.notifyDataSetChanged(); // 重新加载适配器内容
}
// 打开图片选择器
private void openImagePicker() {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE); // 启动选择图片的活动
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST_CODE && resultCode == getActivity().RESULT_OK && data != null) {
Uri selectedImageUri = data.getData(); // 获取选中的图片 URI
if (selectedImageUri != null) {
try {
if (isImageSizeAcceptable(selectedImageUri)) {
saveImageToInternalStorage(selectedImageUri); // 保存图片到内部存储
} else {
Toast.makeText(getContext(), "图片大小超过限制", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getContext(), "无法获取图片大小: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
}
// 检查图片大小是否在允许范围内
private boolean isImageSizeAcceptable(Uri uri) throws IOException {
InputStream inputStream = requireContext().getContentResolver().openInputStream(uri);
if (inputStream == null) {
return false;
}
long fileSize = inputStream.available();
inputStream.close();
long maxFileSize = 10 * 1024 * 1024; // 最大 10MB
return fileSize <= maxFileSize;
}
// 将选中的图片保存到内部存储
private void saveImageToInternalStorage(Uri uri) {
try {
InputStream inputStream = requireContext().getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
if (bitmap == null) {
Toast.makeText(getContext(), "无法加载图片", Toast.LENGTH_SHORT).show();
return;
}
File internalStorageDir = requireContext().getFilesDir();
File imageFile = new File(internalStorageDir, System.currentTimeMillis() + ".jpg");
FileOutputStream outputStream = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
inputStream.close();
String imagePath = imageFile.getAbsolutePath();
new Thread(() -> {
if (isImageAlreadyExists(imagePath)) {
requireActivity().runOnUiThread(() -> Toast.makeText(getContext(), "该图片已经存在", Toast.LENGTH_SHORT).show());
imageFile.delete();
return;
}
imagePaths.add(imagePath);
requireActivity().runOnUiThread(() -> {
adapter.updateImagePaths(imagePaths);
setView(!imagePaths.isEmpty());
});
importDao.insert(new ImportEntry(imagePath));
}).start();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getContext(), "保存图片失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
// 检查图片是否已经存在
private boolean isImageAlreadyExists(String imagePath) {
File newImageFile = new File(imagePath);
for (String path : imagePaths) {
File existingFile = new File(path);
if (filesAreIdentical(existingFile, newImageFile)) {
return true;
}
}
List<ImportEntry> imageEntries = importDao.getAllImages();
for (ImportEntry importEntry : imageEntries) {
File existingFile = new File(importEntry.getImagePath());
if (filesAreIdentical(existingFile, newImageFile)) {
return true;
}
}
return false;
}
// 比较两个文件是否相同
private boolean filesAreIdentical(File file1, File file2) {
return file1.length() == file2.length(); // 比较文件长度
}
// 加载图片路径列表
private void loadImagePaths() {
new Thread(() -> {
imagePaths.clear(); // 清空列表防止重复添加
List<ImportEntry> imageEntries = importDao.getAllImages();
for (ImportEntry importEntry : imageEntries) {
imagePaths.add(importEntry.getImagePath()); // 添加路径到列表
}
requireActivity().runOnUiThread(() -> {
adapter.updateImagePaths(imagePaths);
setView(!imagePaths.isEmpty());
});
}).start();
}
// 更新视图切换空视图与图片视图
private void setView(Boolean hasData) {
if (hasData) {
recyclerView.setVisibility(View.VISIBLE);
linearLayout.setVisibility(View.GONE);
} else {
recyclerView.setVisibility(View.GONE);
linearLayout.setVisibility(View.VISIBLE);
}
}
}

View File

@ -0,0 +1,99 @@
package com.haven.wallpapers.jsonbean;
import androidx.annotation.Nullable;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import java.io.Serializable;
@Entity(tableName = "collection")
public class Data implements Serializable {
@PrimaryKey(autoGenerate = true)
public int id;
private String imId;
private String description;
private String fullUrl;
private String previewUrl1080;
private String previewUrl400;
private String previewUrl200;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImId() {
return imId;
}
public void setImId(String imId) {
this.imId = imId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getFullUrl() {
return fullUrl;
}
public void setFullUrl(String fullUrl) {
this.fullUrl = fullUrl;
}
public String getPreviewUrl1080() {
return previewUrl1080;
}
public void setPreviewUrl1080(String previewUrl1080) {
this.previewUrl1080 = previewUrl1080;
}
public String getPreviewUrl400() {
return previewUrl400;
}
public void setPreviewUrl400(String previewUrl400) {
this.previewUrl400 = previewUrl400;
}
public String getPreviewUrl200() {
return previewUrl200;
}
public void setPreviewUrl200(String previewUrl200) {
this.previewUrl200 = previewUrl200;
}
@Override
public boolean equals(@Nullable Object obj) {
Data obj1 = (Data) obj;
if (obj1 != null) {
if (obj1.getImId().equals(imId)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,25 @@
package com.haven.wallpapers.jsonbean;
import java.io.Serializable;
import java.util.List;
public class Info implements Serializable {
private String name;
private List<Data> list;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Data> getList() {
return list;
}
public void setList(List<Data> list) {
this.list = list;
}
}

View File

@ -0,0 +1,10 @@
package com.haven.wallpapers.listener;
import com.haven.wallpapers.jsonbean.Data;
public interface InfoListener {
public void onItemClickAction(String name);
public void onHomeInfoClickAction(Data homeInfo);
}

View File

@ -0,0 +1,9 @@
package com.haven.wallpapers.listener;
import com.haven.wallpapers.jsonbean.Data;
public interface LIkeListener {
void onItemClickAction(Data info);
}

View File

@ -0,0 +1,11 @@
package com.haven.wallpapers.listener;
import java.io.InputStream;
public interface OnDownloadListener {
void onDownloadResult(boolean saveGalleryOk, InputStream inputStream, String isSave);
}

View File

@ -0,0 +1,6 @@
package com.haven.wallpapers.listener;
public interface OnSelectTypeListener {
void onSelectType(int type);
}

View File

@ -0,0 +1,8 @@
package com.haven.wallpapers.listener;
import com.haven.wallpapers.jsonbean.Data;
public interface UrlListener {
public void onItemClickAction(Data dataInfo);
}

View File

@ -0,0 +1,28 @@
package com.haven.wallpapers.myviewholder;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.haven.wallpapers.R;
public class DetailsVH extends RecyclerView.ViewHolder{
private ImageView imageView;
private LinearLayout itemRoot;
private ImageView collection;
public DetailsVH(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.imageView_wallpaper);
itemRoot = itemView.findViewById(R.id.item_root);
}
public LinearLayout getItemRoot() {
return itemRoot;
}
public ImageView getImageView() {
return imageView;
}
}

View File

@ -0,0 +1,48 @@
package com.haven.wallpapers.myviewholder;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.haven.wallpapers.R;
public class InfoVH extends RecyclerView.ViewHolder {
private TextView text;
private RelativeLayout seeAll;
private ImageView leftImage;
private ImageView rightImage;
private LinearLayout itemRoot;
public InfoVH(@NonNull View itemView) {
super(itemView);
leftImage = itemView.findViewById(R.id.vh_left_image);
rightImage = itemView.findViewById(R.id.vh_right_image);
itemRoot = itemView.findViewById(R.id.item_root);
text = itemView.findViewById(R.id.vh_text);
seeAll = itemView.findViewById(R.id.vh_see_all);
}
public TextView getText() {
return text;
}
public RelativeLayout getSeeAll() {
return seeAll;
}
public ImageView getLeftImage() {
return leftImage;
}
public ImageView getRightImage() {
return rightImage;
}
public LinearLayout getItemRoot() {
return itemRoot;
}
}

View File

@ -0,0 +1,30 @@
package com.haven.wallpapers.room;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.haven.wallpapers.jsonbean.Data;
@Database(entities = {Data.class, ImportEntry.class}, version = 1,exportSchema=false)
public abstract class AppDatabase extends RoomDatabase {
public abstract LikeDao taskDao();
public abstract ImportDao imageEntryDao();
private static volatile AppDatabase INSTANCE;
public static AppDatabase getInstance(final Context context) {
if (INSTANCE == null) {
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "app_database")
.build();
}
}
}
return INSTANCE;
}
}

View File

@ -0,0 +1,26 @@
package com.haven.wallpapers.room;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import java.util.List;
@Dao
public interface ImportDao {
@Insert
void insert(ImportEntry importEntry);
@Delete
void delete(ImportEntry importEntry);
@Query("SELECT * FROM image_entry")
List<ImportEntry> getAllImages();
@Query("SELECT * FROM image_entry WHERE imagePath = :imagePath LIMIT 1")
ImportEntry findByPath(String imagePath);
@Query("DELETE FROM image_entry WHERE imagePath = :imagePath")
void deleteByPath(String imagePath);
}

View File

@ -0,0 +1,31 @@
package com.haven.wallpapers.room;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "image_entry")
public class ImportEntry {
@PrimaryKey(autoGenerate = true)
private int id;
private String imagePath;
public ImportEntry(String imagePath) {
this.imagePath = imagePath;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
}

View File

@ -0,0 +1,24 @@
package com.haven.wallpapers.room;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.Update;
import com.haven.wallpapers.jsonbean.Data;
import java.util.List;
@Dao
public interface LikeDao {
@Query("SELECT * FROM collection")
List<Data> getAllTasks();
@Query("SELECT * FROM collection WHERE imId = :imId")
Data getTaskByUrl(String imId);
@Query("DELETE FROM collection WHERE imId = :imId")
void deleteTaskByUrl(String imId);
@Insert(onConflict = OnConflictStrategy.IGNORE)
void insertTask(Data task);
@Update
void updateTask(Data task);
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/nav_selected_color" android:state_checked="true" />
<item android:color="@color/nav_selected_color" android:state_checked="false" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="16dp"/>
</shape>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M630.1,151.9L630.1,62.2L361.8,62.2v89.7L93.6,151.9v134.6h89.4v673.1h625.9v-673.1h89.4L898.4,151.9L630.1,151.9zM361.8,869.9h-89.4L272.4,286.5h89.4v583.4zM540.7,869.9h-89.4L451.3,286.5h89.4v583.4zM719.5,869.9h-89.4L630.1,286.5h89.4v583.4z"
android:fillColor="#FA596F"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M395.2,513.6l323.1,-312.4c19.1,-18.4 19.1,-48.3 0,-66.7 -19.1,-18.4 -49.9,-18.4 -69,0L291.8,480.3c-19.1,18.4 -19.1,48.3 0,66.7l357.6,345.7c9.5,9.2 22,13.8 34.5,13.8 12.5,0 25,-4.6 34.5,-13.8 19.1,-18.4 19.1,-48.2 0,-66.7L395.2,513.6z"
android:fillColor="#272636"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5,18.404H19V20.004H5V18.404ZM12.778,10.404H18.222L12,16.804L5.778,10.404H11.222V4.004H12.778V10.404Z"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="13dp"
android:height="12dp"
android:viewportWidth="13"
android:viewportHeight="12">
<path
android:pathData="M4,1.5L9.001,6.001L4,10.502"
android:strokeLineJoin="round"
android:strokeWidth="1.2"
android:fillColor="#00000000"
android:strokeColor="#9B9B9B"
android:strokeLineCap="round"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View File

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M517.1,460.3v-116.4a23.3,23.3 0,0 0,-46.5 0v116.4a93.1,93.1 0,0 0,93.1 93.1h116.4a23.3,23.3 0,0 0,0 -46.5h-116.4a39.6,39.6 0,0 1,-11.9 -1.9l247.9,-247.9A23.3,23.3 0,0 0,768 224.3L519,472.2a39.6,39.6 0,0 1,-1.9 -11.9z"
android:fillColor="#E22F60"
android:strokeColor="#E22F60"
android:strokeWidth="10"/>
<path
android:pathData="M861.1,395.6a23.3,23.3 0,0 0,-23.3 23.3v372.4a46.5,46.5 0,0 1,-46.5 46.5H232.7a46.5,46.5 0,0 1,-46.5 -46.5V232.7a46.5,46.5 0,0 1,46.5 -46.5h372.4a23.3,23.3 0,0 0,0 -46.5H232.7a93.1,93.1 0,0 0,-93.1 93.1v558.5a93.1,93.1 0,0 0,93.1 93.1h558.5a93.1,93.1 0,0 0,93.1 -93.1V418.9a23.3,23.3 0,0 0,-23.3 -23.3z"
android:fillColor="#E22F60"
android:strokeColor="#E22F60"
android:strokeWidth="10"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="25"
android:viewportHeight="24">
<path
android:pathData="M16.873,4.004C14.966,4.004 13.309,4.989 12.5,6.422C11.691,4.989 10.034,4.004 8.127,4.004C5.231,4.004 3.5,6.525 3.5,8.962C3.5,14.734 11.879,19.722 12.235,19.932C12.317,19.98 12.408,20.004 12.5,20.004C12.592,20.004 12.683,19.98 12.765,19.932C13.121,19.722 21.5,14.734 21.5,8.962C21.5,6.525 19.769,4.004 16.873,4.004Z"
android:fillColor="#FF223D"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="25"
android:viewportHeight="24">
<path
android:pathData="M16.873,4.004C14.966,4.004 13.309,4.989 12.5,6.422C11.691,4.989 10.034,4.004 8.127,4.004C5.231,4.004 3.5,6.525 3.5,8.962C3.5,14.734 11.879,19.722 12.235,19.932C12.317,19.98 12.408,20.004 12.5,20.004C12.592,20.004 12.683,19.98 12.765,19.932C13.121,19.722 21.5,14.734 21.5,8.962C21.5,6.525 19.769,4.004 16.873,4.004Z"
android:fillColor="#ffffff"/>
</vector>

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="24dp"
android:viewportWidth="25"
android:viewportHeight="24">
<path
android:pathData="M20.994,5.111C18.175,1.021 12.626,3.434 12.626,7.588C12.626,3.434 7.076,1.021 4.257,5.111C1.342,9.339 4.215,16.746 12.626,21C21.036,16.746 23.909,9.339 20.994,5.111Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#E22F60"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--设置progress背景颜色-->
<item android:id="@android:id/background">
<shape>
<corners android:radius="8dp"/>
<solid android:color="@color/sub_color" />
</shape>
</item>
<!--设置progress进度条颜色-->
<item android:id="@android:id/progress">
<clip android:clipOrientation="horizontal">
<shape>
<corners android:radius="8dp"/>
<solid android:color="@color/wel_pb_color" />
</shape>
</clip>
</item>
</layer-list>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/black_trans"/><!--内部-->
<size android:width="80dp" android:height="80dp"/>
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/like_icon"/>
<item android:state_selected="false" android:drawable="@drawable/no_like"/>
</selector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M4,11H20C20.265,11 20.52,11.105 20.707,11.293C20.895,11.48 21,11.735 21,12C21,12.265 20.895,12.52 20.707,12.707C20.52,12.895 20.265,13 20,13H4C3.735,13 3.48,12.895 3.293,12.707C3.105,12.52 3,12.265 3,12C3,11.735 3.105,11.48 3.293,11.293C3.48,11.105 3.735,11 4,11ZM4,4H18C18.265,4 18.52,4.105 18.707,4.293C18.895,4.48 19,4.735 19,5C19,5.265 18.895,5.52 18.707,5.707C18.52,5.895 18.265,6 18,6H4C3.869,6 3.739,5.974 3.617,5.924C3.496,5.874 3.386,5.8 3.293,5.707C3.2,5.614 3.126,5.504 3.076,5.383C3.026,5.261 3,5.131 3,5C3,4.869 3.026,4.739 3.076,4.617C3.126,4.496 3.2,4.386 3.293,4.293C3.386,4.2 3.496,4.126 3.617,4.076C3.739,4.026 3.869,4 4,4ZM4,18H16C16.265,18 16.52,18.105 16.707,18.293C16.895,18.48 17,18.735 17,19C17,19.265 16.895,19.52 16.707,19.707C16.52,19.895 16.265,20 16,20H4C3.735,20 3.48,19.895 3.293,19.707C3.105,19.52 3,19.265 3,19C3,18.735 3.105,18.48 3.293,18.293C3.48,18.105 3.735,18 4,18Z"
android:fillColor="#242F39"/>
</vector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/color_trans"/>
<corners android:radius="6dp"/>
</shape>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="17.142857dp" android:viewportHeight="20" android:viewportWidth="21" android:width="18dp">
<path android:fillColor="#00000000" android:fillType="evenOdd" android:pathData="M15.989,10.416H8.251C7.397,10.416 6.704,11.121 6.704,11.99V15.925C6.704,16.795 7.397,17.499 8.251,17.499H15.989C16.844,17.499 17.537,16.795 17.537,15.925V11.99C17.537,11.121 16.844,10.416 15.989,10.416Z" android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="1.66667"/>
<path android:fillColor="#ffffff" android:pathData="M12.979,2.212L16.312,4.295C16.834,4.622 16.834,5.382 16.312,5.709L12.979,7.792C12.424,8.139 11.704,7.74 11.704,7.085V2.919C11.704,2.264 12.424,1.865 12.979,2.212Z"/>
<path android:fillColor="#00000000" android:pathData="M12.537,5H9.667C5.985,5 3,7.985 3,11.667V13.333" android:strokeColor="#ffffff" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="1.66667"/>
</vector>

View File

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="24dp"
android:viewportWidth="23"
android:viewportHeight="20">
<path
android:pathData="M1.211,7L10.953,1.154C11.112,1.059 11.31,1.059 11.468,1.154L21.211,7"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#E22F60"
android:strokeLineCap="round"/>
<path
android:pathData="M3.211,6L3.211,19"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#E22F60"
android:strokeLineCap="round"/>
<path
android:pathData="M19.211,6L19.211,19"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#E22F60"
android:strokeLineCap="round"/>
<path
android:pathData="M15.651,12.5C15.651,14.176 13.663,15.535 11.211,15.535C8.758,15.535 6.77,14.176 6.77,12.5"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#E22F60"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="25dp"
android:viewportWidth="25"
android:viewportHeight="25">
<path
android:pathData="M11.505,5.5L3.505,12.5L11.505,19.5"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="@color/white"
android:strokeLineCap="round"/>
<path
android:pathData="M3.505,12.5H21.5"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="@color/white"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/details_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="25dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginTop="20dp"
android:padding="5dp">
<ImageView
android:layout_gravity="center"
android:id="@+id/imageview_back"
android:layout_width="23dp"
android:layout_height="23dp"
android:src="@drawable/im_back" />
<TextView
android:id="@+id/details_text"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:text="Nature"
android:textColor="#2A2E33"
android:textStyle="bold"
android:textSize="24sp">
</TextView>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="10dp"
android:id="@+id/details_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
tools:context=".activity.InitialActivity">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cardView"
android:layout_centerHorizontal="true"
android:layout_marginTop="150dp"
app:cardCornerRadius="14dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/imageview_logo"
android:layout_width="90dp"
android:layout_height="90dp"
android:src="@mipmap/ic_launcher_foreground" />
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/textview_appname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/cardView"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="22sp" />
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="300dp"
android:layout_height="8dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="140dp"
android:progress="20"
android:progressDrawable="@drawable/progress_style" />
</RelativeLayout>

View File

@ -0,0 +1,33 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/bottomNavigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNavigation"
android:layout_width="match_parent"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:itemTextAppearanceActiveBoldEnabled="false"
app:itemActiveIndicatorStyle="@null"
android:background="@color/white"
app:labelVisibilityMode="selected"
app:itemRippleColor="@color/itemRippleColor"
app:activeIndicatorLabelPadding="@null"
app:itemIconTint="@color/nav_colors"
app:itemTextColor="@color/nav_colors"
app:elevation="0dp"
app:menu="@menu/nav_menu">
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PrivacyActivity">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="10dp"
android:layout_marginTop="45dp"
android:background="@drawable/round_button"
android:padding="5dp">
<ImageView
android:id="@+id/back"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="center"
android:src="@drawable/view_back"
tools:ignore="ContentDescription" />
</FrameLayout>
</RelativeLayout>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".activity.ViewActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/preview"
android:scaleType="centerCrop" />
<FrameLayout
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="10dp"
android:layout_marginTop="45dp"
android:background="@drawable/round_button"
android:padding="5dp">
<ImageView
android:id="@+id/imageview_back"
android:layout_width="wrap_content"
android:layout_height="23dp"
android:layout_gravity="center"
android:src="@drawable/view_back"
tools:ignore="ContentDescription" />
</FrameLayout>
<TextView
android:id="@+id/textview_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/shape_text_loading"
android:padding="7dp"
android:text="@string/set_text_loading"
android:textColor="@color/black"
android:textSize="18sp"
android:visibility="gone" />
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="327dp"
android:layout_height="48dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
app:cardCornerRadius="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/set_wallpaper"
android:textColor="@color/text_color"/>
</androidx.cardview.widget.CardView>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_above="@+id/cardView"
android:layout_marginBottom="22dp">
<FrameLayout
android:id="@+id/share"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="16dp"
android:background="@drawable/round_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/download"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_gravity="center"
android:foreground="@drawable/share_icon" />
</FrameLayout>
<FrameLayout
android:id="@+id/download"
android:layout_width="36dp"
android:layout_height="36dp"
android:background="@drawable/round_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/collection_layout"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/share">
<ImageView
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_gravity="center"
android:foreground="@drawable/im_down" />
</FrameLayout>
<FrameLayout
android:id="@+id/collection_layout"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="16dp"
android:background="@drawable/round_button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/download">
<ImageView
android:id="@+id/collection"
android:layout_width="26dp"
android:layout_height="26dp"
android:layout_gravity="center"
android:src="@drawable/selector_like" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/black"
android:visibility="gone" />
</RelativeLayout>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView_wallpaper"
android:layout_width="match_parent"
android:layout_height="180dp" />
</LinearLayout>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:background="@drawable/dialog_bg"
android:orientation="vertical">
<LinearLayout
android:id="@+id/layout_home"
android:layout_width="match_parent"
android:layout_height="54dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/home"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:gravity="center"
android:text="@string/type_home"
android:textColor="@color/black"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_lock"
android:layout_width="match_parent"
android:layout_height="54dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/lock"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:gravity="center"
android:text="@string/type_lock"
android:textColor="@color/black"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/layout_both"
android:layout_width="match_parent"
android:layout_height="54dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/both"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:gravity="center"
android:text="@string/type_both"
android:textColor="@color/black"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="30dp"
tools:context=".fragment.FavoriteFragment">
<TextView
android:id="@+id/details_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/like"
android:textColor="#2A2E33"
android:textSize="24sp"
android:textStyle="bold" />
<RelativeLayout
android:id="@+id/like_text"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_centerInParent="true">
<TextView
android:layout_width="260dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="@string/favorite_text"
android:textColor="@color/sub_color"
android:textSize="14sp"
tools:ignore="HardcodedText" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/like_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/details_text"
android:layout_marginTop="10dp"/>
</RelativeLayout>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/blue"
android:orientation="vertical"
tools:context=".fragment.HomeFragment">
<RelativeLayout
android:id="@+id/top_info"
android:layout_width="match_parent"
android:layout_height="240dp">
<ImageView
android:id="@+id/top_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:ignore="ContentDescription" />
<TextView
android:layout_width="298.8dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:gravity="center"
android:text="@string/top_text"
android:textColor="@color/white"
android:textSize="17sp"
tools:ignore="HardcodedText" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/home_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp" />
</LinearLayout>

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="30dp">
<TextView
android:id="@+id/details_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="Import"
android:textColor="#2A2E33"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/btn_select_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp"
android:src="@drawable/btn_frame"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<LinearLayout
android:id="@+id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="292dp"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:gravity="center"
android:lineSpacingExtra="4dp"
android:text="@string/no_import"
android:textColor="@color/sub_color" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
app:layout_constraintBottom_toTopOf="@id/btn_select_image"
app:layout_constraintTop_toBottomOf="@id/details_text" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/blue"
android:orientation="vertical"
tools:context=".fragment.SettingFragment">
<TextView
android:id="@+id/setting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="@string/setting"
android:textSize="24dp"
android:textStyle="bold"
tools:ignore="SpUsage" />
<RelativeLayout
android:id="@+id/about"
android:layout_width="350dp"
android:layout_height="40dp"
android:layout_alignTop="@+id/setting"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:background="#4DFFFFFF">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="20dp"
android:gravity="center"
android:text="About"
android:textColor="@color/black"
android:textSize="16sp"
tools:ignore="HardcodedText" />
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginStart="320dp"
android:src="@drawable/im_more"
tools:ignore="ContentDescription,RtlHardcoded"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/feedback"
android:layout_width="350dp"
android:layout_height="40dp"
android:layout_alignTop="@+id/about"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:background="#4DFFFFFF">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="20dp"
android:gravity="center"
android:text="Feedback"
android:textColor="@color/black"
android:textSize="16sp"
tools:ignore="HardcodedText" />
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginStart="320dp"
android:src="@drawable/im_more"
tools:ignore="ContentDescription,RtlHardcoded" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/Privacy"
android:layout_width="350dp"
android:layout_height="40dp"
android:layout_alignTop="@+id/feedback"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:background="#4DFFFFFF"
tools:ignore="HardcodedText">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="20dp"
android:gravity="center"
android:text="Privacy Policy"
android:textColor="@color/black"
android:textSize="16sp"
tools:ignore="HardcodedText" />
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginStart="320dp"
android:src="@drawable/im_more"
tools:ignore="ContentDescription,RtlHardcoded" />
</RelativeLayout>
</RelativeLayout>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.TopicFragment">
</FrameLayout>

View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/vh_see_all"
android:layout_width="75dp"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@+id/enter_button"
android:text="@string/see_all"
android:textColor="#2A2E33"
android:textSize="14sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/enter_button"
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/im_more" />
</RelativeLayout>
<TextView
android:id="@+id/vh_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:gravity="center_horizontal|top"
android:text="@string/nature"
android:textColor="#2A2E33"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp">
<ImageView
android:id="@+id/vh_left_image"
android:layout_width="163dp"
android:layout_height="180dp"
android:layout_marginStart="20dp"
android:layout_weight="1"/>
<ImageView
android:id="@+id/vh_right_image"
android:layout_width="163dp"
android:layout_height="180dp"
android:layout_marginStart="10dp"
android:layout_weight="1"/>
<View
android:layout_width="20dp"
android:layout_height="match_parent"></View>
</LinearLayout>
</LinearLayout>

View File

@ -0,0 +1,25 @@
<?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/item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView_wallpaper"
android:layout_width="match_parent"
android:layout_height="320dp"
android:scaleType="fitXY" />
<ImageView
android:id="@+id/delete"
android:layout_width="23dp"
android:layout_height="23dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="@drawable/icon_delete"
app:layout_constraintBottom_toBottomOf="@+id/imageView_wallpaper"
app:layout_constraintEnd_toEndOf="@+id/imageView_wallpaper" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/tab_home"
android:title="Home" />
<item
android:id="@+id/navigation_import"
android:icon="@drawable/import_im"
android:title="Import" />
<item
android:id="@+id/navigation_favorite"
android:icon="@drawable/no_like_icon"
android:title="Like"/>
</menu>

View File

@ -0,0 +1,5 @@
<?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="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?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="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1,7 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.Wallpaper2" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customize your dark theme here. -->
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
</style>
</resources>

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