源代码

This commit is contained in:
yuqian 2025-12-02 16:53:26 +08:00
commit 3c46502592
135 changed files with 169270 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

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
.idea/AndroidProjectSystem.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

6
.idea/compiler.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

18
.idea/deploymentTargetSelector.xml generated Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-11-26T02:57:54.291938700Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\24526\.android\avd\Medium_Phone.avd" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState>
</selectionStates>
</component>
</project>

13
.idea/deviceManager.xml generated Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DeviceTable">
<option name="columnSorters">
<list>
<ColumnSorterState>
<option name="column" value="Name" />
<option name="order" value="ASCENDING" />
</ColumnSorterState>
</list>
</option>
</component>
</project>

21
.idea/gradle.xml generated Normal file
View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="$PROJECT_DIR$/../../gradle/gradle-8.11.1-bin/gradle-8.11.1" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

10
.idea/migrations.xml generated Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

9
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,9 @@
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

17
.idea/runConfigurations.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

4
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

1
app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

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

@ -0,0 +1,69 @@
import java.text.SimpleDateFormat
import java.util.Date
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
id("kotlin-kapt")
id("kotlin-parcelize")
}
android {
namespace = "com.adpro.pixelshow"
compileSdk = 36
val timeStamp: String = SimpleDateFormat("MM_dd_HH_mm").format(Date())
defaultConfig {
applicationId = "com.adpro.pixelshow"
minSdk = 26
targetSdk = 36
versionCode = 2
versionName = "2.0"
setProperty(
"archivesBaseName",
"PixelShow_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_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures{
viewBinding = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation("androidx.room:room-runtime:2.7.2")
kapt("androidx.room:room-compiler:2.7.2")
implementation("androidx.room:room-ktx:2.7.2")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
implementation("androidx.activity:activity-ktx:1.10.1")
implementation("com.github.bumptech.glide:glide:4.16.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
}

29
app/google-services.json Normal file
View File

@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "751074193027",
"project_id": "sketch-master-9f917",
"storage_bucket": "sketch-master-9f917.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:751074193027:android:4183c3717dff0d59d735b6",
"android_client_info": {
"package_name": "com.apps.sketchmaster"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyCdsZ677J8g3SEy376qKPoR-xMOljicZJQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

Binary file not shown.

Binary file not shown.

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

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

Binary file not shown.

View File

@ -0,0 +1,37 @@
{
"version": 3,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "com.adpro.pixelshow",
"variantName": "release",
"elements": [
{
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "PixelShow_V1.0_1_11_17_11_20-release.apk"
}
],
"elementType": "File",
"baselineProfiles": [
{
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/PixelShow_V1.0_1_11_17_11_20-release.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/PixelShow_V1.0_1_11_17_11_20-release.dm"
]
}
],
"minSdkVersionForDexing": 26
}

View File

@ -0,0 +1,24 @@
package com.adpro.pixelshow
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.adpro.pixelshow", appContext.packageName)
}
}

View File

@ -0,0 +1,46 @@
<?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" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name="com.adpro.pixelshow.IAppLifecycle"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.PixelShow"
tools:targetApi="31">
<activity
android:name=".look.TypeInfoActivity"
android:exported="false" />
<activity
android:name=".look.InitActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".look.SearchKeyActivity"
android:exported="false" />
<activity
android:name=".look.FirstSelActivity"
android:exported="false" />
<activity
android:name=".look.DownloadRequestActivity"
android:theme="@style/Base.Theme.PixelShow"
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

20703
app/src/main/assets/Film.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

View File

@ -0,0 +1,76 @@
package com.adpro.pixelshow
import android.app.Application
import android.util.Log
import com.adpro.pixelshow.data.AppDataBase
import com.adpro.pixelshow.data.MovieDao
import com.adpro.pixelshow.util.TypeUtil
import java.io.IOException
class IAppLifecycle : Application() {
private val animaLs = "Animals.json"
private val experiment = "Experimental.json"
private val film = "Film.json"
private val nature = "Nature.json"
private val patterns = "Patterns.json"
private val street = "Street.json"
private val travel = "Travel.json"
private val wallpaper = "Featured.json"
companion object {
var classificationList: MutableList<String> = mutableListOf()
var isDataInitialized = false
private set
}
override fun onCreate() {
super.onCreate()
val database = AppDataBase.getDatabase(this)
val paperDao = database.movieDao()
Thread {
initializeData(paperDao)
isDataInitialized = true
}.start()
}
private fun initializeData(paperDao: MovieDao) {
val names = arrayOf(animaLs, travel, experiment, film, nature, patterns, street, wallpaper)
val startTime = System.currentTimeMillis()
for (name in names) {
try {
// 在后台线程读取文件
val inputStream = assets.open(name)
val jsonData = TypeUtil.getConvert(inputStream)
Log.d("DataInit", "Loaded JSON for $name")
if (jsonData.isNotEmpty()) {
val classificationName = name.substring(0, name.indexOf("."))
// 同步添加分类名称(线程安全)
synchronized(classificationList) {
classificationList.add(classificationName)
}
// 解析数据
val movies = TypeUtil.getData(jsonData, classificationName)
// 批量插入数据
if (movies.isNotEmpty()) {
// 使用批量插入方法
paperDao.insertAll(movies)
Log.d("DataInit", "[$classificationName] insert ${movies.size} data")
}
}
} catch (e: IOException) {
Log.e("DataInit", " $name error", e)
}
}
val duration = System.currentTimeMillis() - startTime
Log.d("DataInit", "use time: ${duration}ms")
}
}

View File

@ -0,0 +1,23 @@
package com.adpro.pixelshow.data
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [Movie::class], version = 1, exportSchema = false)
abstract class AppDataBase:RoomDatabase() {
abstract fun movieDao():MovieDao
companion object{
@Volatile
private var INSTANCE:AppDataBase?=null
fun getDatabase(context:Context):AppDataBase{
return INSTANCE?: synchronized(this){
INSTANCE?:createDatabase(context).also { INSTANCE=it }
}
}
private fun createDatabase(context: Context):AppDataBase{
return Room.databaseBuilder(context.applicationContext,AppDataBase::class.java,"wallpaper_database").fallbackToDestructiveMigration().build()
}
}
}

View File

