V1.2(3) 初版

This commit is contained in:
litingting 2025-12-09 10:02:01 +08:00
commit cb366893eb
115 changed files with 171394 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

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

@ -0,0 +1,64 @@
import java.util.Date
import java.text.SimpleDateFormat
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("io.objectbox")
kotlin("kapt")
}
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
android {
namespace = "com.wall.photography.picture"
compileSdk = 36
defaultConfig {
//com.wall.photography.wallpapers
applicationId = "com.wall.photography.picture"
minSdk = 24
targetSdk = 36
versionCode = 3
versionName = "1.2"
setProperty("archivesBaseName", "Picture_v" + versionName + "(${versionCode})_$timestamp")
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
buildFeatures{
viewBinding = true
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("com.google.android.material:material:1.11.0")
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
testImplementation("junit:junit:4.13.2")
implementation ("com.github.bumptech.glide:glide:5.0.5")
implementation ("jp.wasabeef:glide-transformations:4.3.0") // Glide Transformations
implementation("com.squareup.okhttp3:okhttp:5.3.1")
// ObjectBox
implementation("io.objectbox:objectbox-android:5.0.1")
implementation("io.objectbox:objectbox-kotlin:5.0.1")
kapt("io.objectbox:objectbox-processor:5.0.1")
}

View File

@ -0,0 +1,130 @@
{
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
"entities": [
{
"id": "5:6904440383598185263",
"lastPropertyId": "13:4696443091513284958",
"name": "Data",
"properties": [
{
"id": "1:1378876122512921411",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "2:7060028158868516187",
"name": "categoryName",
"type": 9
},
{
"id": "3:4080405383934368678",
"name": "imId",
"type": 9
},
{
"id": "4:3245451512034402870",
"name": "description",
"type": 9
},
{
"id": "5:7282959557789901017",
"name": "fullUrl",
"type": 9
},
{
"id": "6:3462981496642273639",
"name": "previewUrl1080",
"type": 9
},
{
"id": "7:803679427410445656",
"name": "previewUrl400",
"type": 9
},
{
"id": "8:5329464952013185080",
"name": "previewUrl200",
"type": 9
},
{
"id": "9:2164550589022148788",
"name": "authorName",
"type": 9
},
{
"id": "10:3287625753974725033",
"name": "authorHeader",
"type": 9
},
{
"id": "11:6206323152990425588",
"name": "authorHtml",
"type": 9
},
{
"id": "12:2407167584005736159",
"name": "isLike",
"type": 1
},
{
"id": "13:4696443091513284958",
"name": "isDownload",
"type": 1
}
],
"relations": []
}
],
"lastEntityId": "5:6904440383598185263",
"lastIndexId": "0:0",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
"modelVersion": 5,
"modelVersionParserMinimum": 5,
"retiredEntityUids": [
8119453540460508569,
8776066878034520742,
817335537070466014,
5374318059423987080
],
"retiredIndexUids": [],
"retiredPropertyUids": [
8848640050018073106,
4870222079156330783,
4966768060561274983,
8892036187720267027,
1670319685727744805,
3855211567189961055,
7567671966987007993,
2590164264280025677,
8912833100894718986,
7138929457594592554,
3957870060050722570,
2943285943884558608,
7262008615134929676,
7105947400861196483,
1954934496493857304,
8582031355111471002,
8410380097928190493,
3380197792593924336,
5750724995960958985,
5907193265594068445,
7643711915014989832,
5454072153734548882,
8866886314389627366,
6647852625511577303,
8481286751506557167,
615207224772228883,
2114128640869665061,
4004858028833616093,
1649948666606108567,
4925649389754620618,
6869613325061909824,
1127054227079914732
],
"retiredRelationUids": [],
"version": 1
}

BIN
app/picture.jks Normal file

Binary file not shown.

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

@ -0,0 +1,28 @@
# 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
-keep class com.wall.photography.picture.Data.** { *; }
-keep class com.google.gson.** { *; }
-keepattributes Signature
-keepattributes AnnotationDefault,RuntimeVisibleAnnotations

View File

@ -0,0 +1,26 @@
package com.free.life.wallpaper;
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 live, 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 live.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.hd.kwallpapers.wallpapers.live", appContext.getPackageName());
}
}

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application
android:name="com.wall.photography.picture.MyApp"
android:allowBackup="true"
android:usesCleartextTraffic="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/icon"
android:label="@string/app_name"
android:roundIcon="@mipmap/icon"
android:supportsRtl="true"
android:theme="@style/Theme.Wallpaper"
tools:targetApi="31">
<activity
android:name="com.wall.photography.picture.Activity.Search"
android:exported="false" />
<activity
android:name="com.wall.photography.picture.Activity.List"
android:exported="false" />
<activity
android:name="com.wall.photography.picture.Activity.Splash"
android:exported="true"
android:theme="@style/Theme.WelWallpaper">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.wall.photography.picture.Activity.Wallpaper"
android:exported="false" />
<activity
android:name="com.wall.photography.picture.Activity.Main"
android:exported="false" />
</application>
</manifest>

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,68 @@
package com.wall.photography.picture.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import com.wall.photography.picture.databinding.ActivityListBinding;
import com.wall.photography.picture.tool.CommonUtils;
import com.wall.photography.picture.tool.ObjectBoxManager;
import com.wall.photography.picture.tool.GridItemDecoration;
import com.wall.photography.picture.Connect.ItemClick;
import com.wall.photography.picture.Data.Data;
public class List extends AppCompatActivity implements ItemClick {
private ActivityListBinding vb;
private String categoryName;
public static final String key_index = "index";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vb = ActivityListBinding.inflate(getLayoutInflater());
setContentView(vb.getRoot());
CommonUtils.initFull(this, false);
categoryName = getIntent().getStringExtra(key_index);
vb.name.setText(categoryName);
initList();
vb.imageviewBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
private void initList() {
java.util.List<Data> data;
// 如果是标签FeatureAnimalFilm显示所有壁纸
if (categoryName != null && (categoryName.equals("Feature") || categoryName.equals("Animal") || categoryName.equals("Film"))) {
data = ObjectBoxManager.queryWallpapersByTag(categoryName, 500);
} else {
// 否则按分类查询
data = ObjectBoxManager.queryCategoryAll(categoryName);
}
GridItemDecoration itemHelper = new GridItemDecoration(10, 10, 0);
// StaggeredGridLayoutManager gridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
vb.list.addItemDecoration(itemHelper);
vb.list.setLayoutManager(gridLayoutManager);
int height = CommonUtils.dp2Px(180);
com.wall.photography.picture.Project.List itemList = new com.wall.photography.picture.Project.List(this, height,false);
itemList.setDataInfo(data);
itemList.setInfoWallpaperListener(this);
vb.list.setAdapter(itemList);
}
@Override
public void onItemClickAction(Data info) {
Intent intent = new Intent(this, Wallpaper.class);
intent.putExtra(CommonUtils.key_info, info);
startActivity(intent);
}
}

View File

@ -0,0 +1,115 @@
package com.wall.photography.picture.Activity;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import com.google.android.material.tabs.TabLayout;
import com.wall.photography.picture.fragment.MainFragment;
import com.wall.photography.picture.R;
import com.wall.photography.picture.databinding.ActivityMainBinding;
import com.wall.photography.picture.databinding.ProjectTabBinding;
import com.wall.photography.picture.fragment.Like;
import com.wall.photography.picture.fragment.Settings;
import com.wall.photography.picture.tool.CommonUtils;
import java.util.ArrayList;
import java.util.List;
public class Main extends AppCompatActivity {
private ActivityMainBinding vb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vb = ActivityMainBinding.inflate(getLayoutInflater());
CommonUtils.initFull(this, false);
setContentView(vb.getRoot());
List<Fragment> list = new ArrayList<>();
list.add(MainFragment.newInstance(0));
// list.add(FragUiSearch.newInstance());
list.add(Like.newInstance());
list.add(Settings.newInstance());
// list.add(FragmentDownload.newInstance());
int[] ints = {R.drawable.selector_home, R.drawable.selector_tab_like, R.drawable.selector_tab_settings};
vb.viewpager2.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
return list.get(position);
}
@Override
public int getItemCount() {
return list.size();
}
});
vb.viewpager2.setUserInputEnabled(false);
for (int i = 0; i < list.size(); i++) {
TabLayout.Tab tab = vb.tab.newTab();
ProjectTabBinding tabVb = ProjectTabBinding.inflate(getLayoutInflater());
tabVb.imageIcon.setImageDrawable(ContextCompat.getDrawable(this, ints[i]));
tab.setCustomView(tabVb.getRoot());
if (i == 0) {
tabVb.imageIndicator.setVisibility(View.VISIBLE);
} else {
tabVb.imageIndicator.setVisibility(View.GONE);
}
vb.tab.addTab(tab);
}
vb.tab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
int position = tab.getPosition();
vb.viewpager2.setCurrentItem(position);
View customView = tab.getCustomView();
View imageIndicator = customView.findViewById(R.id.image_indicator);
imageIndicator.setVisibility(View.VISIBLE);
// 更新图标为选中状态
android.widget.ImageView imageIcon = customView.findViewById(R.id.image_icon);
if (imageIcon != null) {
imageIcon.setSelected(true);
}
if (position == 0) {
vb.textviewWallpaper.setText(getString(R.string.app_name));
} else if (position == 1) {
vb.textviewWallpaper.setText(getString(R.string.collections));
} else if (position == 2) {
vb.textviewWallpaper.setText(getString(R.string.settings));
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
View customView = tab.getCustomView();
View imageIndicator = customView.findViewById(R.id.image_indicator);
imageIndicator.setVisibility(View.INVISIBLE);
// 更新图标为未选中状态
android.widget.ImageView imageIcon = customView.findViewById(R.id.image_icon);
if (imageIcon != null) {
imageIcon.setSelected(false);
}
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
}

View File

@ -0,0 +1,115 @@
package com.wall.photography.picture.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.TextView.OnEditorActionListener
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import com.wall.photography.picture.R
import com.wall.photography.picture.databinding.ActivitySearchBinding
import com.wall.photography.picture.tool.CommonUtils
import com.wall.photography.picture.tool.ObjectBoxManager
import com.wall.photography.picture.tool.GridItemDecoration
import com.wall.photography.picture.Connect.ItemClick
import com.wall.photography.picture.Data.Data
import com.wall.photography.picture.Project.List
class Search : AppCompatActivity() ,
ItemClick {
private lateinit var adapterWallapper: List
private lateinit var binding:ActivitySearchBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySearchBinding.inflate(layoutInflater)
setContentView(binding.root)
CommonUtils.initFull(this, false)
initList()
binding.imageviewBack.setOnClickListener {
finish()
}
// 从Intent中获取搜索关键词并自动搜索
val searchKeyword = intent.getStringExtra("search_keyword")
if (!searchKeyword.isNullOrBlank()) {
binding.et.setText(searchKeyword)
// 延迟执行搜索,确保界面已经初始化完成
binding.et.post {
startSearch()
}
}
}
private fun initList() {
val height = CommonUtils.dp2Px(180)
adapterWallapper =
List(this, height, true)
adapterWallapper.setInfoWallpaperListener(this)
val recyclerItemHelper = GridItemDecoration(10, 10, 15)
val gridLayoutManager = GridLayoutManager(this, 2)
binding.resultRecycler.run {
layoutManager = gridLayoutManager
addItemDecoration(recyclerItemHelper)
adapter = adapterWallapper
}
binding.et.setOnEditorActionListener(OnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
startSearch()
return@OnEditorActionListener true
}
false
})
binding.btnSearch.setOnClickListener { startSearch() }
}
private fun closeKeyboard() {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(binding.et.windowToken, 0)
}
private fun startSearch() {
closeKeyboard()
binding.searchPb.visibility = View.VISIBLE
val string: String = binding.et.text.toString()
if (string.isNotEmpty()) {
val search = ObjectBoxManager.search(string)
if (search.size > 0) {
showEmpty(false)
adapterWallapper.setDataInfo(search)
binding.searchPb.visibility = View.GONE
} else {
binding.searchPb.visibility = View.GONE
showEmpty(true)
}
} else {
binding.searchPb.visibility = View.GONE
Toast.makeText(
this,
getString(R.string.please_input_keyword),
Toast.LENGTH_SHORT
).show()
}
}
private fun showEmpty(showEmpty: Boolean) {
if (showEmpty) {
binding.emptyLayout.visibility = View.VISIBLE
binding.resultRecycler.visibility = View.GONE
} else {
binding.emptyLayout.visibility = View.GONE
binding.resultRecycler.visibility = View.VISIBLE
}
}
override fun onItemClickAction(info: Data?) {
val intent = Intent(this, Wallpaper::class.java)
intent.putExtra(CommonUtils.key_info, info)
startActivity(intent)
}
}

View File

@ -0,0 +1,80 @@
package com.wall.photography.picture.Activity;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import androidx.appcompat.app.AppCompatActivity;
import com.wall.photography.picture.databinding.ActivitySplashBinding;
import com.wall.photography.picture.tool.CommonUtils;
public class Splash extends AppCompatActivity {
private CountDownTimer countDownTimer;
private ActivitySplashBinding vb;
private long totalTime = 2000;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vb = ActivitySplashBinding.inflate(getLayoutInflater());
CommonUtils.initFull(this,true);
setContentView(vb.getRoot());
countDownTimer = new CountDownTimer(totalTime,100) {
@Override
public void onTick(long millisUntilFinished) {
int progressPercentage = (int) ((100 * millisUntilFinished) / totalTime);
int countdownPercentage = 100 - progressPercentage;
vb.progressbar.setProgress(countdownPercentage);
}
@Override
public void onFinish() {
vb.progressbar.setProgress(100);
Intent intent = new Intent(Splash.this, Main.class);
startActivity(intent);
finish();
}
};
// countDownTimer = AdManager.showWelcomeAd(this, totalTime, new CountAction() {
// @Override
// public void onCount(long millisUntilFinished) {
// int progressPercentage = (int) ((100 * millisUntilFinished) / totalTime);
//
// int countdownPercentage = 100 - progressPercentage;
//
// vb.progressbar.setProgress(countdownPercentage);
// }
// }, new GoMainAction() {
// @Override
// public void onGo() {
// vb.progressbar.setProgress(100);
// Intent intent = new Intent(WElActivity.this, HomeActivity.class);
// startActivity(intent);
// finish();
// }
// });
countDownTimer.start();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null) {
countDownTimer.cancel();
countDownTimer = null;
}
}
}