@ -0,0 +1,146 @@
package com.adpro.pixelshow.data
import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.adpro.pixelshow.IAppLifecycle
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.launch
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val repository: MovieRepository by lazy {
val dao = AppDataBase.getDatabase(application).movieDao()
MovieRepository(dao)
}
// 防抖控制
private var lastSearchTime = 0L
private var lastQuery: String? = null
private val searchDebounceTime = 500L
// LiveData 统一暴露
private val _paperResult = MutableLiveData<Movie?>() // id查询结果
val paperResult: LiveData<Movie?> get() = _paperResult
private val _classificationList = MutableLiveData<List<Movie>>(emptyList()) // 类别列表
val classificationList: LiveData<List<Movie>> get() = _classificationList
private val _coverMap = MutableLiveData<Map<String, List<Movie>>>(emptyMap()) // 封面分类映射
val coverMap: LiveData<Map<String, List<Movie>>> get() = _coverMap
private val _loadingState = MutableLiveData(false) // 加载状态
val loadingState: LiveData<Boolean> get() = _loadingState
private val _searchList = MutableLiveData<List<Movie>>(emptyList()) // 搜索结果
val searchList: LiveData<List<Movie>> get() = _searchList
private val _isLiked = MutableLiveData<Boolean?>() // 是否收藏
val isLiked: LiveData<Boolean?> get() = _isLiked
val likeMovies: LiveData<List<Movie>> get() = repository.getLikes()
// 添加标题存储
var currentTitleName: String? = null
fun debugDatabase() {
viewModelScope.launch(Dispatchers.IO) {
try {
val movies = repository.allMovie()
Log.d("DB_DEBUG", "总记录数: ${movies.size}")
movies.take(5).forEach { paper ->
Log.d("DB_DEBUG", "Movie[${paper.id}]: " +
"cat=${paper.classificationName}, " +
"imId=${paper.imId}, " +
"desc=${paper.description.take(10)}...")
}
} catch (e: Exception) {
Log.e("DB_DEBUG", "查询失败", e)
}
}
}
fun updateMovie(paper: Movie) {
viewModelScope.launch(Dispatchers.IO) {
repository.updateMovie(paper)
}
}
fun getMovieResult(id: String) {
viewModelScope.launch(Dispatchers.IO) {
_paperResult.postValue(repository.getMovieById(id))
}
}
fun getClassificationList(name: String) {
viewModelScope.launch(Dispatchers.IO) {
_classificationList.postValue(repository.getMovieByClassification(name))
}
}
fun loadAllClassificationCovers() {
if (_loadingState.value == true) return
viewModelScope.launch(Dispatchers.IO) {
_loadingState.postValue(true)
val classificationList = IAppLifecycle.classificationList
val resultMap = mutableMapOf<String, List<Movie>>()
val deferredList = classificationList.map { classification ->
async {
try {
classification to repository.getClassificationCover(classification)
} catch (e: Exception) {
Log.e("BatchLoad", "加载分类[$classification]失败: ${e.message}")
classification to emptyList<Movie>()
}
}
}
deferredList.awaitAll().forEach { (classification, movies) ->
resultMap[classification] = movies
}
_coverMap.postValue(resultMap)
_loadingState.postValue(false)
Log.d("BatchLoad", "所有分类封面数据加载完成")
}
}
fun getSearchList(query: String) {
val currentTime = System.currentTimeMillis()
if (query == lastQuery && (currentTime - lastSearchTime) < searchDebounceTime) {
return
}
lastQuery = query
lastSearchTime = currentTime
viewModelScope.launch(Dispatchers.IO) {
try {
_searchList.postValue(repository.searchByKey(query))
} catch (e: Exception) {
_searchList.postValue(emptyList())
Log.e("Search", "Search failed", e)
}
}
}
fun checkLike(id: String) {
viewModelScope.launch(Dispatchers.IO) {
_isLiked.postValue(repository.isLike(id))
}
}
fun setLike(paper: Movie) {
viewModelScope.launch(Dispatchers.IO) {
val updateMovie = paper.copy(isLike = !paper.isLike)
repository.updateMovie(updateMovie)
Log.d("setlike status",updateMovie.isLike.toString())
_isLiked.postValue(updateMovie.isLike)
}
}
}

View File

@ -0,0 +1,24 @@
package com.adpro.pixelshow.data
import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import kotlinx.parcelize.Parcelize
@Parcelize
@Entity(tableName = "movies",
indices = [Index(value = ["imId"], unique = true)])
data class Movie(
@PrimaryKey(autoGenerate = true) var id: Int = 0,
@ColumnInfo(name = "classificationName") var classificationName: String = "",
@ColumnInfo(name = "imId") var imId: String = "",
@ColumnInfo(name = "description") var description: String = "",
@ColumnInfo(name = "fullUrl") var fullUrl: String = "",
@ColumnInfo(name = "previewUrl1080") var previewUrl1080: String = "",
@ColumnInfo(name = "previewUrl400") var previewUrl400: String = "",
@ColumnInfo(name = "previewUrl200") var previewUrl200: String = "",
@ColumnInfo(name = "is_like") var isLike: Boolean = false,
@ColumnInfo(name = "isDownload") var isDownload: Boolean = false
):Parcelable

View File

@ -0,0 +1,39 @@
package com.adpro.pixelshow.data
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
@Dao
interface MovieDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertAll(movies: List<Movie>)
@Update
suspend fun update(movie: Movie)
@Query("SELECT * FROM movies WHERE imId=:imId")
suspend fun getById(imId: String): Movie?
@Query("SELECT * FROM movies WHERE classificationName=:name LIMIT 6 OFFSET 20")
suspend fun queryCover(name: String): List<Movie>
@Query("SELECT * FROM movies WHERE classificationName=:name")
suspend fun queryEachGenera(name: String): List<Movie>
@Query("SELECT * FROM movies WHERE is_like = 1")
fun queryLikeMovie(): LiveData<List<Movie>>
@Query("SELECT * FROM movies WHERE description LIKE '%'||:name||'%'")
suspend fun search(name: String): List<Movie>
@Query("SELECT * FROM movies WHERE imId = :imId AND is_like = 1")
suspend fun queryIsLike(imId: String): Movie?
@Query("SELECT * FROM movies")
suspend fun getAllMovies(): List<Movie>
}

View File

@ -0,0 +1,31 @@
package com.adpro.pixelshow.data
import androidx.lifecycle.LiveData
class MovieRepository(private val movieDao: MovieDao) {
suspend fun allMovie():List<Movie>{
return movieDao.getAllMovies()
}
// suspend fun insertMovie(paper: Movie){
// paperDao.insert(paper)
// }
suspend fun updateMovie(movie: Movie){
movieDao.update(movie)
}
suspend fun getMovieById(id:String):Movie?{
return movieDao.getById(id)
}
suspend fun getClassificationCover(name:String):List<Movie>{
return movieDao.queryCover(name)
}
suspend fun getMovieByClassification(name: String):List<Movie>{
return movieDao.queryEachGenera(name)
}
fun getLikes():LiveData<List<Movie>>{
return movieDao.queryLikeMovie()
}
suspend fun searchByKey(key:String):List<Movie>{
return movieDao.search(key)
}
suspend fun isLike(id: String): Boolean = movieDao.queryIsLike(id) != null
}

View File

@ -0,0 +1,56 @@
package com.adpro.pixelshow.event
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.adpro.pixelshow.R
import com.adpro.pixelshow.data.Movie
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.request.RequestOptions
import com.adpro.pixelshow.databinding.ItemChangeLoveBinding
class ChangeLoveAdapter: RecyclerView.Adapter<ChangeLoveAdapter.MovieViewHolder>() {
private lateinit var context: Context
private var movieList:List<Movie> = emptyList()
private lateinit var listener: SecFavListener
class MovieViewHolder(val binding: ItemChangeLoveBinding): RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
context=parent.context
val binding= ItemChangeLoveBinding.inflate(LayoutInflater.from(context),parent,false)
return MovieViewHolder(binding)
}
fun setList(list: List<Movie>){
this.movieList=list
}
override fun getItemCount(): Int {
return movieList.size
}
override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
val item= movieList[position]
val previewUrl200 = item.previewUrl200
val previewUrl400 = item.previewUrl400
// holder.binding.text.text=item.description
Glide.with(context).load(previewUrl400).placeholder(R.mipmap.bg_placeholder)
.error(R.mipmap.bg_placeholder).thumbnail(
Glide.with(context)
.asDrawable()
.load(previewUrl200)
.apply(
RequestOptions()
.format(DecodeFormat.PREFER_RGB_565)
)
.placeholder(R.mipmap.bg_placeholder)
.centerCrop()
).into(holder.binding.img)
holder.binding.img.setOnClickListener {
listener.inItemClick(item)
}
}
fun setListener(listener: SecFavListener){
this.listener=listener
}
}

View File