View File

@ -0,0 +1,399 @@
package com.wall.photography.picture.Activity;
import android.app.WallpaperManager;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.DecodeFormat;
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.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.wall.photography.picture.MyApp;
import com.wall.photography.picture.R;
import com.wall.photography.picture.databinding.ActivityWallapperBinding;
import com.wall.photography.picture.fragment.MyDialog;
import com.wall.photography.picture.tool.CommonUtils;
import com.wall.photography.picture.tool.ObjectBoxManager;
import com.wall.photography.picture.tool.JsonParser;
import com.wall.photography.picture.Connect.SelectType;
import com.wall.photography.picture.Data.Data;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import kotlin.Unit;
import kotlin.jvm.functions.Function2;
import okhttp3.Call;
public class Wallpaper extends AppCompatActivity implements SelectType {
private WeakReference<Wallpaper> weakReference;
private Data data;
private WallpaperManager wallpaperManager;
private int permissionCode = 1;
private String mSavePath;
private String imId;
private String fullUrl;
private MyDialog dialogType;
private File downloadFile;
private Call call;
private ActivityWallapperBinding vb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vb = ActivityWallapperBinding.inflate(getLayoutInflater());
CommonUtils.initFull(this, true);
setContentView(vb.getRoot());
weakReference = new WeakReference<>(this);
// 使用新的 API 替代已过时的 getSerializableExtra()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
data = getIntent().getSerializableExtra(CommonUtils.key_info, Data.class);
} else {
data = (Data) getIntent().getSerializableExtra(CommonUtils.key_info);
}
if (data == null) {
return;
}
imId = data.getImId();
mSavePath = JsonParser.INSTANCE.getSaveFilePath(this, imId);
wallpaperManager = WallpaperManager.getInstance(this);
initClick();
loadDetail();
vb.tvContent.setText(data.getDescription());
}
private void loadDetail() {
String previewUrl400 = data.getPreviewUrl400();
String previewUrl1080 = data.getPreviewUrl1080();
fullUrl = data.getFullUrl();
File file = new File(mSavePath);
RequestOptions options = new RequestOptions()
.format(DecodeFormat.PREFER_RGB_565);
int[] screenWidthHeight = CommonUtils.getScreenWidthHeight(this);
Log.d(MyApp.TAG, "--------width=" + screenWidthHeight[0] + "----height=" + screenWidthHeight[1]);
if (file.exists()) {
Glide.with(this)
.load(file)
.apply(options)
.placeholder(R.mipmap.im_placeholder)
.transition(DrawableTransitionOptions.withCrossFade(500))
.into(vb.imageviewPreview);
} else {
Glide.with(this)
.asDrawable()
.load(previewUrl1080)
.apply(options)
.skipMemoryCache(true)
.placeholder(R.mipmap.im_placeholder)
.thumbnail(
Glide.with(Wallpaper.this)
.asDrawable()
.load(previewUrl400)
.apply(options)
.placeholder(R.mipmap.im_placeholder)
.centerCrop()
)
.transition(DrawableTransitionOptions.withCrossFade(500)) // 500ms 淡入效果
.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;
}
})
.centerCrop()
.into(vb.imageviewPreview);
}
boolean b = ObjectBoxManager.queryIsLike(imId);
vb.imageFavorite.setSelected(b);
}
private void initClick() {
vb.imageviewBack.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
vb.buttonSet.setOnClickListener(v -> {
if (dialogType == null) {
dialogType = new MyDialog();
dialogType.setListener(Wallpaper.this);
}
if (!dialogType.isAdded()) {
dialogType.show(getSupportFragmentManager(), "");
}
});
vb.imageFavorite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean selected = vb.imageFavorite.isSelected();
vb.imageFavorite.setSelected(!selected);
boolean selectedNew = vb.imageFavorite.isSelected();
data.setLike(selectedNew);
ObjectBoxManager.updateLike(data);
}
});
vb.layoutDownload.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean permission = JsonParser.INSTANCE.requestPermission(Wallpaper.this, permissionCode);
if (!permission) {
return;
}
startSaveToAlbum();
}
});
}
private void startSaveToAlbum() {
showDownloadLoading(true);
if (downloadFile != null && downloadFile.exists()) {
Log.d(MyApp.TAG, "-----------Download 2");
startSave(downloadFile);
return;
}
Log.d(MyApp.TAG, "-----------Download 3");
doDownload(true, true);
}
private void doDownload(boolean showMsg, boolean save) {
call = JsonParser.INSTANCE.downloadFile(fullUrl, mSavePath, new Function2<Boolean, InputStream, Unit>() {
@Override
public Unit invoke(Boolean aBoolean, InputStream inputStream) {
File file = new File(mSavePath);
if (aBoolean && file.exists()) {
downloadFile = file;
if (save) {
startSave(downloadFile);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
Wallpaper activity = weakReference.get();
if (activity != null && !activity.isDestroyed()) {
Log.d(MyApp.TAG, "-------weakReference !=null");
} else {
Log.d(MyApp.TAG, "-------weakReference null");
}
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
showDownloadLoading(false);
if (showMsg) {
Toast.makeText(Wallpaper.this, getString(R.string.download_fail), Toast.LENGTH_SHORT).show();
}
}
});
}
return null;
}
});
}
private void showDownloadLoading(boolean show) {
if (show) {
vb.pbDownload.setVisibility(View.VISIBLE);
vb.imageDownload.setVisibility(View.GONE);
} else {
vb.pbDownload.setVisibility(View.GONE);
vb.imageDownload.setVisibility(View.VISIBLE);
}
}
private void showSetWallpaperLoading(boolean show) {
Log.d(MyApp.TAG, "-----------showSetWallpaperLoading" + show);
if (show) {
vb.pbSet.setVisibility(View.VISIBLE);
vb.buttonSet.setVisibility(View.GONE);
} else {
vb.pbSet.setVisibility(View.GONE);
vb.buttonSet.setVisibility(View.VISIBLE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == permissionCode && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startSaveToAlbum();
}
}
private void startSave(File file) {
ObjectBoxManager.insertOrUpdateDownload(data);
Uri uri = JsonParser.INSTANCE.saveToGallery(Wallpaper.this, file);
runOnUiThread(new Runnable() {
@Override
public void run() {
showDownloadLoading(false);
if (uri == null) {
Toast.makeText(Wallpaper.this, getString(R.string.save_fail), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(Wallpaper.this, getString(R.string.save_success), Toast.LENGTH_LONG).show();
}
Log.d(MyApp.TAG, "--------path=" + file.getAbsolutePath() + "---uri=" + uri);
}
});
}
@Override
public void onSelectType(int type) {
showSetWallpaperLoading(true);
if (downloadFile != null && downloadFile.exists()) {
new Thread(new Runnable() {
@Override
public void run() {
Log.d(MyApp.TAG, "--------downloadFile=" + downloadFile.exists());
setWallpaper(downloadFile, type);
}
}).start();
}
else {
call = JsonParser.INSTANCE.downloadFile(fullUrl, mSavePath, new Function2<Boolean, InputStream, Unit>() {
@Override
public Unit invoke(Boolean aBoolean, InputStream inputStream) {
Log.d(MyApp.TAG, "--------downloadFile=" + Thread.currentThread().getName());
File file = new File(mSavePath);
if (aBoolean && file.exists()) {
downloadFile = file;
setWallpaper(downloadFile, type);
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
showSetWallpaperLoading(false);
Toast.makeText(Wallpaper.this, getString(R.string.set_fail), Toast.LENGTH_SHORT).show();
}
});
}
return null;
}
});
}
}
private void setWallpaper(File file, int type) {
try {
FileInputStream fileInputStream = new FileInputStream(file);
switch (type) {
case MyDialog.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 MyDialog.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 MyDialog.type_both:
wallpaperManager.setStream(fileInputStream);
break;
}
deleteCacheFile();
runOnUiThread(new Runnable() {
@Override
public void run() {
showSetWallpaperLoading(false);
Toast.makeText(Wallpaper.this, getString(R.string.set_success), Toast.LENGTH_SHORT).show();
}
});
} catch (Exception exception) {
runOnUiThread(new Runnable() {
@Override
public void run() {
showSetWallpaperLoading(false);
Toast.makeText(Wallpaper.this, getString(R.string.set_fail), Toast.LENGTH_SHORT).show();
}
});
}
}
private void deleteCacheFile() {
if (downloadFile != null && downloadFile.exists()) {
boolean delete = downloadFile.delete();
Log.d(MyApp.TAG, "--------delete=" + delete);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (call != null) {
call.cancel();
}
}
}

View File

@ -0,0 +1,12 @@
package com.wall.photography.picture.Connect;
import com.wall.photography.picture.Data.Data;
public interface ItemClick {
void onItemClickAction(Data info);
default void onClickMore(String name){}
default void onTagClick(String tagType, Data info){}
}

View File

@ -0,0 +1,9 @@
package com.wall.photography.picture.Connect;
import com.wall.photography.picture.Data.Data;
import java.util.List;
public interface LikeList {
void onLikeList(List<Data> dataList);
}

View File

@ -0,0 +1,8 @@
package com.wall.photography.picture.Connect;
import com.wall.photography.picture.Data.Data;
public interface OnUpdateLike {
void onAdd(Data data);
void onRemove(Data data);
}

View File

@ -0,0 +1,6 @@
package com.wall.photography.picture.Connect;
public interface SelectType {
void onSelectType(int type);
}

View File

@ -0,0 +1,159 @@
package com.wall.photography.picture.Data;
import androidx.annotation.Nullable;
import java.io.Serializable;
import io.objectbox.annotation.Entity;
import io.objectbox.annotation.Id;
@Entity
public class Data implements Serializable {
@Id
private long id;
private String categoryName;
private String imId;
private String description;
private String fullUrl;
private String previewUrl1080;
private String previewUrl400;
private String previewUrl200;
private String authorName;
private String authorHeader;
private String authorHtml;
private boolean isLike;
private boolean isDownload;
public boolean isLike() {
return isLike;
}
public void setLike(boolean like) {
isLike = like;
}
public boolean isDownload() {
return isDownload;
}
public void setDownload(boolean download) {
isDownload = download;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getImId() {
return imId;
}
public void setImId(String imId) {
this.imId = imId;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
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;
}
public String getAuthorName() {
return authorName;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getAuthorHeader() {
return authorHeader;
}
public void setAuthorHeader(String authorHeader) {
this.authorHeader = authorHeader;
}
public String getAuthorHtml() {
return authorHtml;
}
public void setAuthorHtml(String authorHtml) {
this.authorHtml = authorHtml;
}
@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,119 @@
package com.wall.photography.picture;
import android.app.Application;
import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;
import com.wall.photography.picture.Data.Data;
import com.wall.photography.picture.tool.CommonUtils;
import com.wall.photography.picture.tool.JsonParser;
import com.wall.photography.picture.tool.ObjectBoxManager;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyApp extends Application {
public static Context mAppContext;
public static String TAG = "-------MyApp---------";
public static Typeface defaultFont;
private String animasName = "Animalssearch.json";
private String exName = "Experimentalsearch.json";
private String filmName = "Filmsearch.json";
private String natureName = "Naturesearch.json";
private String pattName = "Patternssearch.json";
private String streetName = "Streetsearch.json";
private String travelName = "Travelsearch.json";
private String wallpaperName = "Featuredsearch.json";
private ExecutorService executor;
private static List<String> CategoryNames = new ArrayList<>();
private int i = 0;
@Override
public void onCreate() {
super.onCreate();
mAppContext = this;
defaultFont = Typeface.createFromAsset(getAssets(), "custfont.ttf");
ObjectBoxManager.init(this);
executor = Executors.newFixedThreadPool(8);
String[] names = {wallpaperName, animasName, filmName};
try {
for (String name : names) {
InputStream open = getAssets().open(name);
String covertStr = CommonUtils.getCovertStr(open);
if (!covertStr.isEmpty()) {
String realName = name.substring(0, name.indexOf("."));
CategoryNames.add(realName);
executor.execute(new Runnable() {
@Override
public void run() {
i++;
Log.d(MyApp.TAG, "開始載入分類: " + realName);
List<Data> data = JsonParser.INSTANCE.getData(covertStr, realName);
Log.d(MyApp.TAG, "分類 " + realName + " 解析出 " + data.size() + " 條數據");
Collections.shuffle(data);
int successCount = 0;
for (Data data1:data){
ObjectBoxManager.addData(data1);
successCount++;
}
Log.d(MyApp.TAG, "分類 " + realName + " 成功添加 " + successCount + " 條數據到數據庫");
// if (i == 8) {
// executor.shutdown();
// Log.d(MyWallpaper.TAG, "------------data complete");
// }
}
});
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static List<String> getCategoryNames() {
return CategoryNames;
}
// private void initTop(){
// ATSDK.checkIsEuTraffic(this, new NetTrafficeCallback() {
//
// @Override
// public void onResultCallback(boolean isEU) {
// Log.e(TAG, "onResultCallback:" + isEU);
// if (isEU && ATSDK.getGDPRDataLevel( MyApp.mAppContext) == ATSDK.UNKNOWN) {
// ATSDK.showGdprAuth(MyApp.mAppContext);
// }
//
// }
//
// @Override
// public void onErrorCallback(String errorMsg) {
// Log.e(TAG, "onErrorCallback:" + errorMsg);
// }
// });
//
// ATSDK.init( this, APPId, AppKey);
// //测试工具
//// ATDebuggerUITest.showDebuggerUI(this,debug_Key);
// AdManager.loadAllAd();
//
// }
}

View File

@ -0,0 +1,140 @@
package com.wall.photography.picture.Project;
import android.content.Context;
import android.graphics.Bitmap;
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.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.wall.photography.picture.MyApp;
import com.wall.photography.picture.R;
import com.wall.photography.picture.tool.ObjectBoxManager;
import com.wall.photography.picture.Data.Data;
import com.wall.photography.picture.Connect.ItemClick;
import com.wall.photography.picture.tool.CommonUtils;
import java.util.ArrayList;
import java.util.List;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class Like extends RecyclerView.Adapter<Like.LikeVh> {
private List<Data> dataInfo = new ArrayList<>();
private Context myContext;
private ItemClick onItemClick;
public void setInfoWallpaperListener(ItemClick onItemClick) {
this.onItemClick = onItemClick;
}
public Like(Context myCon) {
myContext = myCon;
}
public void setDataInfo(List<Data> dataInfo) {
this.dataInfo = dataInfo;
notifyDataSetChanged();
}
@NonNull
@Override
public LikeVh onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(myContext).inflate(R.layout.project_like, parent, false);
return new LikeVh(itemView);
}
@Override
public void onBindViewHolder(@NonNull LikeVh holder, int position) {
Data info = dataInfo.get(position);
ImageView imageView = holder.getImageView();
ImageView imFavorite = holder.getImFavorite();
String previewUrl400 = info.getPreviewUrl400();
String imId = info.getImId();
View spaceView = holder.getSpaceView();
if (position == dataInfo.size() - 1) {
spaceView.setVisibility(View.VISIBLE);
} else {
spaceView.setVisibility(View.GONE);
}
MultiTransformation<Bitmap> multiTransformation = new MultiTransformation<>(
new CenterCrop(),
new RoundedCornersTransformation(CommonUtils.dp2Px(12), 0) // 圆角效果
);
Glide.with(myContext)
.load(previewUrl400)
.placeholder(R.mipmap.im_placeholder)
.transform(multiTransformation)
.into(imageView);
imFavorite.setSelected(true);
imFavorite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imFavorite.setSelected(false);
info.setLike(false);
ObjectBoxManager.updateLike(info);
int adapterPosition = holder.getAdapterPosition();
notifyItemRemoved(adapterPosition);
Log.d(MyApp.TAG, "----------notifyItemRemoved-adapterPosition=" + adapterPosition);
}
});
holder.getLayout().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClick != null) {
onItemClick.onItemClickAction(info);
}
}
});
}
@Override
public int getItemCount() {
return dataInfo.size();
}
public class LikeVh extends RecyclerView.ViewHolder {
private ImageView imageView;
private RelativeLayout layout;
private ImageView imFavorite;
private View spaceView;
public LikeVh(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.wallpaper);
layout = itemView.findViewById(R.id.layout);
imFavorite = itemView.findViewById(R.id.image_favorite);
spaceView = itemView.findViewById(R.id.space_view);
}
public View getSpaceView() {
return spaceView;
}
public ImageView getImFavorite() {
return imFavorite;
}
public RelativeLayout getLayout() {
return layout;
}
public ImageView getImageView() {
return imageView;
}
}
}

View File

@ -0,0 +1,293 @@
package com.wall.photography.picture.Project;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
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 android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.wall.photography.picture.R;
import com.wall.photography.picture.Data.Data;
import com.wall.photography.picture.Connect.ItemClick;
import com.wall.photography.picture.tool.CommonUtils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class List extends RecyclerView.Adapter<List.MyViewHolder> {
private java.util.List<Data> dataInfo = new ArrayList<>();
private ItemClick onItemClick;
private WeakReference<Context> weakReference;
private int itemHeight;
private boolean showSpace = false;
public void setInfoWallpaperListener(ItemClick onItemClick) {
this.onItemClick = onItemClick;
}
public List(Context myCon, int itemHeight, boolean show) {
weakReference = new WeakReference<>(myCon);
this.itemHeight = itemHeight;
showSpace = show;
}
public void setDataInfo(java.util.List<Data> dataInfo) {
this.dataInfo = dataInfo;
notifyDataSetChanged();
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = weakReference.get();
if (context != null) {
View itemView = LayoutInflater.from(context).inflate(R.layout.project_list, parent, false);
ImageView imageView = itemView.findViewById(R.id.wallpaper);
ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
layoutParams.height = itemHeight;
imageView.setLayoutParams(layoutParams);
return new MyViewHolder(itemView);
}
return null;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Data info = dataInfo.get(position);
ImageView imageView = holder.getImageView();
String previewUrl400 = info.getPreviewUrl400();
String previewUrl200 = info.getPreviewUrl200();
RelativeLayout item = holder.getLayout();
String imId = info.getImId();
int curheight;
View spaceView = holder.getSpaceView();
if (showSpace && position == dataInfo.size() - 1) {
spaceView.setVisibility(View.VISIBLE);
} else {
spaceView.setVisibility(View.GONE);
}
MultiTransformation<Bitmap> multiTransformation = new MultiTransformation<>(
new CenterCrop(),
new RoundedCornersTransformation(CommonUtils.dp2Px(12), 0) // 圆角效果
);
RequestOptions options = new RequestOptions()
.format(DecodeFormat.PREFER_RGB_565);
Context context = weakReference.get();
if (context != null) {
Log.d("-----------","----------------Glide");
Glide.with(context)
.asDrawable()
.thumbnail(Glide.with(context)
.load(previewUrl200)
.transform(multiTransformation))
.load(previewUrl400)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
android.util.Log.e("ImageLoad", "Failed to load image: " + model + ", Error: " + (e != null ? e.getMessage() : "Unknown"));
if (e != null) {
e.logRootCauses("ImageLoad");
}
return false;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
android.util.Log.d("ImageLoad", "Successfully loaded image from: " + dataSource);
return false;
}
})
.placeholder(R.drawable.image_load_placeholder)
.error(R.drawable.image_load_fail)
.transform(multiTransformation)
.into(imageView);
}
item.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClick != null) {
onItemClick.onItemClickAction(info);
}
}
});
// 隐藏图片上的标签文字
holder.tagText.setVisibility(View.GONE);
}
private void setupTagText(MyViewHolder holder, int position) {
if (position < 0 || position >= dataInfo.size()) {
holder.tagText.setVisibility(View.GONE);
return;
}
Data info = dataInfo.get(position);
String categoryName = info.getCategoryName();
// 根据真实分类名称映射到标签
String tagText = getTagForCategory(categoryName);
if (tagText != null && !tagText.isEmpty()) {
final String finalTagText = tagText;
holder.tagText.setText(finalTagText);
holder.tagText.setVisibility(View.VISIBLE);
// 标签点击事件
holder.tagText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClick != null && holder.getAdapterPosition() != RecyclerView.NO_POSITION) {
Data itemInfo = dataInfo.get(holder.getAdapterPosition());
onItemClick.onTagClick(finalTagText, itemInfo);
}
}
});
} else {
holder.tagText.setVisibility(View.GONE);
}
}
/**
* 根据分类名称获取对应的标签
*/
private String getTagForCategory(String categoryName) {
if (categoryName == null) {
return null;
}
// 将分类映射到标签分类名是JSON文件名去掉.json后缀
switch (categoryName) {
case "Featuredsearch":
return "Feature";
case "Animalssearch":
return "Animal";
case "Filmsearch":
return "Film";
default:
return null;
}
}
@Override
public int getItemCount() {
return dataInfo.size();
}
@Override
public void onViewRecycled(@NonNull MyViewHolder holder) {
super.onViewRecycled(holder);
}
private static DiffUtil.ItemCallback<Data> diff = new DiffUtil.ItemCallback<Data>() {
@Override
public boolean areItemsTheSame(@NonNull Data oldItem, @NonNull Data newItem) {
return oldItem.getImId().equals(newItem.getImId());
}
@Override
public boolean areContentsTheSame(@NonNull Data oldItem, @NonNull Data newItem) {
return oldItem.getImId().equals(newItem.getImId());
}
};
private static class MyCallback extends DiffUtil.Callback {
private java.util.List<Data> mOldList;
private java.util.List<Data> mNewList;
public MyCallback(java.util.List<Data> oldList, java.util.List<Data> newList) {
mOldList = oldList;
mNewList = newList;
}
@Override
public int getOldListSize() {
return mOldList.size();
}
@Override
public int getNewListSize() {
return mNewList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return mOldList.get(oldItemPosition).getImId().equals(mNewList.get(newItemPosition).getImId());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return mOldList.get(oldItemPosition).getImId().equals(mNewList.get(newItemPosition).getImId());
}
}
static class MyViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private RelativeLayout layout;
private View spaceView;
private TextView tagText;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.wallpaper);
layout = itemView.findViewById(R.id.layout);
spaceView = itemView.findViewById(R.id.space_view);
tagText = itemView.findViewById(R.id.tag_text);
}
public RelativeLayout getLayout() {
return layout;
}
public ImageView getImageView() {
return imageView;
}
public View getSpaceView() {
return spaceView;
}
}
}

View File

@ -0,0 +1,117 @@
package com.wall.photography.picture.Project;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.MultiTransformation;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.wall.photography.picture.MyApp;
import com.wall.photography.picture.R;
import com.wall.photography.picture.databinding.ProjectMainBinding;
import com.wall.photography.picture.Data.Data;
import com.wall.photography.picture.tool.CommonUtils;
import com.wall.photography.picture.tool.ObjectBoxManager;
import com.wall.photography.picture.Connect.ItemClick;
import java.util.ArrayList;
import java.util.List;
import jp.wasabeef.glide.transformations.RoundedCornersTransformation;
public class Main extends RecyclerView.Adapter<Main.HomeParentHolder> {
private List<String> data = new ArrayList<>();
private Context mContext;
private ItemClick listener;
private MultiTransformation<Bitmap> multiTransformation = new MultiTransformation<>(
new CenterCrop(),
new RoundedCornersTransformation(CommonUtils.dp2Px(12), 0)
);
public void setData(List<String> data) {
this.data = data;
notifyDataSetChanged();
}
public void setInfoWallpaperListener(ItemClick onItemClick) {
this.listener = onItemClick;
}
@NonNull
@Override
public HomeParentHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
mContext = parent.getContext();
ProjectMainBinding inflate = ProjectMainBinding.inflate(LayoutInflater.from(mContext), parent, false);
return new HomeParentHolder(inflate);
}
@Override
public void onBindViewHolder(@NonNull HomeParentHolder holder, int position) {
String name = data.get(position);
List<Data> data1 = ObjectBoxManager.queryHome(name);
String previewUrl400 = data1.get(0).getPreviewUrl1080();
holder.itemBing.tvClassName.setText(name);
if (position == data.size() - 1) {
holder.itemBing.spaceView.setVisibility(View.VISIBLE);
} else {
holder.itemBing.spaceView.setVisibility(View.GONE);
}
Glide.with(mContext)
.asDrawable()
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.load(previewUrl400)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target<Drawable> target, boolean isFirstResource) {
Log.d(MyApp.TAG, "------------e=" + e.getMessage() + "---previewUrl400=" + previewUrl400);
return false;
}
@Override
public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target<Drawable> target, @NonNull DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.placeholder(R.mipmap.im_placeholder)
.into(holder.itemBing.preview);
holder.itemBing.preview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onClickMore(name);
}
});
}
@Override
public int getItemCount() {
return data.size();
}
static class HomeParentHolder extends RecyclerView.ViewHolder {
private ProjectMainBinding itemBing;
public HomeParentHolder(@NonNull ProjectMainBinding itemView) {
super(itemView.getRoot());
itemBing = itemView;
}
}
}

View File

@ -0,0 +1,99 @@
package com.wall.photography.picture.fragment;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import com.wall.photography.picture.MyApp;
import com.wall.photography.picture.R;
import com.wall.photography.picture.Activity.Wallpaper;
import com.wall.photography.picture.databinding.FragmentLikeBinding;
import com.wall.photography.picture.tool.CommonUtils;
import com.wall.photography.picture.tool.ObjectBoxManager;
import com.wall.photography.picture.tool.GridItemDecoration;
import com.wall.photography.picture.Connect.ItemClick;
import com.wall.photography.picture.Connect.LikeList;
import com.wall.photography.picture.Data.Data;
import java.util.List;
import io.objectbox.reactive.DataSubscription;
public class Like extends Fragment implements ItemClick {
private FragmentLikeBinding vb;
private DataSubscription dataSubscription;
public Like() {
}
public static Like newInstance() {
Like fragment = new Like();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
vb = FragmentLikeBinding.inflate(inflater, container, false);
vb.tvTitle.setText(getString(R.string.no_like_data));
initList();
return vb.getRoot();
}
private void initList() {
com.wall.photography.picture.Project.Like itemLike = new com.wall.photography.picture.Project.Like(requireContext());
dataSubscription = ObjectBoxManager.setLikeDataListener(new LikeList() {
@Override
public void onLikeList(List<Data> dataList) {
Log.d(MyApp.TAG, "------size = " + dataList.size());
if(dataList.size()==0){
vb.layoutNoData.setVisibility(View.VISIBLE);
vb.listRecycler.setVisibility(View.GONE);
}else {
vb.layoutNoData.setVisibility(View.GONE);
vb.listRecycler.setVisibility(View.VISIBLE);
itemLike.setDataInfo(dataList);
}
}
});
GridItemDecoration GridItemDecoration = new GridItemDecoration(10, 10, 15);
GridLayoutManager gridLayoutManager = new GridLayoutManager(requireContext(), 2);
vb.listRecycler.setLayoutManager(gridLayoutManager);
vb.listRecycler.addItemDecoration(GridItemDecoration);
itemLike.setInfoWallpaperListener(this);
vb.listRecycler.setAdapter(itemLike);
}
@Override
public void onItemClickAction(Data info) {
Intent intent = new Intent(requireContext(), Wallpaper.class);
intent.putExtra(CommonUtils.key_info, info);
startActivity(intent);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (dataSubscription != null) {
dataSubscription.cancel();
}
Log.d(MyApp.TAG,"------favoriteFragment-onDestroyView");
}
}