@ -0,0 +1,60 @@
package com.adpro.pixelshow.event
import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.adpro.pixelshow.R
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.ItemClassFillingBinding
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.request.RequestOptions
class ClassFillingAdapter : RecyclerView.Adapter<ClassFillingAdapter.MainInViewHolder>() {
private lateinit var context: Context
private var coverList: List<Movie> = mutableListOf()
private lateinit var listener: SecFavListener
class MainInViewHolder(val binding: ItemClassFillingBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainInViewHolder {
context = parent.context
val binding = ItemClassFillingBinding.inflate(LayoutInflater.from(parent.context), parent, false);
return MainInViewHolder(binding)
}
override fun getItemCount(): Int {
return coverList.size
}
override fun onBindViewHolder(holder: MainInViewHolder, position: Int) {
val previewUrl400 = coverList[position].previewUrl400
val previewUrl200 = coverList[position].previewUrl200
Log.d("MainInAdapter", "previewUrl400 is $previewUrl400 previewUrl200 is $previewUrl200")
Glide.with(context).load(previewUrl400).placeholder(R.mipmap.bg_placeholder)
.error(R.mipmap.bg_placeholder).thumbnail(
Glide.with(context)
.asDrawable()
.load(previewUrl200)
.apply(
RequestOptions()
.format(DecodeFormat.PREFER_RGB_565)
)
.placeholder(R.mipmap.bg_placeholder)
.centerCrop()
).into(holder.binding.inImage)
holder.binding.inImage.setOnClickListener {
listener.inItemClick(coverList[position])
}
}
fun setListener(listener: SecFavListener) {
this.listener = listener
}
fun setCoverList(list: List<Movie>) {
this.coverList = list
}
}

View File

@ -0,0 +1,62 @@
package com.adpro.pixelshow.event
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.ItemClassEveryBinding
import com.adpro.pixelshow.look.DownloadRequestActivity
class ClassFrameAdapter : RecyclerView.Adapter<ClassFrameAdapter.CategoryViewHolder>(),SecFavListener {
private var categoryNameList:List<String> = mutableListOf()
private var coverAllList:List<List<Movie>> = mutableListOf()
private lateinit var context: Context
private lateinit var adapterListener:FirClassListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder {
val binding= ItemClassEveryBinding.inflate(LayoutInflater.from(parent.context),parent,false)
context=parent.context
return CategoryViewHolder(binding)
}
override fun onBindViewHolder(holder: CategoryViewHolder, position: Int) {
holder.binding.txTitle.text = categoryNameList[position]
val adapter=ClassFillingAdapter()
adapter.setCoverList(coverAllList[position])
adapter.setListener(this)
holder.binding.rvView.adapter=adapter
val girdLayoutManager = GridLayoutManager(context,3)
holder.binding.rvView.layoutManager=girdLayoutManager
holder.binding.rvView.setOnClickListener{
adapterListener.more(categoryNameList[position])
}
holder.binding.llView.setOnClickListener {
adapterListener.more(categoryNameList[position])
}
}
override fun getItemCount(): Int {
return categoryNameList.size
}
fun setList(classificationList: MutableList<String>,list:List<List<Movie>>) {
this.categoryNameList=classificationList
this.coverAllList=list
}
fun setListener(listener: FirClassListener){
this.adapterListener=listener
}
class CategoryViewHolder(val binding: ItemClassEveryBinding) : RecyclerView.ViewHolder(binding.root)
override fun inItemClick(movie: Movie) {
val intent=Intent(context,DownloadRequestActivity::class.java)
intent
intent.putExtra(DownloadRequestActivity.paperKey,movie)
context.startActivity(intent)
}
}

View File

@ -0,0 +1,5 @@
package com.adpro.pixelshow.event
interface FirClassListener {
fun more(name:String)
}

View File

@ -0,0 +1,5 @@
package com.adpro.pixelshow.event
interface IntentListener {
fun onClick(type:Int)
}

View File

@ -0,0 +1,56 @@
package com.adpro.pixelshow.event
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.adpro.pixelshow.R
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.ItemMoreAndSearchBinding
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.request.RequestOptions
class MoreAndSearchAdapter: RecyclerView.Adapter<MoreAndSearchAdapter.DoubleViewHolder>() {
private lateinit var context:Context
private var list:List<Movie> = emptyList()
private lateinit var listener:SecFavListener
class DoubleViewHolder(val binding: ItemMoreAndSearchBinding): RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DoubleViewHolder {
context=parent.context
val binding=ItemMoreAndSearchBinding.inflate(LayoutInflater.from(context),parent,false)
return DoubleViewHolder(binding)
}
fun setList(list: List<Movie>){
this.list=list
}
override fun getItemCount(): Int {
return list.size
}
override fun onBindViewHolder(holder: DoubleViewHolder, position: Int) {
val item= list[position]
val previewUrl200 = item.previewUrl200
val previewUrl400 = item.previewUrl400
holder.binding.text.text=item.description
Glide.with(context).load(previewUrl400).placeholder(R.mipmap.bg_placeholder)
.error(R.mipmap.bg_placeholder).thumbnail(
Glide.with(context)
.asDrawable()
.load(previewUrl200)
.apply(
RequestOptions()
.format(DecodeFormat.PREFER_RGB_565)
)
.placeholder(R.mipmap.bg_placeholder)
.centerCrop()
).into(holder.binding.img)
holder.binding.img.setOnClickListener {
listener.inItemClick(item)
}
}
fun setListener(listener: SecFavListener){
this.listener=listener
}
}

View File

@ -0,0 +1,7 @@
package com.adpro.pixelshow.event
import com.adpro.pixelshow.data.Movie
interface SecFavListener {
fun inItemClick(movie:Movie)
}

View File

@ -0,0 +1,84 @@
package com.adpro.pixelshow.look
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.adpro.pixelshow.IAppLifecycle
import com.adpro.pixelshow.event.ClassFrameAdapter
import com.adpro.pixelshow.data.MainViewModel
import com.adpro.pixelshow.databinding.FragmentClassBinding
import com.adpro.pixelshow.event.FirClassListener
class ClassificationFragment : Fragment(),FirClassListener {
private lateinit var binding:FragmentClassBinding
private lateinit var viewModel:MainViewModel
private lateinit var adapter: ClassFrameAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding=FragmentClassBinding.inflate(inflater,container,false)
init()
return binding.root
}
private fun init(){
viewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]
adapter=ClassFrameAdapter()
adapter.setListener(this)
binding.rvView.adapter = adapter
binding.rvView.layoutManager = LinearLayoutManager(requireContext())
viewModel.coverMap.value?.takeIf { it.isNotEmpty() }?.let {
Log.d("DataLoad", "hasLoad")
updateAdapter()
}
viewModel.loadAllClassificationCovers()
viewModel.loadingState.observe(viewLifecycleOwner) { isLoading ->
viewModel.coverMap.value?.let { coverMap ->
if (!isLoading && coverMap.isNotEmpty()) {
updateAdapter()
}
}
}
viewModel.coverMap.observe(viewLifecycleOwner) { coverMap ->
viewModel.loadingState.value?.let { isLoading ->
if (!isLoading && coverMap.isNotEmpty()) {
updateAdapter()
}
}
}
}
private fun updateAdapter() {
val classificationList = IAppLifecycle.classificationList
val coverMap = viewModel.coverMap.value
// 确保数据一致性
val coversForCategories = classificationList.map { classificationName ->
coverMap?.get(classificationName) ?: emptyList()
}
adapter.setList(classificationList, coversForCategories)
adapter.notifyDataSetChanged()
Log.d("AdapterUpdate", "refresh data")
classificationList.forEachIndexed { index, classification ->
val count = coversForCategories[index].size
Log.d("DataDebug", "[$index] $classification: $count data")
}
}
override fun more(name: String) {
val intent=Intent(requireActivity(),TypeInfoActivity::class.java)
intent.putExtra(TypeInfoActivity.titleName,name)
startActivity(intent)
}
}

View File

@ -0,0 +1,312 @@
package com.adpro.pixelshow.look
import android.app.WallpaperManager
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.adpro.pixelshow.R
import com.adpro.pixelshow.data.MainViewModel
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.ActivityDownRequestBinding
import com.adpro.pixelshow.event.IntentListener
import com.adpro.pixelshow.util.ApplyUtils
import com.adpro.pixelshow.util.TypeUtil
import com.adpro.pixelshow.util.TopBarUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DecodeFormat
import com.bumptech.glide.request.RequestOptions
import okhttp3.Call
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
class DownloadRequestActivity : AppCompatActivity(), IntentListener {
companion object {
var paperKey = "paper"
}
private lateinit var binding: ActivityDownRequestBinding
lateinit var paper: Movie
private lateinit var viewModel: MainViewModel
private var fullUrl = ""
private var mSavePath = ""
private lateinit var wallpaperManager: WallpaperManager
private lateinit var downloadFile: File
private var call: Call?=null
private var isGranted = false
private lateinit var setDialog: ToApplyDialog
private var isSetting = false
private val storagePermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
if (permissions.all { it.value }) {
isGranted = true
} else {
Toast.makeText(this, getString(R.string.no_permit), Toast.LENGTH_SHORT).show()
}
}
private fun requestStoragePermission() {
val permissions = TypeUtil.getStoragePermissions()
if (TypeUtil.hasStoragePermission(this)) {
isGranted = true
} else {
storagePermissionLauncher.launch(permissions)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDownRequestBinding.inflate(layoutInflater)
setContentView(binding.root)
TopBarUtils.setStatusBar(this.window)
TopBarUtils.setLightStatusBar(this.window,true)
init()
}
override fun onDestroy() {
super.onDestroy()
call?.let {
it.cancel()
}
deleteCacheFile()
}
private fun isActivityValid(): Boolean {
return !isFinishing && !isDestroyed
}
private fun init() {
viewModel = ViewModelProvider(this)[MainViewModel::class.java]
paper = intent?.getParcelableExtra(paperKey)!!
fullUrl = paper.fullUrl
mSavePath = TypeUtil.getSaveFilePath(this, paper.imId)
downloadFile = File(mSavePath)
setDialog = ToApplyDialog()
setDialog.setListener(this@DownloadRequestActivity)
wallpaperManager = WallpaperManager.getInstance(this)
Glide.with(this)
.load(paper.previewUrl1080)
.apply(
RequestOptions()
.format(DecodeFormat.PREFER_RGB_565)
)
.skipMemoryCache(true)
.thumbnail(
Glide.with(this)
.load(paper.previewUrl400)
.apply(
RequestOptions()
.format(DecodeFormat.PREFER_RGB_565)
.centerCrop()
)
)
.into(binding.image)
binding.imageBack.setOnClickListener { finish() }
binding.tvContent.text = paper.description
viewModel.isLiked.observe(this) { b ->
Log.d("initb", b.toString())
if (b != null) {
binding.imageLike.isSelected = b
}
}
viewModel.checkLike(paper.imId)
binding.imageLike.setOnClickListener {
setLikeStatus()
}
binding.layoutDownload.setOnClickListener {
startDownload()
}
binding.layoutSet.setOnClickListener {
showSetDialog()
}
}
private fun showSetDialog() {
if (isSetting) return
if (!setDialog.isAdded) {
setDialog.show(supportFragmentManager, "")
}
}
private fun setLikeStatus() {
val b = !binding.imageLike.isSelected
binding.imageLike.isSelected = !b
paper.isLike = !b
viewModel.setLike(paper)
}
private fun startDownload() {
requestStoragePermission()
if (!isGranted) return
showDownloadLoading(true)
if (downloadFile.exists()) {
saveToGallery()
return
}
doDownload()
}
private fun saveToGallery() {
val uri: Uri? = ApplyUtils.saveToGallery(this, downloadFile)
if (!isActivityValid()) return
runOnUiThread {
showDownloadLoading(false)
if (uri == null) {
Toast.makeText(
this@DownloadRequestActivity,
getString(R.string.save_fail),
Toast.LENGTH_SHORT
).show()
} else {
Toast.makeText(
this@DownloadRequestActivity,
getString(R.string.save_success),
Toast.LENGTH_SHORT
).show()
}
Log.d("YYYYYY", "--------path=" + downloadFile.getAbsolutePath() + "---uri=" + uri)
}
}
private fun doDownload() {
call = ApplyUtils.downloadFile(fullUrl, mSavePath, object : ApplyUtils.ConnectCallBack {
override fun onResult(success: Boolean, inputStream: InputStream?) {
val file = File(mSavePath)
if (file.exists() && success) {
downloadFile = file
saveToGallery()
} else {
if (!isActivityValid()) return
runOnUiThread {
showDownloadLoading(false)
Toast.makeText(
this@DownloadRequestActivity,
getString(R.string.down_fail),
Toast.LENGTH_SHORT
).show()
}
}
}
})
}
private fun showDownloadLoading(show: Boolean) {
if (show) {
binding.pbDownload.visibility = View.VISIBLE
binding.imageDownload.visibility = View.GONE
} else {
binding.pbDownload.visibility = View.GONE
binding.imageDownload.visibility = View.VISIBLE
}
}
private fun deleteCacheFile() {
if (downloadFile.exists()) {
val delete = downloadFile.delete()
Log.d("YYYYYY", "--------delete=$delete")
}
}
override fun onClick(type: Int) {
showSetWallpaperLoading(true)
if (downloadFile.exists()) {
Thread {
Log.d("YYYYYY", "skip download and set")
setWallPaper(downloadFile, type)
}.start()
} else {
call =
ApplyUtils.downloadFile(fullUrl, mSavePath, object : ApplyUtils.ConnectCallBack {
override fun onResult(success: Boolean, inputStream: InputStream?) {
val file = File(mSavePath)
if (file.exists() && success) {
downloadFile = file
setWallPaper(downloadFile, type)
} else {
showDownloadLoading(false)
if (!isActivityValid()) return
runOnUiThread {
Toast.makeText(
this@DownloadRequestActivity,
getString(R.string.set_fail),
Toast.LENGTH_SHORT
).show()
}
}
}
})
}
}
private fun showSetWallpaperLoading(show: Boolean) {
Log.d("YYYYYY", "-----------showSetWallpaperLoading$show")
if (show) {
isSetting = true
binding.pbSet.visibility = View.VISIBLE
} else {
isSetting = false
binding.pbSet.visibility = View.GONE
}
}
private fun setWallPaper(file: File, type: Int) {
try {
FileInputStream(file).use { fileInputStream ->
when (type) {
ToApplyDialog.TYPE_HOME -> {
// FLAG_SYSTEM 表示设置为主屏幕壁纸
wallpaperManager.setStream(
fileInputStream,
null,
true,
WallpaperManager.FLAG_SYSTEM
)
}
ToApplyDialog.TYPE_LOCK -> {
// FLAG_LOCK 设置为锁屏壁纸
wallpaperManager.setStream(
fileInputStream,
null,
true,
WallpaperManager.FLAG_LOCK
)
}
ToApplyDialog.TYPE_BOTH -> {
// 同时设置主屏和锁屏壁纸
wallpaperManager.setStream(fileInputStream)
}
else -> {}
}
}
if (!isActivityValid()) return
runOnUiThread {
showSetWallpaperLoading(false)
Toast.makeText(
this@DownloadRequestActivity,
getString(R.string.set_success),
Toast.LENGTH_SHORT
).show()
}
} catch (e: Exception) {
if (!isActivityValid()) return
runOnUiThread {
showSetWallpaperLoading(false)
Toast.makeText(
this@DownloadRequestActivity,
getString(R.string.set_fail),
Toast.LENGTH_SHORT
).show()
}
}
}
}

View File