View File

@ -0,0 +1,91 @@
package com.wall.photography.picture.fragment
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.wall.photography.picture.Activity.Wallpaper
import com.wall.photography.picture.Connect.ItemClick
import com.wall.photography.picture.Data.Data
import com.wall.photography.picture.Project.List
import com.wall.photography.picture.databinding.FragmentMainChildBinding
import com.wall.photography.picture.tool.CommonUtils
import com.wall.photography.picture.tool.GridItemDecoration
import com.wall.photography.picture.tool.ObjectBoxManager
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [MainChildFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class MainChildFragment : Fragment(), ItemClick {
// TODO: Rename and change types of parameters
private var param1Tag: String? = null
private var param2: String? = null
private lateinit var vb: FragmentMainChildBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1Tag = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
vb = FragmentMainChildBinding.inflate(inflater, container, false)
initData()
return vb.root
}
private fun initData() {
Log.d("-----------", "----------------initData")
val queryWallpapersByTag = ObjectBoxManager.queryWallpapersByTag(param1Tag, 500)
Log.d("-----------", "----------------queryWallpapersByTag")
val itemHelper = GridItemDecoration(10, 10, 0)
val gridLayoutManager = GridLayoutManager(requireContext(), 3)
vb.recyclerview.addItemDecoration(itemHelper)
vb.recyclerview.setLayoutManager(gridLayoutManager)
vb.recyclerview.setHasFixedSize(true)
vb.recyclerview.setItemViewCacheSize(20)
val height = CommonUtils.dp2Px(180)
val itemList = List(requireContext(), height, false)
itemList.setDataInfo(queryWallpapersByTag)
itemList.setInfoWallpaperListener(this@MainChildFragment)
vb.recyclerview.setAdapter(itemList)
}
override fun onItemClickAction(info: Data?) {
val intent = Intent(requireContext(), Wallpaper::class.java)
intent.putExtra(CommonUtils.key_info, info)
startActivity(intent)
}
companion object {
@JvmStatic
fun newInstance(tag: String) =
MainChildFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, tag)
// putString(ARG_PARAM2, param2)
}
}
}
}

View File

@ -0,0 +1,346 @@
package com.wall.photography.picture.fragment;
import android.content.Intent;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import com.wall.photography.picture.R;
import com.wall.photography.picture.Activity.Search;
import com.wall.photography.picture.Activity.Wallpaper;
import com.wall.photography.picture.databinding.FragmentMainBinding;
import com.wall.photography.picture.Data.Data;
import com.wall.photography.picture.tool.CommonUtils;
import com.wall.photography.picture.tool.GridItemDecoration;
import com.wall.photography.picture.Connect.ItemClick;
import com.wall.photography.picture.Project.List;
import com.wall.photography.picture.tool.ObjectBoxManager;
import java.util.ArrayList;
public class MainFragment extends Fragment implements ItemClick {
private FragmentMainBinding vb;
private ArrayList<String> tabTexts;
private String currentTag = "Feature"; // 默认选中Feature
private List itemList;
public MainFragment() {
}
public static MainFragment newInstance(int type) {
Bundle bundle = new Bundle();
bundle.putInt(CommonUtils.key_index, type);
MainFragment fragment = new MainFragment();
fragment.setArguments(bundle);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
vb = FragmentMainBinding.inflate(inflater, container, false);
tabTexts = new ArrayList<>();
tabTexts.add(getString(R.string.Feature));
tabTexts.add(getString(R.string.Animal));
tabTexts.add(getString(R.string.Film));
initTabVp();
return vb.getRoot();
}
private void initTabVp() {
vb.loadingPb.setVisibility(View.GONE);
initList();
initTags();
}
private void initTags() {
// 默认选中Feature设置初始状态
vb.btnTag4d.setSelected(true);
vb.btnTagLive.setSelected(false);
vb.btnTag4k.setSelected(false);
// 去掉所有阴影和边框效果
vb.btnTag4d.setElevation(0f);
vb.btnTagLive.setElevation(0f);
vb.btnTag4k.setElevation(0f);
vb.btnTag4d.setBackground(null);
vb.btnTagLive.setBackground(null);
vb.btnTag4k.setBackground(null);
// 字体大小保持布局文件中的设置不变25sp
// 设置浅绿色和下划线
setupTextStyle(vb.btnTag4d, true);
setupTextStyle(vb.btnTagLive, false);
setupTextStyle(vb.btnTag4k, false);
// 更新下划线显示状态和宽度
updateUnderlineVisibility(R.id.underline_4d, true); // 默认选中Feature显示下划线
updateUnderlineVisibility(R.id.underline_live, false);
updateUnderlineVisibility(R.id.underline_4k, false);
// 更新下划线颜色
updateUnderlineColor(R.id.underline_4d, true);
updateUnderlineColor(R.id.underline_live, false);
updateUnderlineColor(R.id.underline_4k, false);
updateUnderlineWidth(vb.btnTag4d, R.id.underline_4d);
// 设置点击监听器到包含TextView的RelativeLayout
View layout4d = vb.getRoot().findViewById(R.id.layout_tag_4d);
View layoutLive = vb.getRoot().findViewById(R.id.layout_tag_live);
View layout4k = vb.getRoot().findViewById(R.id.layout_tag_4k);
initVp();
if (layout4d != null) {
layout4d.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchTag(tabTexts.get(0));
}
});
}
if (layoutLive != null) {
layoutLive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchTag(tabTexts.get(1));
}
});
}
if (layout4k != null) {
layout4k.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchTag(tabTexts.get(2));
}
});
}
// 设置搜索图标点击事件
if (vb.btnSearch != null) {
vb.btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 跳转到搜索页面
Intent intent = new Intent(requireContext(), Search.class);
startActivity(intent);
}
});
}
}
private void initVp() {
java.util.List<Fragment> list = new ArrayList<>();
list.add(MainChildFragment.newInstance(tabTexts.get(0)));
list.add(MainChildFragment.newInstance(tabTexts.get(1)));
list.add(MainChildFragment.newInstance(tabTexts.get(2)));
vb.vp2.setOffscreenPageLimit(2);
vb.vp2.setUserInputEnabled(false);
vb.vp2.setAdapter(new FragmentStateAdapter(this) {
@NonNull
@Override
public Fragment createFragment(int position) {
return list.get(position);
}
@Override
public int getItemCount() {
return list.size();
}
});
}
private void switchTag(String tag) {
if (currentTag.equals(tag)) {
return; // 如果已经是当前标签不重复切换
}
currentTag = tag;
// 更新标签选中状态和文字颜色
boolean is4D = tag.equals("Feature");
boolean isLIVE = tag.equals("Animal");
boolean is4K = tag.equals("Film");
vb.btnTag4d.setSelected(is4D);
vb.btnTagLive.setSelected(isLIVE);
vb.btnTag4k.setSelected(is4K);
// 动态更新文字颜色和下划线浅绿色带下划线
setupTextStyle(vb.btnTag4d, is4D);
setupTextStyle(vb.btnTagLive, isLIVE);
setupTextStyle(vb.btnTag4k, is4K);
// 更新下划线显示状态和宽度
updateUnderlineVisibility(R.id.underline_4d, is4D);
updateUnderlineVisibility(R.id.underline_live, isLIVE);
updateUnderlineVisibility(R.id.underline_4k, is4K);
// 更新下划线颜色
updateUnderlineColor(R.id.underline_4d, is4D);
updateUnderlineColor(R.id.underline_live, isLIVE);
updateUnderlineColor(R.id.underline_4k, is4K);
if (is4D) {
updateUnderlineWidth(vb.btnTag4d, R.id.underline_4d);
}
if (isLIVE) {
updateUnderlineWidth(vb.btnTagLive, R.id.underline_live);
}
if (is4K) {
updateUnderlineWidth(vb.btnTag4k, R.id.underline_4k);
}
// 字体大小保持布局文件中的设置不变不进行任何变化
// 刷新列表数据
// refreshListData();
if (tag.equals(tabTexts.get(0))) {
vb.vp2.setCurrentItem(0);
} else if (tag.equals(tabTexts.get(1))) {
vb.vp2.setCurrentItem(1);
} else {
vb.vp2.setCurrentItem(2);
}
}
/**
* 设置文字样式选中时深绿色未选中时浅绿色
*/
private void setupTextStyle(TextView textView, boolean isSelected) {
// 颜色值
int lightGreenColor = 0xFF90EE90; // 浅绿色未选中
int darkGreenColor = 0xFF228B22; // 深绿色选中- ForestGreen
// 根据选中状态设置文字颜色
int textColor = isSelected ? darkGreenColor : lightGreenColor;
textView.setTextColor(textColor);
// 移除默认的PaintFlags下划线
textView.setPaintFlags(textView.getPaintFlags() & ~Paint.UNDERLINE_TEXT_FLAG);
}
/**
* 更新下划线显示/隐藏状态
*/
private void updateUnderlineVisibility(int underlineViewId, boolean isVisible) {
View underlineView = vb.getRoot().findViewById(underlineViewId);
if (underlineView != null) {
underlineView.setVisibility(isVisible ? View.VISIBLE : View.INVISIBLE);
}
}
/**
* 更新下划线颜色选中时深绿色未选中时浅绿色
*/
private void updateUnderlineColor(int underlineViewId, boolean isSelected) {
View underlineView = vb.getRoot().findViewById(underlineViewId);
if (underlineView != null) {
int lightGreenColor = 0xFF90EE90; // 浅绿色未选中
int darkGreenColor = 0xFF228B22; // 深绿色选中- ForestGreen
int underlineColor = isSelected ? darkGreenColor : lightGreenColor;
underlineView.setBackgroundColor(underlineColor);
}
}
/**
* 更新下划线宽度以匹配文字宽度
*/
private void updateUnderlineWidth(TextView textView, int underlineViewId) {
View underlineView = vb.getRoot().findViewById(underlineViewId);
if (underlineView != null && textView != null) {
// 使用post确保TextView已经完成测量
textView.post(new Runnable() {
@Override
public void run() {
// 计算文字的实际宽度不包括padding
Paint paint = textView.getPaint();
String text = textView.getText().toString();
float textWidth = paint.measureText(text);
// 设置下划线的宽度为文字宽度
ViewGroup.LayoutParams params = underlineView.getLayoutParams();
params.width = (int) textWidth;
underlineView.setLayoutParams(params);
}
});
}
}
private void refreshListData() {
java.util.List<Data> data = ObjectBoxManager.queryWallpapersByTag(currentTag, 500);
if (itemList != null) {
itemList.setDataInfo(data);
} else {
initList();
}
}
private void initList() {
// java.util.List<Data> data = ObjectBoxManager.queryWallpapersByTag(currentTag, 500);
// android.util.Log.d("FragmentMain", "已載入 " + data.size() + " 張圖片,標籤: " + currentTag);
//
// if (data.isEmpty()) {
// android.util.Log.e("FragmentMain", "數據庫中沒有找到數據!請檢查數據是否正確加載。");
// // 顯示錯誤提示給用戶
// if (getActivity() != null) {
// getActivity().runOnUiThread(new Runnable() {
// @Override
// public void run() {
// android.widget.Toast.makeText(requireContext(),
// "正在載入圖片數據,請稍候...",
// android.widget.Toast.LENGTH_LONG).show();
// }
// });
// }
// }
//
// GridItemDecoration itemHelper = new GridItemDecoration(10, 10, 0);
// GridLayoutManager gridLayoutManager = new GridLayoutManager(requireContext(), 3);
// vb.classRecycler.addItemDecoration(itemHelper);
// vb.classRecycler.setLayoutManager(gridLayoutManager);
// int height = CommonUtils.dp2Px(180);
// itemList = new List(requireContext(), height, false);
// itemList.setDataInfo(data);
// itemList.setInfoWallpaperListener(this);
// vb.classRecycler.setAdapter(itemList);
}
@Override
public void onItemClickAction(Data info) {
Intent intent = new Intent(requireContext(), Wallpaper.class);
intent.putExtra(CommonUtils.key_info, info);
startActivity(intent);
}
@Override
public void onClickMore(String name) {
Intent intent = new Intent(requireContext(), com.wall.photography.picture.Activity.List.class);
intent.putExtra(com.wall.photography.picture.Activity.List.key_index, name);
startActivity(intent);
}
@Override
public void onTagClick(String tagType, Data info) {
// 点击标签后跳转到列表页面显示所有壁纸标签用于筛选
Intent intent = new Intent(requireContext(), com.wall.photography.picture.Activity.List.class);
intent.putExtra(com.wall.photography.picture.Activity.List.key_index, tagType);
startActivity(intent);
}
}

View File

@ -0,0 +1,89 @@
package com.wall.photography.picture.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.wall.photography.picture.databinding.MyDialogBinding;
import com.wall.photography.picture.Connect.SelectType;
public class MyDialog extends DialogFragment {
private MyDialogBinding vb;
private SelectType 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(SelectType listener) {
this.listener = listener;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
vb = MyDialogBinding.inflate(inflater, container, false);
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){
listener.onSelectType(type_home);
dismiss();
}
}
});
vb.layoutLock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener!= null){
listener.onSelectType(type_lock);
dismiss();
}
}
});
vb.layoutBoth.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(listener!= null){
listener.onSelectType(type_both);
dismiss();
}
}
});
}
}

View File