@ -0,0 +1,57 @@
package com.adpro.pixelshow.look
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import com.adpro.pixelshow.event.ChangeLoveAdapter
import com.adpro.pixelshow.data.MainViewModel
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.FragmentLikePageBinding
import com.adpro.pixelshow.event.SecFavListener
class LikeFragment : Fragment(),SecFavListener {
private lateinit var binding: FragmentLikePageBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter:ChangeLoveAdapter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding=FragmentLikePageBinding.inflate(inflater,container,false)
init()
return binding.root
}
private fun init(){
viewModel=ViewModelProvider(requireActivity())[MainViewModel::class.java]
adapter=ChangeLoveAdapter()
adapter.setListener(this)
viewModel.likeMovies.observe(viewLifecycleOwner) { movies ->
Log.d("LikeFragment","paper is$movies")
if (movies.isNullOrEmpty()) {
// 可以在这里显示空状态视图
binding.layoutNoData.visibility = View.VISIBLE
binding.rvView.visibility = View.GONE
} else {
binding.layoutNoData.visibility = View.GONE
binding.rvView.visibility = View.VISIBLE
adapter.setList(movies)
adapter.notifyDataSetChanged()
}
}
val gridLayoutManager = GridLayoutManager(requireActivity(), 3)
binding.rvView.layoutManager=gridLayoutManager
binding.rvView.adapter=adapter
}
override fun inItemClick(paper: Movie) {
val intent= Intent(context, DownloadRequestActivity::class.java)
intent.putExtra(DownloadRequestActivity.paperKey,paper)
startActivity(intent)
}
}

View File

@ -0,0 +1,119 @@
package com.adpro.pixelshow.look
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.adpro.pixelshow.R
import com.adpro.pixelshow.data.MainViewModel
import com.adpro.pixelshow.databinding.ActivityFistSelBinding
import com.adpro.pixelshow.util.TopBarUtils
class FirstSelActivity : AppCompatActivity() {
private lateinit var binding: ActivityFistSelBinding
private var isTransitionInProgress = false
private var lastClickTime = 0L
private val TAP_THROTTLE = 300L
private lateinit var classFragment: Fragment
private lateinit var favFragment: Fragment
private lateinit var mainViewModel : MainViewModel
private var activeFragment: Fragment? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFistSelBinding.inflate(layoutInflater)
setContentView(binding.root)
mainViewModel = ViewModelProvider(this)[MainViewModel::class.java]
initFragments()
TopBarUtils.setStatusBar(this.window)
TopBarUtils.setLightStatusBar(this.window,true)
mainViewModel .debugDatabase()
initializeFragments()
}
private fun updateTab(position: Int) {
binding.imgHome.isSelected = false
binding.imgLike.isSelected = false
val defaultColor = getColor(R.color.colorNotSelect)
val selectColor = getColor(R.color.green_text)
binding.tvStart.setTextColor(defaultColor)
binding.tvEnd.setTextColor(defaultColor)
when (position) {
0 -> {
binding.imgHome.isSelected = true
binding.tvStart.setTextColor(selectColor)
binding.rlSearch.visibility = View.VISIBLE
}
1 -> {
binding.imgLike.isSelected = true
binding.tvEnd.setTextColor(selectColor)
binding.rlSearch.visibility = View.GONE
}
}
}
private fun initFragments() {
classFragment = ClassificationFragment()
favFragment = LikeFragment()
}
private fun initializeFragments() {
switchFragment(0)
binding.llHome.setOnClickListener {
if (System.currentTimeMillis() - lastClickTime > TAP_THROTTLE) {
switchFragment(0)
lastClickTime = System.currentTimeMillis()
}
}
binding.llLike.setOnClickListener {
if (System.currentTimeMillis() - lastClickTime > TAP_THROTTLE) {
switchFragment(1)
lastClickTime = System.currentTimeMillis()
}
}
binding.rlSearch.setOnClickListener {
Log.d("ClickTest", "RelativeLayout被点击了");
startActivity(Intent(this, SearchKeyActivity::class.java))
}
}
private fun switchFragment(position: Int) {
if (isTransitionInProgress) return
var targetFragment = when (position) {
0 -> {
if (activeFragment is ClassificationFragment) return
classFragment
}
1 -> {
if (activeFragment is LikeFragment) return
favFragment
}
else -> null
}
if (targetFragment == null || binding.fragmentIn.id == View.NO_ID) return
updateTab(position)
isTransitionInProgress = true
supportFragmentManager.beginTransaction().apply {
setCustomAnimations(
android.R.anim.fade_in,
android.R.anim.fade_out
)
if (targetFragment.isAdded) {
show(targetFragment)
} else {
add(binding.fragmentIn.id, targetFragment)
}
activeFragment?.takeIf { it.isAdded }?.let { hide(it) }
activeFragment = targetFragment
commit()
supportFragmentManager.executePendingTransactions()
isTransitionInProgress = false
}
}
}

View File

@ -0,0 +1,50 @@
package com.adpro.pixelshow.look
import android.content.Intent
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import androidx.appcompat.app.AppCompatActivity
import com.adpro.pixelshow.databinding.ActivityInitBinding
import com.adpro.pixelshow.util.TopBarUtils
class InitActivity : AppCompatActivity() {
lateinit var binding: ActivityInitBinding
private var handler: Handler = Handler()
private var countDownTimer: CountDownTimer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityInitBinding.inflate(layoutInflater)
setContentView(binding.root)
TopBarUtils.setStatusBar(this.window)
TopBarUtils.setLightStatusBar(this.window,true)
handler.postDelayed({
val intent= Intent(
this@InitActivity,
FirstSelActivity::class.java
)
startActivity(intent)
finish()
}, 4000)
countDownTimer = object : CountDownTimer(4000, 100) {
override fun onTick(millisUntilFinished: Long) {
val progress = ((4000 - millisUntilFinished) / 4000f * 100).toInt()
binding.progressbar.progress = progress
}
override fun onFinish() {
binding.progressbar.progress = 100
}
}.start()
}
override fun onDestroy() {
super.onDestroy()
handler.removeCallbacksAndMessages(null)
if (countDownTimer != null) {
countDownTimer!!.cancel()
}
}
}

View File

@ -0,0 +1,127 @@
package com.adpro.pixelshow.look
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import com.adpro.pixelshow.R
import com.adpro.pixelshow.event.MoreAndSearchAdapter
import com.adpro.pixelshow.data.MainViewModel
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.ActivitySearchKeyBinding
import com.adpro.pixelshow.event.SecFavListener
import com.adpro.pixelshow.util.TopBarUtils
class SearchKeyActivity : AppCompatActivity(), SecFavListener {
lateinit var binding: ActivitySearchKeyBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter: MoreAndSearchAdapter
private var resultList: List<Movie> = emptyList()
private var searchKey = ""
private var isClick = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySearchKeyBinding.inflate(layoutInflater)
setContentView(binding.root)
TopBarUtils.setStatusBar(this.window)
TopBarUtils.setLightStatusBar(this.window,true)
init()
}
private fun init() {
viewModel = ViewModelProvider(this)[MainViewModel::class.java]
adapter = MoreAndSearchAdapter()
adapter.setListener(this)
binding.list.adapter = adapter
binding.list.layoutManager = GridLayoutManager(this, 2)
binding.tvStart.setOnClickListener { startSearch() }
binding.imageBack.setOnClickListener { finish() }
binding.editText.requestFocus()
binding.editText.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE) {
return@setOnEditorActionListener true
startSearch()
}
false
}
viewModel.searchList.observe(this) { list ->
resultList = list
binding.searchPb.visibility = View.GONE
Log.d("SearchResult", "result list size${list.size}")
if (resultList.isNotEmpty()) {
showEmpty(false)
adapter.setList(resultList)
adapter.notifyDataSetChanged()
} else if (isClick) {
showEmpty(true)
}
}
binding.editText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
searchKey = s.toString().trim()
if (searchKey.isNotEmpty()) {
binding.tvStart.visibility = View.VISIBLE
} else {
binding.tvStart.visibility = View.GONE
}
}
override fun afterTextChanged(s: Editable) {
}
})
}
private fun startSearch() {
closeKeyboard()
isClick = true
binding.searchPb.visibility = View.VISIBLE
if (searchKey.isNotEmpty()) {
Log.d("SearchStart", "searchKey is$searchKey")
viewModel.getSearchList(searchKey)
} else {
binding.searchPb.visibility = View.GONE
Toast.makeText(
this,
getString(R.string.please_enter),
Toast.LENGTH_SHORT
).show()
}
}
private fun showEmpty(showEmpty: Boolean) {
if (showEmpty) {
binding.emptyLayout.visibility = View.VISIBLE
binding.list.visibility = View.GONE
} else {
binding.emptyLayout.visibility = View.GONE
binding.list.visibility = View.VISIBLE
}
}
private fun closeKeyboard() {
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as? InputMethodManager
val currentFocus = currentFocus ?: binding.root
inputMethodManager?.hideSoftInputFromWindow(currentFocus.windowToken, 0)
}
override fun inItemClick(paper: Movie) {
val intent = Intent(this, DownloadRequestActivity::class.java)
intent.putExtra(DownloadRequestActivity.paperKey, paper)
startActivity(intent)
}
}