@ -0,0 +1,101 @@
package com.wall.photography.picture.fragment;
import android.app.Dialog;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import com.wall.photography.picture.databinding.DialogRateUsBinding;
public class RatingDialog extends DialogFragment {
private DialogRateUsBinding binding;
private int selectedRating = 0;
private ImageView[] stars;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DialogRateUsBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// 初始化星星数组
stars = new ImageView[]{
binding.star1,
binding.star2,
binding.star3,
binding.star4,
binding.star5
};
// 设置初始状态为灰色
updateStarsDisplay(0);
// 为每个星星设置点击事件
for (int i = 0; i < stars.length; i++) {
final int rating = i + 1;
stars[i].setOnClickListener(v -> {
selectedRating = rating;
updateStarsDisplay(rating);
binding.btnSubmit.setEnabled(true);
});
}
// 取消按钮
binding.btnCancel.setOnClickListener(v -> dismiss());
// 提交按钮
binding.btnSubmit.setOnClickListener(v -> {
if (selectedRating > 0) {
Toast.makeText(getContext(),
"Thank you for rating us " + selectedRating + " stars!",
Toast.LENGTH_SHORT).show();
dismiss();
}
});
}
private void updateStarsDisplay(int rating) {
for (int i = 0; i < stars.length; i++) {
if (i < rating) {
// 选中的星星 - 金色
stars[i].setColorFilter(Color.parseColor("#FFD700"), PorterDuff.Mode.SRC_IN);
} else {
// 未选中的星星 - 灰色
stars[i].setColorFilter(Color.parseColor("#CCCCCC"), PorterDuff.Mode.SRC_IN);
}
}
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
return dialog;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

View File

@ -0,0 +1,78 @@
package com.wall.photography.picture.fragment;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import com.wall.photography.picture.databinding.FragmentSettingsBinding;
public class Settings extends Fragment {
private FragmentSettingsBinding vb;
public Settings() {
}
public static Settings newInstance() {
Settings fragment = new Settings();
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
vb = FragmentSettingsBinding.inflate(inflater, container, false);
// 设置点击事件
setupClickListeners();
setVersion();
return vb.getRoot();
}
private void setVersion() {
try {
PackageManager pm = requireActivity().getPackageManager();
PackageInfo pInfo = pm.getPackageInfo(requireActivity().getPackageName(), 0);
String versionName = pInfo.versionName;
vb.tvVersionNumber.setText("V " + versionName);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
vb.tvVersionNumber.setText("V 1.0");
}
}
private void setupClickListeners() {
// Rate us 点击事件 - 显示评星对话框
if (vb.layoutRateUs != null) {
vb.layoutRateUs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showRatingDialog();
}
});
}
// Version - 移除点击监听不可点击
if (vb.layoutPrivacy != null) {
vb.layoutPrivacy.setOnClickListener(null);
vb.layoutPrivacy.setClickable(false);
vb.layoutPrivacy.setFocusable(false);
}
}
private void showRatingDialog() {
RatingDialog ratingDialog = new RatingDialog();
if (getActivity() != null) {
ratingDialog.show(getActivity().getSupportFragmentManager(), "RatingDialog");
}
}
}

View File

@ -0,0 +1,145 @@
package com.wall.photography.picture.tool;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Debug;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.wall.photography.picture.MyApp;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
public class CommonUtils {
public static final String key_info = "key_info";
public static final String key_index = "key_index";
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 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);
}
private static Bitmap getBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
// 创建一个空白的 Bitmap
Bitmap bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
// <EFBFBD>?Canvas 上绘<EFBFBD>?Drawable
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
public static String saveDrawableToFile( Drawable drawable,String saveFilePath) {
// <EFBFBD>?Drawable 转换<EFBFBD>?Bitmap
Bitmap bitmap = getBitmap(drawable);
// 创建要保存的文件
File file = new File(saveFilePath);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
// <EFBFBD>?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();
}
public static void printUsedMemory(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
Debug.MemoryInfo[] memoryInfoArray = activityManager.getProcessMemoryInfo(new int[]{android.os.Process.myPid()});
for (Debug.MemoryInfo memoryInfo : memoryInfoArray) {
int totalPss = memoryInfo.getTotalPss();
int totalPrivateDirty = memoryInfo.getTotalPrivateDirty();
int totalSharedDirty = memoryInfo.getTotalSharedDirty();
Log.d("MemoryInfo", "Total PSS: " + totalPss + " KB");
Log.d("MemoryInfo", "Total Private Dirty: " + totalPrivateDirty + " KB");
Log.d("MemoryInfo", "Total Shared Dirty: " + totalSharedDirty + " KB");
}
}
public static int[] getScreenWidthHeight(Context context) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
return new int[]{width, height};
}
}

View File

@ -0,0 +1,35 @@
package com.wall.photography.picture.tool;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
import com.wall.photography.picture.MyApp;
import com.wall.photography.picture.R;
public class CustomTextView extends androidx.appcompat.widget.AppCompatTextView {
public CustomTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initAttrs(context,attrs);
}
private void initAttrs(Context context, AttributeSet attrs){
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomeTv);
boolean aBoolean = typedArray.getBoolean(R.styleable.CustomeTv_apply_font,false);
if(aBoolean){
setTypeface(MyApp.defaultFont);
}
typedArray.recycle();
}
}

View File

@ -0,0 +1,57 @@
package com.wall.photography.picture.tool;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class GridItemDecoration 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 GridItemDecoration(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,229 @@
package com.wall.photography.picture.tool
import android.Manifest
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.util.Log
import androidx.core.app.ActivityCompat
import com.wall.photography.picture.MyApp
import com.wall.photography.picture.Data.Data
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONArray
import org.json.JSONObject
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
object JsonParser {
fun getData(jsonStr: String, category: String): MutableList<Data> {
val jsonArray = JSONArray(jsonStr)
var data = mutableListOf<Data>()
var get: JSONObject
var text_description: String
var links: JSONObject
var download: String
var urls: JSONObject
var regular: String
var small: String
var thumb: String
var users: JSONObject
var name: String
var header_large: String
var user_html: String
val host = "https://unsplash.com/photos/"
var bean: Data
var indexOf: Int
var substring: String
for (i in 0 until 300) {
get = jsonArray.getJSONObject(i)
text_description = get.getString("alt_description")
links = get.getJSONObject("links")
download = links.getString("download")
// val downloadLocation = links.getString("download_location")
// val html = links.getString("html")
urls = get.getJSONObject("urls")
// val full = urls.getString("full")
// val raw = urls.getString("raw")
regular = urls.getString("regular")
small = urls.getString("small")
thumb = urls.getString("thumb")
users = get.getJSONObject("user")
// val portfolio_url = users.getString("portfolio_url")
name = users.getString("name")
header_large = users.getString("header_large")
// val header_medium = users.getString("header_medium")
// val header_small = users.getString("header_small")
user_html = users.getString("authorHtml")
indexOf = download.indexOf("/download")
substring = download.substring(host.length, indexOf)
// Log.d(MyApp.TAG, "i=$i----------substring=$substring")
bean = Data().apply {
imId = substring
categoryName = category
description = text_description
fullUrl = download
previewUrl1080 = regular
previewUrl400 = small
previewUrl200 = thumb
authorName = name
authorHeader = header_large
authorHtml = user_html
}
data.add(bean)
}
return data
}
fun downloadFile(
url: String,
savePath: String,
result: (Boolean, input: InputStream?) -> Unit
): Call {
var client = OkHttpClient()
var request = Request.Builder().url(url).build()
var call = client.newCall(request)
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
result.invoke(false, null)
}
override fun onResponse(call: Call, response: Response) {
response.body?.run {
val byteStream = byteStream()
val writeFile = writeFile(byteStream, savePath)
result.invoke(writeFile, byteStream)
} ?: run {
result.invoke(false, null)
}
}
})
return call
}
fun writeFile(input: InputStream, filePath: String): Boolean {
try {
val byte = ByteArray(4096)
val output = ByteArrayOutputStream()
var l: Int
while (input.read(byte).also { l = it } != -1) {
output.write(byte, 0, l)
}
val fileDe = File(filePath)
if (!fileDe.exists()) {
fileDe.createNewFile()
}
val fileOutputStream = FileOutputStream(filePath)
fileOutputStream.write(output.toByteArray())
output.close()
fileOutputStream.close()
return true
} catch (ex: Exception) {
Log.d("-----------", "---------ex=" + ex.message)
return false
}
}
fun saveToGallery(context: Context, photoFile: File): Uri? {
val displayName = "${System.currentTimeMillis()}.jpg"
val contentValues = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, displayName)
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.Images.Media.IS_PENDING, 1)
}
}
val contentResolver = context.contentResolver
val collectionUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
val imageUri = contentResolver.insert(collectionUri, contentValues)
imageUri?.let { uri ->
try {
contentResolver.openOutputStream(uri)?.use { outputStream ->
val inputStream = FileInputStream(photoFile)
inputStream.copyTo(outputStream)
inputStream.close()
outputStream.close()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.clear()
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
contentResolver.update(uri, contentValues, null, null)
} else {
}
return uri
} catch (e: IOException) {
Log.d(MyApp.TAG, "-----------------e=${e.printStackTrace()}")
return null
}
} ?: run {
Log.d(MyApp.TAG, "----------------false")
return null
}
}
fun requestPermission(context: Activity, requestCode: Int): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return true
}
return if (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
context,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
requestCode
)
false
} else {
true
}
}
fun getSaveFilePath(context: Context, imId: String): String {
return "${context.cacheDir}/${imId}.jpg"
}
}

View File