View File

@ -0,0 +1,83 @@
package com.adpro.pixelshow.look
import android.graphics.Color
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.Window
import com.adpro.pixelshow.R
import com.adpro.pixelshow.databinding.FragmentToApplyBinding
import com.adpro.pixelshow.event.IntentListener
import androidx.core.graphics.drawable.toDrawable
class ToApplyDialog : androidx.fragment.app.DialogFragment() {
private lateinit var vb: FragmentToApplyBinding
private var listener: IntentListener? = null
companion object {
const val TYPE_HOME = 0
const val TYPE_LOCK = 1
const val TYPE_BOTH = 2
}
fun setListener(listener: IntentListener?) {
this.listener = listener
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: android.os.Bundle?
): android.view.View {
vb = FragmentToApplyBinding.inflate(layoutInflater)
init()
return vb.root
}
override fun onCreateDialog(savedInstanceState: android.os.Bundle?): android.app.Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window?.apply {
requestFeature(Window.FEATURE_NO_TITLE)
setWindowAnimations(R.style.CenterShowDialogStyle)
setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
setGravity(Gravity.CENTER)
}
return dialog
}
override fun onStart() {
super.onStart()
dialog?.apply {
setCanceledOnTouchOutside(true)
window?.apply {
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
}
}
private fun init() {
vb.layoutHome.setOnClickListener {
listener?.onClick(TYPE_HOME)
dismiss()
}
vb.layoutLock.setOnClickListener {
listener?.onClick(TYPE_LOCK)
dismiss()
}
vb.layoutBoth.setOnClickListener {
listener?.onClick(TYPE_BOTH)
dismiss()
}
}
}

View File

@ -0,0 +1,74 @@
package com.adpro.pixelshow.look
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import com.adpro.pixelshow.event.MoreAndSearchAdapter
import com.adpro.pixelshow.data.MainViewModel
import com.adpro.pixelshow.data.Movie
import com.adpro.pixelshow.databinding.ActivityTypeInfoBinding
import com.adpro.pixelshow.event.SecFavListener
import com.adpro.pixelshow.util.TopBarUtils
class TypeInfoActivity : AppCompatActivity(),SecFavListener {
private lateinit var binding:ActivityTypeInfoBinding
private lateinit var viewModel: MainViewModel
private lateinit var adapter:MoreAndSearchAdapter
private var currentTitleName: String = ""
companion object{
var titleName:String="name"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=ActivityTypeInfoBinding.inflate(layoutInflater)
init()
TopBarUtils.setStatusBar(this.window)
TopBarUtils.setLightStatusBar(this.window,true)
setContentView(binding.root)
}
private fun init(){
viewModel=ViewModelProvider(this)[MainViewModel::class.java]
currentTitleName = intent?.getStringExtra(titleName) ?: "Default Title"
// 保存标题到ViewModel
viewModel.currentTitleName = currentTitleName
// 设置标题 - 从ViewModel获取确保数据持久化
binding.name.text = viewModel.currentTitleName ?: currentTitleName
binding.searchPb.visibility= View.VISIBLE
binding.imageBack.setOnClickListener { finish() }
adapter=MoreAndSearchAdapter()
adapter.setListener(this)
binding.list.layoutManager=GridLayoutManager(this,2)
binding.list.adapter=adapter
viewModel.classificationList.observe(this) { list ->
// 在这里处理返回的数据
if(list.isNotEmpty()){
updateUI(list)
}
}
if(viewModel.classificationList.value.isNullOrEmpty()){
Log.d("Therererer","startGet")
viewModel.getClassificationList(currentTitleName)
}
}
private fun updateUI(list: List<Movie>){
Log.d("MoreMovieActivity","list size is"+list.size.toString())
adapter.setList(list)
binding.searchPb.visibility= View.GONE
adapter.notifyDataSetChanged()
}
override fun inItemClick(paper: Movie) {
val intent= Intent(this,DownloadRequestActivity::class.java)
intent.putExtra(DownloadRequestActivity.paperKey,paper)
startActivity(intent)
}
}

View File

@ -0,0 +1,132 @@
package com.adpro.pixelshow.util
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.util.Log
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.util.logging.Logger
object ApplyUtils {
private val LOGGER = Logger.getLogger(ApplyUtils::class.java.name)
interface ConnectCallBack {
fun onResult(success: Boolean, inputStream: InputStream?)
}
fun downloadFile(url: String, savePath: String, callback: ConnectCallBack): Call {
val client = OkHttpClient()
val request = Request.Builder().url(url).build()
val call = client.newCall(request)
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
LOGGER.severe("Download failed: ${e.message}")
callback.onResult(false, null)
}
override fun onResponse(call: Call, response: Response) {
response.use {
try {
val responseBody = response.body
if (responseBody != null) {
val inputStream = responseBody.byteStream()
val writeSuccess = writeFile(inputStream, savePath)
callback.onResult(writeSuccess, inputStream)
} else {
LOGGER.warning("Empty response body")
callback.onResult(false, null)
}
} catch (e: Exception) {
LOGGER.severe("Error processing response: ${e.message}")
callback.onResult(false, null)
}
}
}
})
return call
}
private fun writeFile(inputStream: InputStream, filePath: String): Boolean {
val file = File(filePath)
return try {
file.parentFile?.takeIf { !it.exists() }?.mkdirs()
FileOutputStream(file).use { fos ->
val buffer = ByteArray(4096)
var bytesRead: Int
while (inputStream.read(buffer).also { bytesRead = it } != -1) {
fos.write(buffer, 0, bytesRead)
}
true
}
} catch (e: Exception) {
LOGGER.severe("File write error: ${e.message}")
false
}
}
fun saveToGallery(context: Context, file: File): Uri? {
val name = "${System.currentTimeMillis()}.jpg"
val contentValues = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, name)
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 uri = 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 contentResolver = context.contentResolver
val imgUri = contentResolver.insert(uri, contentValues) ?: run {
Log.d("MediaSaver", "Failed to create media entry")
return null
}
try {
contentResolver.openOutputStream(imgUri)?.use { outputStream ->
FileInputStream(file).use { inputStream ->
val buffer = ByteArray(4026)
var byteRead: Int
while (inputStream.read(buffer).also { byteRead = it } != -1) {
outputStream.write(buffer, 0, byteRead)
}
}
}?:run {
Log.d("MediaSaver", "Failed to open output stream")
return null
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentValues.clear()
contentValues.put(MediaStore.Images.Media.IS_PENDING, 0)
contentResolver.update(imgUri, contentValues, null, null)
}
return imgUri
} catch (e: IOException) {
Log.e("MediaSaver", "Error saving image to gallery", e)
// 发生错误时删除创建的文件记录
try {
contentResolver.delete(imgUri, null, null)
} catch (deleteEx: Exception) {
Log.e("MediaSaver", "Failed to delete failed media entry", deleteEx)
}
return null
}
}
}

View File

@ -0,0 +1,24 @@
package com.adpro.pixelshow.util
import android.graphics.Color
import android.view.View
import android.view.Window
object TopBarUtils {
// 设置状态栏透明
fun setStatusBar(window: Window) {
window.statusBarColor = Color.TRANSPARENT
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}
// 设置状态栏黑色字体
fun setLightStatusBar(window: Window, isLight: Boolean) {
var systemUiVisibility = window.decorView.systemUiVisibility
systemUiVisibility = if (isLight) {
systemUiVisibility or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
} else {
systemUiVisibility and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
}
window.decorView.systemUiVisibility = systemUiVisibility
}
}

View File

@ -0,0 +1,103 @@
package com.adpro.pixelshow.util
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.content.ContextCompat
import com.adpro.pixelshow.data.Movie
import org.json.JSONArray
import org.json.JSONObject
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.io.Reader
import java.nio.charset.StandardCharsets
object TypeUtil {
fun getConvert(inputStream: InputStream): String {
var stringStr = ""
try {
val stringBuilder: StringBuilder = StringBuilder()
val buffer = CharArray(8192)
val reader: Reader =
BufferedReader(InputStreamReader(inputStream, StandardCharsets.UTF_8))
var byteRead: Int
while (reader.read(buffer).also { byteRead = it } != -1) {
stringBuilder.appendRange(buffer, 0, byteRead)
}
stringStr = stringBuilder.toString()
} catch (e: IOException) {
return stringStr
}
return stringStr
}
fun getData(data: String, name: String):List<Movie> {
val jsonArray = JSONArray(data)
val movieList = mutableListOf<Movie>()
var eachItem: JSONObject
var _description: String
var links: JSONObject
var download: String
var urls: JSONObject
var regular: String
var small: String
var thumb: String
val host = "https://unsplash.com/photos/"
var movie: Movie
var mid: String
for (i in 0 until jsonArray.length()) {
eachItem = jsonArray.getJSONObject(i)
_description = eachItem.getString("alt_description")
links = eachItem.getJSONObject("links")
download = links.getString("download")
urls = eachItem.getJSONObject("urls")
regular = urls.getString("regular")
small = urls.getString("small")
thumb = urls.getString("thumb")
mid = download.substring(host.length, download.indexOf("/download"))
movie = Movie().apply {
imId = mid
classificationName = name
description = _description
fullUrl = download
previewUrl1080 = regular
previewUrl400 = small
previewUrl200 = thumb
}
movieList.add(movie)
}
return movieList
}
fun getSaveFilePath(context: Context, imId: String): String {
return "${context.cacheDir}/${imId}.jpg"
}
fun checkPermission(context: Context,permissions:Array<String>):Boolean{
return permissions.all {
ContextCompat.checkSelfPermission(context,it)==PackageManager.PERMISSION_GRANTED
}
}
fun getStoragePermissions(): Array<String> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
arrayOf(Manifest.permission.READ_MEDIA_IMAGES)
} else {
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
}
fun hasStoragePermission(context: Context): Boolean {
return getStoragePermissions().all { permission ->
ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0%"
android:toYDelta="100%"
android:duration="300"/>
</set>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="100%"
android:toYDelta="0%"
android:duration="300"/>
</set>

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="M704,128C833.6,128 938.7,234.7 938.7,384c0,298.7 -320,469.3 -426.7,533.3C405.3,853.3 85.3,682.7 85.3,384c0,-149.3 106.7,-256 234.7,-256C399.4,128 469.3,170.7 512,213.3c42.7,-42.7 112.6,-85.3 192,-85.3zM551.9,793.8a1141.4,1141.4 0,0 0,103.3 -72.6C782.3,620.1 853.3,509.6 853.3,384c0,-100.7 -65.6,-170.7 -149.3,-170.7 -45.9,0 -95.6,24.3 -131.7,60.3L512,334l-60.3,-60.3C415.6,237.7 365.9,213.3 320,213.3 237.2,213.3 170.7,284 170.7,384c0,125.6 71.1,236.1 198.2,337.2 31.8,25.3 65.7,48.9 103.3,72.5 12.8,8.1 25.4,15.8 39.9,24.4 14.5,-8.6 27.1,-16.3 39.9,-24.4z"
android:fillColor="@color/green_text"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

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

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 线性渐变配置 -->
<gradient
android:type="linear"
android:startColor="#40A8D8EB"
android:endColor="#40A8D8EB"
android:angle="0"
/>
<corners android:radius="20dp"/>
</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="90"
android:startColor="#80000000"
android:centerColor="#00000000"
android:endColor="#80000000"
android:type="linear" />
</shape>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:topLeftRadius="8dp" android:topRightRadius="8dp" android:bottomRightRadius="8dp" android:bottomLeftRadius="8dp"/>
<solid android:color="#30A8D8EB"/>
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

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

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"
/>
<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/colorSelect"/>
</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/colorNotSelect"/>
</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/green_text"/>
</vector>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/gallery_selection_sel" android:state_selected="true" />
<item android:drawable="@drawable/gallery_selection_default" />
</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/liked_selection_sel" android:state_selected="true" />
<item android:drawable="@drawable/liked_selection_default" />
</selector>

View File

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

View File

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

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M395.2,513.6l-323.1,-312.4c-19.1,-18.4 -19.1,-48.3 0,-66.7 19.1,-18.4 49.9,-18.4 69,0L498.6,480.3c19.1,18.4 19.1,48.3 0,66.7l-357.6,345.7c-9.5,9.2 -22,13.8 -34.5,13.8 -12.5,0 -25,-4.6 -34.5,-13.8 -19.1,-18.4 -19.1,-48.2 0,-66.7L395.2,513.6z"
android:fillColor="@color/white"/>
</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/colorNotSelect"/>
</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/green_text"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="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="#C03B3B"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

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/white"/>
</vector>

View File

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

View File

@ -0,0 +1,27 @@
<?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="#e6e6e6" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="10dp" />
<gradient
android:angle="0"
android:endColor="@color/blue_bg"
android:centerColor="@color/blue_bg"
android:startColor="@color/blue_bg" />
</shape>
</clip>
</item>
</layer-list>

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="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/green_text"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

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="M747.2,283.2L54.5,283.2v692.7h692.7v-692.7zM656.8,373.6v512h-512v-512h512z"
android:fillColor="@color/green_text"/>
<path
android:pathData="M993.3,12.4v692.7h-287.2v-90.4h196.8v-512h-512v224.4h-90.4V12.4z"
android:fillColor="@color/green_text"/>
</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/green_text"
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,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/green_text"
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,119 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/bg_placeholder"
android:scaleType="centerCrop" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/dark_semi_transparent_bg"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="45dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageBack"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_gravity="center"
android:layout_marginStart="8dp"
android:padding="13dp"
android:src="@drawable/process_finished"
app:tint="@color/green_text"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<RelativeLayout
android:id="@+id/layoutSet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingVertical="5dp"
android:layout_marginEnd="20dp"
android:paddingHorizontal="5dp">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/phone_setting"/>
</RelativeLayout>
</LinearLayout>
<TextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="40dp"
android:padding="10dp"
android:text="@string/app_name"
android:textColor="@color/blue_bg"
android:textSize="17sp"
android:textStyle="bold"
android:layout_marginBottom="110dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvContent"
android:background="@drawable/every_out_stroke"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageLike"
android:layout_width="56dp"
android:layout_height="56dp"
android:padding="13dp"
android:src="@drawable/profile_like_icon" />
<RelativeLayout
android:id="@+id/layout_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imageDownload"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerInParent="true"
android:padding="13dp"
android:src="@drawable/pull_down_icon" />
<ProgressBar
android:id="@+id/pb_download"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerInParent="true"
android:indeterminateTint="@color/white"
android:padding="13dp"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>
<ProgressBar
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/pbSet"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_centerInParent="true"
android:indeterminateTint="@color/green_text"
android:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".look.FirstSelActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/bg"
app:layout_constraintTop_toTopOf="parent"
android:scaleType="fitXY"/>
<LinearLayout
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingVertical="20dp"
android:layout_marginTop="20dp"
app:layout_constraintTop_toTopOf="parent"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="28sp"
android:textStyle="bold"
android:layout_marginStart="25dp"
android:layout_gravity="center"
android:textColor="@color/black"/>
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<RelativeLayout
android:id="@+id/rlSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/every_out_stroke"
android:layout_marginEnd="25dp"
android:padding="8dp"
android:descendantFocusability="blocksDescendants"
android:layout_gravity="end">
<ImageView
android:id="@+id/imgSearch"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/search_grey"
app:tint="@color/green_text"
android:layout_centerVertical="true" />
</RelativeLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/fragmentIn"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/title"
app:layout_constraintBottom_toTopOf="@+id/llBottom" />
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#1a5ec1a1"
app:layout_constraintBottom_toTopOf="@+id/llBottom"/>
<LinearLayout
android:id="@+id/llBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:background="@drawable/bottom_main_bar"
app:layout_constraintBottom_toBottomOf="parent"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/llHome"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingVertical="5dp"
android:layout_weight="1"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/imgHome"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerInParent="true"
android:src="@drawable/home_selected_tab_default" />
</RelativeLayout>
<TextView
android:id="@+id/tvStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorNotSelect"
android:textSize="13sp"
android:text="@string/classification"/>
</LinearLayout>
<LinearLayout
android:id="@+id/llLike"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingVertical="5dp"
android:layout_weight="1"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<ImageView
android:id="@+id/imgLike"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_centerInParent="true"
android:src="@drawable/home_selected_tab_sel" />
</RelativeLayout>
<TextView
android:id="@+id/tvEnd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorNotSelect"
android:textSize="13sp"
android:text="@string/like"/>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".look.InitActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/bg"
app:layout_constraintTop_toTopOf="parent"
android:scaleType="fitXY"/>
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/imageview_logo"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="260dp"
android:src="@mipmap/ic_launcher_round"
app:roundPercent="0.2" />
<TextView
android:id="@+id/tvLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/imageview_logo"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:text="@string/app_name"
android:textColor="@color/green_text"
android:textStyle="bold"
android:textSize="25sp"/>
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_centerHorizontal="true"
android:layout_below="@+id/tvLogo"
android:layout_marginHorizontal="20dp"
android:max="100"
android:layout_marginTop="50dp"
android:progress="80"
android:indeterminateTint="@color/white"
android:progressDrawable="@drawable/progress_bar_grey_bg" />
</RelativeLayout>

View File

@ -0,0 +1,117 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".look.SearchKeyActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="45dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/imageBack"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:padding="13dp"
android:layout_marginStart="8dp"
android:src="@drawable/process_finished"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/black" />
<RelativeLayout
android:id="@+id/rlSearch"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/every_out_stroke"
android:layout_marginEnd="20dp"
android:gravity="center"
android:layout_gravity="center">
<ImageView
android:id="@+id/imgSearch"
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/explore_search_icon"
app:tint="@color/green_text"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"/>
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/imgSearch"
android:textSize="16sp"
android:imeOptions="actionSearch"
android:background="@null"
android:maxLines="1"
android:inputType="text"
android:layout_marginEnd="60dp"
android:textColorHint="@color/colorNotSelect"
android:layout_marginStart="10dp"
android:hint="@string/input_name_or_keyword"/>
<TextView
android:id="@+id/tvStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5sp"
android:text="@string/search"
android:textSize="16sp"
android:visibility="gone"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="10dp"
android:textColor="@color/black"
/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_marginHorizontal="20dp"
android:background="@drawable/d_top_10_radius_bg">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginHorizontal="5dp" />
<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/empty_state" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/no_data_found"
android:textColor="#000000" />
</LinearLayout>
<ProgressBar
android:id="@+id/searchPb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/colorSelect"
android:visibility="gone" />
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:src="@drawable/bg"
app:layout_constraintTop_toTopOf="parent"
android:scaleType="fitXY"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="@id/imageBack"
android:layout_alignBottom="@id/imageBack"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="@string/app_name"
android:textColor="@color/green_text"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/imageBack"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center"
android:padding="13dp"
android:src="@drawable/process_finished"
android:layout_marginStart="10dp"
android:layout_marginTop="45dp"
app:layout_constraintLeft_toLeftOf="parent"
app:tint="@color/green_text"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginHorizontal="20dp"
android:layout_below="@id/imageBack" />
<ProgressBar
android:id="@+id/searchPb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/white"
android:visibility="gone" />
</RelativeLayout>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".look.ClassificationFragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rvView"/>
</RelativeLayout>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".look.LikeFragment">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="5dp"
android:id="@+id/rvView"/>
<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="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:src="@drawable/empty_state" />
<TextView
android:id="@+id/tvNoData"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_horizontal"
android:lineSpacingExtra="4dp"
android:text="@string/empty"
android:textColor="@color/colorSelect"
android:layout_marginBottom="50dp"
android:textSize="14sp" />
</LinearLayout>
</RelativeLayout>

View File

@ -0,0 +1,98 @@
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/d_top_10_radius_bg"
android:orientation="vertical"
android:paddingVertical="20dp">
<LinearLayout
android:id="@+id/layout_home"
android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/select_dialog_icon_3" />
<TextView
android:id="@+id/home"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:textStyle="bold"
android:text="@string/apply_to_desktop"
android:textColor="@color/green_text"
android:textSize="18sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginHorizontal="10dp"
android:background="@color/blue_bg" />
<LinearLayout
android:id="@+id/layout_lock"
android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/select_dialog_icon_2" />
<TextView
android:id="@+id/lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:text="@string/apply_to_lock_screen"
android:textStyle="bold"
android:textColor="@color/green_text"
android:textSize="18sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginHorizontal="10dp"
android:background="@color/blue_bg" />
<LinearLayout
android:id="@+id/layout_both"
android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/select_dialog_icon_1" />
<TextView
android:id="@+id/both"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:text="@string/apply_to_all"
android:textStyle="bold"
android:textColor="@color/green_text"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@ -0,0 +1,25 @@
<?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"
android:layout_margin="5dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"
android:src="@mipmap/bg_placeholder" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="@drawable/dark_semi_transparent_bg" />
</androidx.cardview.widget.CardView>
</LinearLayout>

View File

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/llView"
android:layout_marginBottom="5dp"
android:layout_marginHorizontal="15dp"
android:background="@drawable/each_top_radius_8"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingHorizontal="10dp"
android:paddingVertical="20dp"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"/>
<TextView
android:id="@+id/txTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="20sp"
android:layout_marginEnd="10dp"
android:textColor="@color/green_text"/>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/icon_enter_image"
app:tint="@color/green_text"
android:padding="3dp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
android:paddingHorizontal="10dp"
android:id="@+id/rvView"/>
</LinearLayout>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_marginHorizontal="5dp"
android:orientation="horizontal"
android:layout_marginTop="5dp"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="100dp"
app:cardCornerRadius="10dp"
app:cardElevation="0dp">
<ImageView
android:id="@+id/inImage"
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"/>
</androidx.cardview.widget.CardView>
</RelativeLayout>
</LinearLayout>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="10dp">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="180dp"
android:scaleType="centerCrop"
android:src="@mipmap/bg_placeholder" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/dark_semi_transparent_bg" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginHorizontal="10dp"
android:layout_marginBottom="10dp"
android:text="@string/app_name"
android:textColor="@color/blue_bg"
android:maxLines="2"
android:ellipsize="end"
android:textSize="16sp" />
</androidx.cardview.widget.CardView>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

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