@ -0,0 +1,249 @@
package com.wall.photography.picture.tool;
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import com.wall.photography.picture.MyApp;
import com.wall.photography.picture.Data.Data;
import com.wall.photography.picture.Data.Data_;
import com.wall.photography.picture.Data.MyObjectBox;
import com.wall.photography.picture.Connect.OnUpdateLike;
import com.wall.photography.picture.Connect.LikeList;
import java.util.ArrayList;
import java.util.List;
import io.objectbox.Box;
import io.objectbox.BoxStore;
import io.objectbox.android.AndroidScheduler;
import io.objectbox.query.Query;
import io.objectbox.query.QueryBuilder;
import io.objectbox.reactive.DataObserver;
import io.objectbox.reactive.DataSubscription;
import io.objectbox.reactive.DataSubscriptionList;
public class ObjectBoxManager {
private static BoxStore boxStore;
private static Box<Data> LikeBox;
private static List<OnUpdateLike> list = new ArrayList<>();
public static void init(Context context) {
boxStore = MyObjectBox.builder().androidContext(context).build();
}
public static Box<Data> getObjectBoxLike() {
if (LikeBox == null) {
LikeBox = boxStore.boxFor(Data.class);
}
return LikeBox;
}
public static void addData(Data data) {
Box<Data> objectBoxLike = getObjectBoxLike();
String imId = data.getImId();
Data first = objectBoxLike.query()
.equal(Data_.imId, imId, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.findFirst();
if (first == null) {
Log.d(MyApp.TAG, "-----------addData " + imId);
objectBoxLike.put(data);
}else {
Log.d(MyApp.TAG, "-----------忽略添加 ");
}
}
public static DataSubscription setLikeDataListener(LikeList listener) {
Query<Data> build = getObjectBoxLike().query()
.equal(Data_.isLike, true)
.build();
return build.subscribe(new DataSubscriptionList())
.on(AndroidScheduler.mainThread())
.observer(new DataObserver<List<Data>>() {
@Override
public void onData(@NonNull List<Data> data) {
Log.d(MyApp.TAG, "------data=" + data.size());
listener.onLikeList(data);
}
});
}
public static void updateLike(Data boxLike) {
Box<Data> objectBoxLike = getObjectBoxLike();
String imId = boxLike.getImId();
objectBoxLike.put(boxLike);
for (OnUpdateLike listener : list) {
listener.onAdd(boxLike);
}
}
public static void insertOrUpdateDownload(Data boxLike) {
Box<Data> objectBoxLike = getObjectBoxLike();
String imId = boxLike.getImId();
Data first = objectBoxLike.query()
.equal(Data_.imId, imId, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.findFirst();
if (first == null) {
Log.d(MyApp.TAG, "-----------添加11 Download=" + imId);
boxLike.setDownload(true);
objectBoxLike.put(boxLike);
} else {
first.setDownload(true);
objectBoxLike.put(first);
Log.d(MyApp.TAG, "-----------已经存在添加22 Download=" + imId);
}
}
public static List<Data> search(String name) {
Box<Data> objectBoxLike = getObjectBoxLike();
List<Data> data = objectBoxLike.query()
.contains(Data_.description, name, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.find();
return data;
}
public static List<Data> queryHome(String name) {
Box<Data> objectBoxLike = getObjectBoxLike();
List<Data> data = objectBoxLike.query()
.equal(Data_.categoryName, name, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.find(10, 1);
return data;
}
public static List<Data> queryCategoryAll(String name) {
Box<Data> objectBoxLike = getObjectBoxLike();
List<Data> data = objectBoxLike.query()
.equal(Data_.categoryName, name, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.find(0, 200);
return data;
}
public static boolean queryIsLike(String imId) {
Box<Data> objectBoxLike = getObjectBoxLike();
Data first = objectBoxLike.query()
.equal(Data_.imId, imId, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.findFirst();
if (first != null && first.isLike()) {
return true;
} else {
return false;
}
}
public static List<Data> queryAllWallpapers(int limit) {
Box<Data> objectBoxLike = getObjectBoxLike();
List<Data> data = objectBoxLike.query()
.build()
.find(0, limit);
return data;
}
/**
* 根据标签类型查询壁纸
* 将FeatureAnimalFilm映射到不同的分类
*/
public static List<Data> queryWallpapersByTag(String tagType, int limit) {
Box<Data> objectBoxLike = getObjectBoxLike();
List<Data> data = new ArrayList<>();
// 将标签映射到多个分类实现分类功<EFBFBD>?
List<String> categories = getCategoriesForTag(tagType);
if (categories != null && !categories.isEmpty()) {
// 查询多个分类的壁<EFBFBD>?
for (String category : categories) {
List<Data> categoryData = objectBoxLike.query()
.equal(Data_.categoryName, category, QueryBuilder.StringOrder.CASE_SENSITIVE)
.build()
.find(0, limit / categories.size() + 1);
data.addAll(categoryData);
// 如果已经达到限制退<EFBFBD>?
if (data.size() >= limit) {
break;
}
}
// 如果数据超过限制截取前limit<EFBFBD>?
if (data.size() > limit) {
data = data.subList(0, limit);
}
} else {
// 如果没有匹配的分类返回所有壁<EFBFBD>?
data = objectBoxLike.query()
.build()
.find(0, limit);
}
return data;
}
/**
* 根据标签类型获取对应的分类列表
*/
private static List<String> getCategoriesForTag(String tagType) {
List<String> categories = new ArrayList<>();
switch (tagType) {
case "Feature":
// Feature标签对应FeaturedsearchJSON文件名去掉.json后缀
categories.add("Featuredsearch");
break;
case "Animal":
// Animal标签对应AnimalssearchJSON文件名去掉.json后缀
categories.add("Animalssearch");
break;
case "Film":
// Film标签对应FilmsearchJSON文件名去掉.json后缀
categories.add("Filmsearch");
break;
default:
// 默认返回所有分类
break;
}
return categories;
}
/**
* 获取所有分类名称对应JSON文件名去掉.json后缀
*/
public static List<String> getAllCategories() {
List<String> categories = new ArrayList<>();
categories.add("Featuredsearch");
categories.add("Animalssearch");
categories.add("Experimentalsearch");
categories.add("Filmsearch");
categories.add("Naturesearch");
categories.add("Patternssearch");
categories.add("Streetsearch");
categories.add("Travelsearch");
return categories;
}
}

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="#228B22" />
<corners android:radius="8dp" />
</shape>

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="#CCCCCC" />
<corners android:radius="8dp" />
</shape>

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,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="270"
android:startColor="#F0F8F0"
android:centerColor="#E8F5E8"
android:endColor="#D0E8D0"
android:type="linear" />
</shape>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#CCCCCC"
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M878.6,337.2a57.8,57.8 0,0 0,-81.7 0L574.6,559.5V173a57.8,57.8 0,0 0,-115.6 0v386.5L236.8,337.2a57.8,57.8 0,0 0,-81.7 0,57.8 57.8,0 0,0 0,81.8l318.7,318.7a57.6,57.6 0,0 0,40.9 16.9c0.7,0 1.5,-0.1 2.2,-0.1 0.7,0 1.5,0.1 2.2,0.1a57.6,57.6 0,0 0,40.9 -16.9L878.6,419a57.8,57.8 0,0 0,0 -81.8zM861,908.4H165.4a57.8,57.8 0,0 1,0 -115.6h695.6a57.8,57.8 0,0 1,0 115.6z"
android:fillColor="@color/white"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M667.8,117.3C832.9,117.3 938.7,249.7 938.7,427.9c0,138.3 -125.1,290.5 -371.6,461.6a96.8,96.8 0,0 1,-110.2 0C210.4,718.4 85.3,566.1 85.3,427.9 85.3,249.7 191.1,117.3 356.2,117.3c59.6,0 100.1,20.8 155.8,68.1C567.7,138.2 608.2,117.3 667.8,117.3z"
android:fillColor="@color/favorite_true"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M555.5,118l312.9,224.6A117.3,117.3 0,0 1,917.3 437.9V800c0,64.8 -52.5,117.3 -117.3,117.3H640V746.7c0,-70.7 -57.3,-128 -128,-128s-128,57.3 -128,128v170.7H224c-64.8,0 -117.3,-52.5 -117.3,-117.3V437.9a117.3,117.3 0,0 1,48.9 -95.3l312.9,-224.6a74.7,74.7 0,0 1,87.1 0z"
android:fillColor="@color/color_fad91d"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M555.5,118l312.9,224.6A117.3,117.3 0,0 1,917.3 437.9V800c0,64.8 -52.5,117.3 -117.3,117.3H640V746.7c0,-70.7 -57.3,-128 -128,-128s-128,57.3 -128,128v170.7H224c-64.8,0 -117.3,-52.5 -117.3,-117.3V437.9a117.3,117.3 0,0 1,48.9 -95.3l312.9,-224.6a74.7,74.7 0,0 1,87.1 0z"
android:fillColor="@color/sub_color"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M667.8,117.3C832.9,117.3 938.7,249.7 938.7,427.9c0,138.3 -125.1,290.5 -371.6,461.6a96.8,96.8 0,0 1,-110.2 0C210.4,718.4 85.3,566.1 85.3,427.9 85.3,249.7 191.1,117.3 356.2,117.3c59.6,0 100.1,20.8 155.8,68.1C567.7,138.2 608.2,117.3 667.8,117.3z"
android:fillColor="@color/color_fad91d"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M667.8,117.3C832.9,117.3 938.7,249.7 938.7,427.9c0,138.3 -125.1,290.5 -371.6,461.6a96.8,96.8 0,0 1,-110.2 0C210.4,718.4 85.3,566.1 85.3,427.9 85.3,249.7 191.1,117.3 356.2,117.3c59.6,0 100.1,20.8 155.8,68.1C567.7,138.2 608.2,117.3 667.8,117.3z"
android:fillColor="@color/sub_color"/>
</vector>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/color_fad91d"/>
<size android:height="5dp" android:width="5dp"/>
</shape>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M747.2,283.2L54.5,283.2v692.7h692.7v-692.7zM656.8,373.6v512h-512v-512h512z"
android:fillColor="@color/white"/>
<path
android:pathData="M993.3,12.4v692.7h-287.2v-90.4h196.8v-512h-512v224.4h-90.4V12.4z"
android:fillColor="@color/white"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/white"
android:pathData="M776.7,1010.1h-479.9c-28.3,0 -51.3,-23 -51.3,-51.3v-891.1c0,-28.3 23,-51.3 51.3,-51.3h479.9c28.3,0 51.3,23 51.3,51.3v891.1c0,28.3 -23,51.3 -51.3,51.3v0zM536.6,958.8c19.1,0 34.2,-15.4 34.2,-34.2s-15.4,-34.2 -34.2,-34.2 -34.2,15.4 -34.2,34.2 15.4,34.2 34.2,34.2v0zM776.7,119h-479.9v719.7h479.6v-719.7h0.3z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M154.5,469.3H981.3a42.7,42.7 0,1 1,0 85.3H154.5l300.7,266.9a42.7,42.7 0,1 1,-57.1 63.4l-384,-341.3a42.7,42.7 0,0 1,0 -63.4l384,-341.3a42.7,42.7 0,1 1,57.1 63.4L154.5,469.3z"
android:fillColor="@color/black"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M667.8,117.3C832.9,117.3 938.7,249.7 938.7,427.9c0,138.3 -125.1,290.5 -371.6,461.6a96.8,96.8 0,0 1,-110.2 0C210.4,718.4 85.3,566.1 85.3,427.9 85.3,249.7 191.1,117.3 356.2,117.3c59.6,0 100.1,20.8 155.8,68.1C567.7,138.2 608.2,117.3 667.8,117.3zM667.8,180.5c-41.4,0 -70.3,15.2 -117,55 -2.2,1.8 -14.4,12.4 -17.9,15.4a32.3,32.3 0,0 1,-41.8 0c-3.5,-3 -15.8,-13.5 -17.9,-15.4 -46.7,-39.9 -75.5,-55 -117,-55C230.2,180.5 149.3,281.3 149.3,426.7 149.3,537.6 262.9,675.2 493.6,834.8a32.4,32.4 0,0 0,36.7 0C761.1,675.3 874.7,537.6 874.7,426.7c0,-145.4 -80.9,-246.2 -206.9,-246.2z"
android:fillColor="@color/white"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/sub_color"
android:pathData="M320,447.9c35.4,0 64,-28.6 64,-64s-28.6,-64 -64,-64 -64,28.6 -64,64S284.6,447.9 320,447.9zM751.7,706.8c-146.5,-91 -333.4,-91 -479.9,0 -14.3,8.9 -19.3,28.7 -11.3,44.5 8,15.7 26,21.2 40.4,12.4 128.7,-79.9 292.9,-79.9 421.6,0 4.5,2.9 9.6,4.2 14.5,4.2 10.4,0 20.4,-6 25.9,-16.6C771.1,735.5 766,715.6 751.7,706.8zM832,127.9 L192,127.9c-70.7,0 -128,57.3 -128,128l0,576c0,70.7 57.3,128 128,128l640,0c70.7,0 128,-57.3 128,-128l0,-576C960,185.3 902.7,127.9 832,127.9zM896,831.9c0,35.4 -28.6,64 -64,64L192,895.9c-35.4,0 -64,-28.6 -64,-64l0,-576c0,-35.4 28.6,-64 64,-64l640,0c35.4,0 64,28.6 64,64L896,831.9zM704,319.9c-35.4,0 -64,28.6 -64,64s28.6,64 64,64 64,-28.6 64,-64S739.4,319.9 704,319.9z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M950.8,720.1c22.4,29.5 1.4,71.9 -35.6,71.9L108.8,792c-36.7,0 -57.8,-41.8 -36,-71.4l163.7,-221.9c17.9,-24.2 54.1,-24.2 72,0l95.3,129.2 208.1,-261.3c18.2,-22.8 52.9,-22.4 70.5,0.8l268.4,352.7zM356.8,411.2c-49.4,0 -89.5,-40.1 -89.5,-89.6s40.1,-89.6 89.5,-89.6 89.5,40.1 89.5,89.6 -40,89.6 -89.5,89.6z"
android:fillColor="#D1DEF0"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/white"
android:pathData="M426.9,683l170.8,0c25.6,0 42.7,-17.1 42.7,-42.7L640.3,512.3c0,-25.6 -17.1,-42.7 -42.7,-42.7l0,-42.7c0,-47 -38.4,-85.4 -85.4,-85.4s-85.4,38.4 -85.4,85.4l0,42.7c-25.6,0 -42.7,17.1 -42.7,42.7l0,128.1C384.2,666 401.3,683 426.9,683zM461,426.9c0,-29.9 21.3,-51.2 51.2,-51.2s51.2,21.3 51.2,51.2l0,42.7 -102.5,0L461,426.9 461,426.9zM725.7,42.7 L298.8,42.7c-47,0 -85.4,38.4 -85.4,85.4l0,768.4c0,47 38.4,85.4 85.4,85.4l426.9,0c47,0 85.4,-38.4 85.4,-85.4L811.1,128.1C811.1,81.1 772.7,42.7 725.7,42.7zM725.7,811.1 L298.8,811.1 298.8,213.4l426.9,0L725.7,811.1z"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M271.9,728.1v-412.2c0,-30.7 18.9,-53.8 39.9,-53.8h412.2c21,0 39.9,23.6 39.9,54.3v220.2c0,2 0.5,4.1 1,5.6l14.8,-5.6v-220.2c0,-38.9 -25.1,-70.1 -56.3,-70.1h-412.2c-31.2,0 -56.3,31.2 -56.3,70.1v418.3l16.9,-6.7zM271.9,728.1v-412.2c0,-30.7 18.9,-53.8 39.9,-53.8h412.2c21,0 39.9,23.6 39.9,54.3v220.2c0,2 0.5,4.1 1,5.6l14.8,-5.6v-220.2c0,-38.9 -25.1,-70.1 -56.3,-70.1h-412.2c-31.2,0 -56.3,31.2 -56.3,70.1v418.3l16.9,-6.7zM958.5,800.8c-21.5,-16.9 -45.6,-29.7 -71.7,-38.4 -4.1,-1 -8.7,1.5 -9.7,5.6 -1,4.1 1,8.2 4.6,9.7 24.1,8.2 46.6,20.5 67.1,35.8 3.6,2.6 8.7,1.5 11.3,-2 2,-3.1 1.5,-7.7 -1.5,-10.8zM517.6,817.2c-37.9,0 -75.3,10.2 -108,30.2 -45.6,-61.4 -117.2,-97.3 -194,-97.3 -54.3,0 -107.5,18.4 -150,52.2 -3.1,3.1 -3.6,8.2 -0.5,11.3 2.6,3.1 7.2,3.6 10.2,1 39.9,-31.7 89.1,-48.6 140.3,-48.6 74.8,0 143.4,36.4 185.3,96.8 2.6,3.6 7.2,4.6 11.3,2 31.2,-21 68.1,-31.7 105.5,-31.7 35.8,0 69.6,9.7 99.8,27.6 3.6,2 8.2,1 10.8,-2 13.3,-17.9 29.2,-34.3 47.1,-47.6 3.6,-3.1 4.1,-8.2 1,-11.3 -2.6,-3.1 -7.2,-3.6 -10.8,-1.5 -17.4,12.8 -32.8,28.2 -46.1,45.1 -31.7,-16.9 -66.6,-26.1 -101.9,-26.1zM855.6,846.8c-41,-27.6 -96.3,-16.9 -123.9,23.6l-3.1,4.6c-2,3.6 -1,8.7 3.1,11.3 3.6,2 8.7,1 11.3,-3.1 8.2,-14.3 21.5,-25.1 36.9,-31.2 22.5,-8.7 47.6,-5.6 67.6,7.7 3.6,2.6 8.7,1.5 11.3,-2 1.5,-3.1 0.5,-8.2 -3.1,-10.8zM185.3,248.8c2,1.5 2,4.6 0.5,6.1m-45.1,205.3l-18.9,21c-1,1 -2.6,1 -3.6,0 -1,-1 -1,-2.6 0,-3.6l18.9,-21c1,-1 2.6,-1 3.6,0 1,1 1,2.6 0,3.6zM165.4,460.3l-18.9,21c-1,1 -2.6,1 -3.6,0 -1,-1 -1,-2.6 0,-3.6l18.9,-21c1,-1 2.6,-1 3.6,0 0.5,1 1,2.6 0,3.6zM813.1,146.4l-38.4,43c-2,2.6 -6.1,2.6 -8.2,0.5 -2.6,-2 -2.6,-6.1 -0.5,-8.2l38.4,-43c2,-2.6 6.1,-2.6 8.2,-0.5 2.6,2 2.6,5.6 0.5,8.2zM863.7,146.4l-38.4,43c-2,2.6 -6.1,2.6 -8.2,0.5 -2.6,-2 -2.6,-6.1 -0.5,-8.2l38.4,-43c2,-2.6 6.1,-2.6 8.2,-0.5 2.6,2 3.1,5.6 0.5,8.2z"
android:fillColor="@color/sub_title_color"/>
<path
android:pathData="M390.1,451.6c-17.9,0.5 -32.8,-13.8 -33.3,-31.2 -0.5,-17.9 13.8,-32.8 31.2,-33.3h1.5c17.9,0.5 31.7,15.4 31.2,33.3 0.5,16.9 -13.3,30.7 -30.7,31.2zM382.5,419.3c6.1,0 10.8,-4.6 10.8,-10.8 0,-6.1 -4.6,-10.8 -10.8,-10.8 -6.1,0 -10.8,4.6 -10.8,10.8 0,6.1 4.6,10.8 10.8,10.8zM656.4,451.6c-17.9,0.5 -32.8,-13.8 -33.3,-31.2 -0.5,-17.9 13.8,-32.8 31.2,-33.3h1.5c17.9,0.5 31.7,15.4 31.2,33.3 0.5,16.9 -13.3,30.7 -30.7,31.2zM648.2,419.3c6.1,0 10.8,-4.6 10.8,-10.8 0,-6.1 -4.6,-10.8 -10.8,-10.8s-10.8,4.6 -10.8,10.8c0,6.1 5.1,10.8 10.8,10.8zM596,515.1c-2,0 -4.1,-1 -5.6,-2.6 -11.8,-12.3 -23.6,-17.9 -35.3,-17.4 -11.3,0.5 -21,7.7 -26.1,14.3 -2.6,3.6 -7.7,4.1 -11.3,1.5 -0.5,-0.5 -1,-0.5 -1,-1 -14.3,-16.4 -26.6,-15.9 -36.4,-13.8 -8.2,2 -16.4,6.7 -24.6,14.3 -3.1,3.1 -8.2,2.6 -11.3,-0.5 -3.1,-3.1 -2.6,-8.2 0.5,-11.3 10.2,-9.2 21,-15.4 31.7,-17.9 17.4,-4.6 32.8,-0.5 46.6,12.3 6.7,-6.1 17.4,-12.8 31.7,-13.8 16.4,-1 32.3,6.7 47.6,22.5 3.1,3.1 3.1,8.2 0,11.3 -2.6,1 -4.6,2 -6.7,2zM765.4,798.2c-64.5,0 -116.7,-52.2 -116.7,-116.7 0,-64.5 52.2,-116.7 116.7,-116.7 64.5,0 116.7,52.2 116.7,116.7 0,64.5 -52.2,116.7 -116.7,116.7zM707.6,666.6c-8.7,0 -16.4,7.2 -15.9,16.4 0,8.7 7.2,15.9 15.9,15.9h118.3c8.7,0 16.4,-7.2 15.9,-16.4 0,-8.7 -7.2,-15.9 -15.9,-15.9h-118.3z"
android:fillColor="@color/sub_title_color"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M222.1,580.4a356.2,356.2 0,0 0,34.1 152.9,357.6 357.6,0 0,0 477.7,-477.7A357.6,357.6 0,0 0,222.1 580.4z"
android:fillColor="@color/color_0"/>
<path
android:pathData="M1009,936.6l-276.1,-276.1a409.5,409.5 0,1 0,-72.3 72.3l276.1,276.1a51.2,51.2 0,0 0,72.3 -72.3zM409.8,716.9a307.1,307.1 0,1 1,307.1 -307.1,307.1 307.1,0 0,1 -307.1,307.1z"
android:fillColor="@color/black"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M222.1,580.4a356.2,356.2 0,0 0,34.1 152.9,357.6 357.6,0 0,0 477.7,-477.7A357.6,357.6 0,0 0,222.1 580.4z"
android:fillColor="@color/color_0"/>
<path
android:pathData="M1009,936.6l-276.1,-276.1a409.5,409.5 0,1 0,-72.3 72.3l276.1,276.1a51.2,51.2 0,0 0,72.3 -72.3zM409.8,716.9a307.1,307.1 0,1 1,307.1 -307.1,307.1 307.1,0 0,1 -307.1,307.1z"
android:fillColor="@color/black"/>
</vector>

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/white"
android:pathData="M261.9,492.9c20.6,11.9 46,11.9 66.6,0 20.6,-11.9 33.3,-33.9 33.3,-57.6 0,-36.8 -29.8,-66.5 -66.6,-66.5s-66.5,29.8 -66.5,66.5c0,23.8 12.7,45.7 33.2,57.6z"/>
<path
android:fillColor="@color/white"
android:pathData="M804,153.4L221.4,153.4c-78.3,0 -142,63.7 -142,142v436.9c0,78.3 63.7,142 142,142L804,874.3c78.3,0 142,-63.7 142,-142L946,295.4c-0.1,-78.3 -63.7,-142 -142,-142zM144.9,295.4c0,-42.2 34.3,-76.5 76.4,-76.5L804,218.9c42.1,0 76.4,34.3 76.4,76.5v331.1l-95.3,-86.2 -13.6,-9.7c-71.9,-46.1 -164.2,-45.1 -233.9,1.3l-385,232.6c-4.7,-9.9 -7.7,-20.6 -7.7,-32.2L144.9,295.4zM804,808.8L221.4,808.8c-4.1,0 -7.6,-1.7 -11.4,-2.3l362.8,-219.2c49.5,-32.9 113.6,-33.4 162.8,-1.9l143.7,128.5 1.2,-1.3v19.8c-0.1,42.1 -34.4,76.4 -76.5,76.4z"/>
</vector>

View File

@ -0,0 +1,17 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="256dp"
android:height="256dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M219.8,71c-12.3,0 -21.8,-9.6 -21.8,-21.8S208.9,27.3 219.8,27.3c12.3,0 21.8,9.6 21.8,21.8 0,12.3 -9.6,21.8 -21.8,21.8zM219.8,34.1c-8.2,0 -15,6.8 -15,15s6.8,15 15,15c8.2,0 15,-6.8 15,-15 0,-8.2 -6.8,-15 -15,-15z"
android:strokeAlpha="0.3"
android:fillColor="@color/sub_title_color"
android:fillAlpha="0.3"/>
<path
android:pathData="M935.3,1009L112,1009c-4.1,0 -6.8,2.7 -6.8,6.8s2.7,6.8 6.8,6.8h823.3c4.1,0 6.8,-2.7 6.8,-6.8s-2.7,-6.8 -6.8,-6.8zM84.7,1009h-54.6c-4.1,0 -6.8,2.7 -6.8,6.8s2.7,6.8 6.8,6.8h54.6c4.1,0 6.8,-2.7 6.8,-6.8s-4.1,-6.8 -6.8,-6.8zM994,1009h-27.3c-4.1,0 -6.8,2.7 -6.8,6.8s2.7,6.8 6.8,6.8h27.3c4.1,0 6.8,-2.7 6.8,-6.8s-2.7,-6.8 -6.8,-6.8zM244.4,428.7c4.1,0 6.8,-2.7 6.8,-6.8L251.2,210.3h400v109.2L764.6,319.5l4.1,4.1v379.6c0,4.1 2.7,6.8 6.8,6.8s6.8,-2.7 6.8,-6.8L782.3,318.1l-8.2,-8.2c0,-1.4 -2.7,-4.1 -4.1,-4.1l-107.9,-107.9 -1.4,-1.4h-423.3v225.3c0,4.1 2.7,6.8 6.8,6.8zM663.6,305.8v-86l86,86h-86zM244.4,518.8c4.1,0 6.8,-2.7 6.8,-6.8v-64.2c0,-4.1 -2.7,-6.8 -6.8,-6.8s-6.8,2.7 -6.8,6.8v64.2c0,4.1 2.7,6.8 6.8,6.8zM244.4,558.4c4.1,0 6.8,-2.7 6.8,-6.8L251.2,532.5c0,-4.1 -2.7,-6.8 -6.8,-6.8s-6.8,2.7 -6.8,6.8v19.1c0,4.1 2.7,6.8 6.8,6.8zM782.3,740c0,-4.1 -2.7,-6.8 -6.8,-6.8s-6.8,2.7 -6.8,6.8v84.7L251.2,824.7L251.2,570.7c0,-4.1 -2.7,-6.8 -6.8,-6.8s-6.8,2.7 -6.8,6.8v267.6h544.8v-98.3z"
android:fillColor="@color/sub_title_color"/>
<path
android:pathData="M460.1,434.2c-4.1,-1.4 -6.8,1.4 -8.2,5.5 -2.7,15 -12.3,27.3 -24.6,32.8 -24.6,9.6 -58.7,-8.2 -58.7,-9.6 -2.7,-1.4 -6.8,-1.4 -9.6,2.7 -1.4,2.7 -1.4,6.8 2.7,9.6 15,8.2 31.4,13.7 49.2,13.7 6.8,0 15,-1.4 21.8,-4.1 17.7,-8.2 30,-23.2 32.8,-42.3 0,-4.1 -1.4,-8.2 -5.5,-8.2zM584.4,490.2c5.5,2.7 10.9,2.7 17.7,2.7 16.4,-1.4 31.4,-6.8 45.1,-16.4 2.7,-2.7 4.1,-6.8 1.4,-9.6 -2.7,-2.7 -5.5,-4.1 -9.6,-1.4 -19.1,12.3 -35.5,16.4 -49.2,10.9 -21.8,-8.2 -31.4,-39.6 -31.4,-39.6 -1.4,-4.1 -5.5,-5.5 -8.2,-4.1 -4.1,1.4 -5.5,4.1 -4.1,8.2 0,2.7 9.6,38.2 38.2,49.2zM462.8,617.1c1.4,-1.4 36.9,-34.1 81.9,4.1 1.4,1.4 2.7,1.4 4.1,1.4 4.1,0 6.8,-2.7 6.8,-6.8 0,-2.7 -1.4,-4.1 -2.7,-5.5 -56,-45.1 -99.7,-2.7 -101,-2.7 -2.7,2.7 -2.7,6.8 0,9.6s8.2,2.7 10.9,0zM909.3,148.8c12.3,0 21.8,-9.6 21.8,-21.8s-9.6,-21.8 -21.8,-21.8c-12.3,0 -21.8,9.6 -21.8,21.8 1.4,12.3 10.9,21.8 21.8,21.8zM909.3,113.3c8.2,0 15,6.8 15,15s-6.8,15 -15,15c-8.2,0 -15,-6.8 -15,-15 1.4,-8.2 8.2,-15 15,-15zM73.7,296.3l13.7,8.2 -6.8,13.7c-1.4,2.7 0,5.5 2.7,6.8 2.7,1.4 5.5,0 6.8,-2.7l5.5,-12.3 12.3,8.2c1.4,0 1.4,1.4 2.7,1.4 2.7,0 5.5,-2.7 5.5,-5.5 0,-1.4 -1.4,-4.1 -2.7,-4.1l-13.7,-8.2 6.8,-13.7c1.4,-2.7 0,-5.5 -2.7,-6.8 -2.7,-1.4 -5.5,0 -6.8,2.7l-6.8,12.3 -10.9,-9.6c-2.7,-1.4 -5.5,-1.4 -6.8,1.4 -2.7,2.7 -1.4,6.8 1.4,8.2zM957.1,475.1l-19.1,-10.9 8.2,-20.5c1.4,-4.1 0,-6.8 -4.1,-9.6s-6.8,0 -9.6,4.1l-8.2,19.1 -17.7,-9.6c-2.7,-1.4 -6.8,0 -9.6,2.7 -1.4,2.7 0,6.8 2.7,9.6l19.1,10.9 -8.2,20.5c-1.4,4.1 0,6.8 4.1,9.6s6.8,0 9.6,-4.1l8.2,-19.1 17.7,9.6c2.7,1.4 6.8,0 9.6,-2.7s0,-8.2 -2.7,-9.6z"
android:fillColor="@color/sub_title_color"/>
</vector>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="10dp" />
<solid android:color="@color/sub_color" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="10dp" />
<gradient
android:angle="0"
android:endColor="@color/color_fad91d"
android:centerColor="@color/color_fad91d"
android:startColor="@color/color_fad91d" />
</shape>
</clip>
</item>
</layer-list>

View File

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

View File

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

View File

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

View File

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

View File

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

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="oval">
<solid android:color="@color/color_main_view"/>
</shape>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="19dp"/>
<gradient
android:angle="45"
android:endColor="@color/color_4202cb"
android:startColor="@color/color_4202cb" />
</shape>

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp"
tools:context="com.wall.photography.picture.Activity.List">
<ImageView
android:id="@+id/imageview_back"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:background="@drawable/shape_oval_solid"
android:padding="13dp"
android:src="@drawable/image_black_back"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wall.photography.picture.tool.CustomTextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/imageview_back"
android:layout_alignBottom="@id/imageview_back"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="17sp"
app:apply_font="true" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_below="@id/imageview_back" />
</RelativeLayout>

View File

@ -0,0 +1,50 @@
<?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"
android:background="@drawable/bg_gradient_green_light"
tools:context="com.wall.photography.picture.Activity.Main">
<com.wall.photography.picture.tool.CustomTextView
android:id="@+id/textview_wallpaper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:padding="10dp"
android:layout_marginTop="5dp"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="17sp"
android:visibility="gone"
app:apply_font="true" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager2"
android:layout_marginTop="0dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:elevation="0dp"
android:clipToPadding="false"
android:clipChildren="false" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab"
android:layout_width="240dp"
android:layout_height="55dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="22dp"
android:background="@drawable/shape_rect_gradient_radius_19"
app:tabBackground="@color/color_0"
app:tabIndicator="@null"
app:tabIndicatorHeight="0dp" />
</RelativeLayout>

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:paddingTop="30dp">
<ImageView
android:id="@+id/imageview_back"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:background="@drawable/shape_oval_solid"
android:padding="13dp"
android:layout_marginStart="7dp"
android:layout_alignTop="@id/title"
android:src="@drawable/image_black_back"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wall.photography.picture.tool.CustomTextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:padding="10dp"
android:layout_marginTop="12dp"
android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="17sp"
app:apply_font="true" />
<RelativeLayout
android:id="@+id/et_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_toStartOf="@id/btn_search"
android:background="@drawable/shape_rect_stroke_radius_16">
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="41dp"
android:background="@color/color_0"
android:hint="@string/please_input_keyword"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1"
android:paddingStart="11dp"
android:paddingEnd="10dp"
android:textColorHint="@color/sub_title_color"
android:textSize="16sp" />
</RelativeLayout>
<ImageView
android:id="@+id/btn_search"
android:layout_width="55dp"
android:layout_height="wrap_content"
android:layout_alignTop="@id/et_parent"
android:layout_alignBottom="@id/et_parent"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:paddingStart="15dp"
android:paddingTop="6dp"
android:paddingEnd="15dp"
android:paddingBottom="6dp"
android:src="@drawable/image_search_white" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/result_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/et_parent"
android:layout_marginTop="10dp" />
<LinearLayout
android:id="@+id/empty_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/img_empty_result" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/no_search_result"
android:textColor="@color/sub_title_color" />
</LinearLayout>
<ProgressBar
android:id="@+id/search_pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/color_FEA7F5"
android:visibility="gone" />
</RelativeLayout>

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"
tools:context="com.wall.photography.picture.Activity.Splash">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/splash"
/>
<ImageView
android:id="@+id/imageview_app_icon"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="150dp"
android:layout_marginBottom="20dp"
android:src="@mipmap/icon"
android:scaleType="fitCenter"
android:contentDescription="@string/app_name" />
<com.wall.photography.picture.tool.CustomTextView
android:id="@+id/textview_appname"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/imageview_app_icon"
android:layout_marginTop="25dp"
android:layout_marginBottom="100dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="30sp"
app:apply_font="true" />
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="240dp"
android:layout_height="6dp"
android:layout_below="@id/textview_appname"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp"
android:max="100"
android:progress="1"
android:progressDrawable="@drawable/progress_bar_splash" />
</RelativeLayout>

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.wall.photography.picture.Activity.Wallpaper">
<ImageView
android:id="@+id/imageview_preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<ImageView
android:id="@+id/imageview_back"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:layout_marginStart="15dp"
android:layout_marginTop="42dp"
android:background="@drawable/shape_oval_solid"
android:padding="13dp"
android:src="@drawable/image_black_back"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wall.photography.picture.tool.CustomTextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/shape_rect_solid_radius_16"
android:gravity="center"
android:minHeight="40dp"
android:padding="10dp"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="13sp"
app:apply_font="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<RelativeLayout
android:id="@+id/layout_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:background="@drawable/shape_oval_solid"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@id/tv_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<ImageView
android:id="@+id/button_set"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_centerInParent="true"
android:padding="13dp"
android:src="@drawable/image_wallpaper" />
<ProgressBar
android:id="@+id/pb_set"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_centerInParent="true"
android:indeterminateTint="@color/white"
android:padding="13dp"
android:visibility="gone" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/layout_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="26dp"
android:background="@drawable/shape_oval_solid"
app:layout_constraintBottom_toBottomOf="@id/layout_set"
app:layout_constraintRight_toLeftOf="@id/layout_set"
app:layout_constraintTop_toTopOf="@id/layout_set">
<ImageView
android:id="@+id/image_download"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_centerInParent="true"
android:padding="13dp"
android:src="@drawable/ic_download_arrow_white" />
<ProgressBar
android:id="@+id/pb_download"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_centerInParent="true"
android:indeterminateTint="@color/white"
android:padding="13dp"
android:visibility="gone" />
</RelativeLayout>
<ImageView
android:id="@+id/image_favorite"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_marginStart="26dp"
android:background="@drawable/shape_oval_solid"
android:padding="13dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:src="@drawable/selector_favorite"
app:layout_constraintBottom_toBottomOf="@id/layout_set"
app:layout_constraintLeft_toRightOf="@id/layout_set"
app:layout_constraintTop_toTopOf="@id/layout_set" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="24dp"
android:background="@drawable/bg_card_white_rounded">
<TextView
android:id="@+id/tv_dialog_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Rate Our App"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#333333"
android:layout_marginBottom="8dp" />
<TextView
android:id="@+id/tv_dialog_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_dialog_title"
android:layout_centerHorizontal="true"
android:text="How would you rate your experience?"
android:textSize="14sp"
android:textColor="#666666"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp" />
<!-- 评星布局 -->
<LinearLayout
android:id="@+id/layout_stars"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_dialog_message"
android:layout_centerHorizontal="true"
android:orientation="horizontal"
android:layout_marginTop="16dp"
android:layout_marginBottom="24dp">
<ImageView
android:id="@+id/star_1"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/star"
android:padding="4dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackgroundBorderless" />
<ImageView
android:id="@+id/star_2"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/star"
android:padding="4dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackgroundBorderless" />
<ImageView
android:id="@+id/star_3"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/star"
android:padding="4dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackgroundBorderless" />
<ImageView
android:id="@+id/star_4"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/star"
android:padding="4dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackgroundBorderless" />
<ImageView
android:id="@+id/star_5"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/star"
android:padding="4dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackgroundBorderless" />
</LinearLayout>
<!-- 按钮 -->
<LinearLayout
android:id="@+id/layout_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/layout_stars"
android:orientation="horizontal"
android:layout_marginTop="24dp">
<Button
android:id="@+id/btn_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel"
android:textColor="#666666"
android:background="?android:attr/selectableItemBackground"
android:layout_marginEnd="8dp"
style="?android:attr/borderlessButtonStyle" />
<Button
android:id="@+id/btn_submit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Submit"
android:textColor="@color/white"
android:background="@drawable/selector_button_submit"
android:layout_marginStart="8dp"
android:enabled="false" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_gradient_green_light">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/layout_no_data"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/image_no_ata" />
<TextView
android:id="@+id/tv_title"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:gravity="center"
android:lineSpacingExtra="4dp"
android:text="@string/no_like_data"
android:textColor="@color/sub_title_color"
android:textSize="14sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,186 @@
<?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"
tools:context="com.wall.photography.picture.fragment.MainFragment">
<RelativeLayout
android:id="@+id/tags_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:minHeight="60dp"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:paddingEnd="16dp"
android:paddingBottom="14dp">
<!-- 搜索图标 - 放在最右边 -->
<ImageView
android:id="@+id/btn_search"
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:clickable="true"
android:focusable="true"
android:padding="3dp"
android:src="@drawable/image_search_black" />
<!-- 标签容器 - 使用HorizontalScrollView支持横向滚动 -->
<HorizontalScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="12dp"
android:layout_toStartOf="@id/btn_search"
android:fadeScrollbars="true"
android:fillViewport="false"
android:scrollbars="none">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
android:orientation="horizontal"
android:paddingTop="6dp"
android:paddingBottom="6dp">
<!-- Feature 标签 -->
<RelativeLayout
android:id="@+id/layout_tag_4d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:paddingStart="0dp"
android:paddingEnd="16dp">
<TextView
android:id="@+id/btn_tag_4d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:ellipsize="none"
android:gravity="start|center_vertical"
android:paddingStart="0dp"
android:paddingTop="8dp"
android:paddingEnd="0dp"
android:paddingBottom="8dp"
android:singleLine="true"
android:text="Feature"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:id="@+id/underline_4d"
android:layout_width="wrap_content"
android:layout_height="3dp"
android:layout_below="@id/btn_tag_4d"
android:layout_alignStart="@id/btn_tag_4d"
android:layout_marginTop="3dp"
android:background="#90EE90"
android:visibility="visible" />
</RelativeLayout>
<!-- Animal 标签 -->
<RelativeLayout
android:id="@+id/layout_tag_live"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:paddingStart="0dp"
android:paddingEnd="16dp">
<TextView
android:id="@+id/btn_tag_live"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:ellipsize="none"
android:gravity="start|center_vertical"
android:paddingStart="0dp"
android:paddingTop="8dp"
android:paddingEnd="0dp"
android:paddingBottom="8dp"
android:singleLine="true"
android:text="Animal"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:id="@+id/underline_live"
android:layout_width="wrap_content"
android:layout_height="3dp"
android:layout_below="@id/btn_tag_live"
android:layout_alignStart="@id/btn_tag_live"
android:layout_marginTop="3dp"
android:background="#90EE90"
android:visibility="visible" />
</RelativeLayout>
<!-- Film 标签 -->
<RelativeLayout
android:id="@+id/layout_tag_4k"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:paddingStart="0dp"
android:paddingEnd="0dp">
<TextView
android:id="@+id/btn_tag_4k"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:ellipsize="none"
android:gravity="start|center_vertical"
android:paddingStart="0dp"
android:paddingTop="8dp"
android:paddingEnd="0dp"
android:paddingBottom="8dp"
android:singleLine="true"
android:text="Film"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
<View
android:id="@+id/underline_4k"
android:layout_width="wrap_content"
android:layout_height="3dp"
android:layout_below="@id/btn_tag_4k"
android:layout_alignStart="@id/btn_tag_4k"
android:layout_marginTop="3dp"
android:background="#90EE90"
android:visibility="visible" />
</RelativeLayout>
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tags_header" />
<ProgressBar
android:id="@+id/loading_pb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/white" />
</RelativeLayout>

View File

@ -0,0 +1,14 @@
<?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.MainChildFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_gradient_green_light">
<TextView
android:id="@+id/tv_settings_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="40dp"
android:text="@string/settings"
android:textSize="24sp"
android:textColor="#333333"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/settings_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_settings_title"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginTop="30dp"
android:background="@drawable/bg_card_white_rounded"
android:orientation="vertical"
android:elevation="4dp">
<!-- Rate us 选项 -->
<RelativeLayout
android:id="@+id/layout_rate_us"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/iv_rate_us"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@mipmap/star"
android:clickable="false"
android:focusable="false" />
<TextView
android:id="@+id/tv_rate_us"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/iv_rate_us"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:text="Rate us"
android:textSize="16sp"
android:textColor="#333333"
android:clickable="false"
android:focusable="false" />
<ImageView
android:id="@+id/iv_chevron_rate_us"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_arrow_right_gray"
android:clickable="false"
android:focusable="false" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:background="#E0E0E0" />
<!-- Version 选项 -->
<RelativeLayout
android:id="@+id/layout_privacy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/iv_privacy"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:src="@mipmap/privacy"
android:clickable="false"
android:focusable="false" />
<TextView
android:id="@+id/tv_privacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/iv_privacy"
android:layout_centerVertical="true"
android:layout_marginStart="16dp"
android:text="Version"
android:textSize="16sp"
android:textColor="#333333"
android:clickable="false"
android:focusable="false" />
<TextView
android:id="@+id/tv_version_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="8dp"
android:text="1.1"
android:textSize="14sp"
android:textColor="#999999"
android:clickable="false"
android:focusable="false" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,97 @@
<?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/shape_rect_gradient_radius_19"
android:orientation="vertical">
<LinearLayout
android:id="@+id/layout_home"
android:layout_width="match_parent"
android:layout_height="54dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_wallpaper_home_screen" />
<TextView
android:id="@+id/home"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:text="@string/type_home"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="@color/white" />
<LinearLayout
android:id="@+id/layout_lock"
android:layout_width="match_parent"
android:layout_height="54dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/image_lock" />
<TextView
android:id="@+id/lock"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:text="@string/type_lock"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:background="@color/white" />
<LinearLayout
android:id="@+id/layout_both"
android:layout_width="match_parent"
android:layout_height="54dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/ic_wallpaper_both_screens" />
<TextView
android:id="@+id/both"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:text="@string/type_both"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/wallpaper"
android:layout_width="match_parent"
android:layout_height="180dp" />
<ImageView
android:id="@+id/image_favorite"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@id/wallpaper"
android:padding="13dp"
android:src="@drawable/selector_favorite" />
<View
android:id="@+id/space_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_below="@id/wallpaper" />
</RelativeLayout>

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/wallpaper"
android:layout_width="match_parent"
android:layout_height="100dp" />
<TextView
android:id="@+id/tag_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/wallpaper"
android:layout_alignBottom="@id/wallpaper"
android:layout_alignStart="@id/wallpaper"
android:layout_alignEnd="@id/wallpaper"
android:layout_centerInParent="true"
android:text=""
android:textSize="16sp"
android:textStyle="bold"
android:textColor="@color/white"
android:visibility="gone"
android:gravity="center"
android:clickable="true"
android:focusable="true" />
<View
android:id="@+id/space_view"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_below="@id/wallpaper" />
</RelativeLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:layout_marginBottom="10dp"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/preview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<com.wall.photography.picture.tool.CustomTextView
android:id="@+id/tv_class_name"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/color_main_view"
android:gravity="center"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="16sp"
app:apply_font="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<View
android:id="@+id/space_view"
android:layout_width="match_parent"
android:layout_height="80dp" />
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="@+id/image_icon"
android:layout_width="25dp"
android:layout_height="25dp" />
<ImageView
android:id="@+id/image_indicator"
android:layout_width="5dp"
android:layout_height="5dp"
android:layout_marginTop="5dp"
android:src="@drawable/ic_tab_indicator" />
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomeTv">
<attr name="apply_font" format="boolean"/>
</declare-styleable>
</resources>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="favorite_true">#C03B3B</color>
<color name="sub_title_color">#C9C7C7</color>
<color name="sub_color">#979696</color>
<color name="color_FEA7F5">#FEA7F5</color>
<color name="color_0">#00000000</color>
<!-- <color name="color_283c56">#415F85</color>-->
<color name="color_main_view">#33FFFFFF</color>
<!-- <color name="color_e969f9">#F1B0AB</color>-->
<!-- <color name="color_1177f7">#DEEFCA</color>-->
<color name="color_4202cb">#F3C5B7</color>
<color name="color_fad91d">#BAF475</color>
</resources>

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