init
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
BIN
app/FunkyVoice.jks
Normal file
67
app/build.gradle.kts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import java.util.Date
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.application)
|
||||||
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.kotlin.compose)
|
||||||
|
id("io.objectbox")
|
||||||
|
}
|
||||||
|
val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
|
||||||
|
android {
|
||||||
|
namespace = "com.prank.funky.voice"
|
||||||
|
compileSdk = 35
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId = "com.prank.funky.voice"
|
||||||
|
minSdk = 24
|
||||||
|
targetSdk = 35
|
||||||
|
versionCode = 1
|
||||||
|
versionName = "1.0"
|
||||||
|
setProperty("archivesBaseName", "FunkyVoice_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.lifecycle.runtime.ktx)
|
||||||
|
implementation(libs.androidx.activity.compose)
|
||||||
|
implementation(platform(libs.androidx.compose.bom))
|
||||||
|
implementation(libs.androidx.ui)
|
||||||
|
implementation(libs.androidx.ui.graphics)
|
||||||
|
implementation(libs.androidx.ui.tooling.preview)
|
||||||
|
implementation(libs.androidx.material3)
|
||||||
|
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)
|
||||||
|
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||||
|
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||||
|
debugImplementation(libs.androidx.ui.tooling)
|
||||||
|
debugImplementation(libs.androidx.ui.test.manifest)
|
||||||
|
implementation ("com.github.bumptech.glide:glide:4.16.0")
|
||||||
|
}
|
||||||
109
app/objectbox-models/default.json
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
{
|
||||||
|
"_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.",
|
||||||
|
"_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.",
|
||||||
|
"_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.",
|
||||||
|
"entities": [
|
||||||
|
{
|
||||||
|
"id": "3:2765052130869583396",
|
||||||
|
"lastPropertyId": "3:6236996964031349478",
|
||||||
|
"name": "EntitySounds",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": "1:5164626891309238159",
|
||||||
|
"name": "id",
|
||||||
|
"type": 6,
|
||||||
|
"flags": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2:623595642016909498",
|
||||||
|
"name": "name",
|
||||||
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3:6236996964031349478",
|
||||||
|
"name": "covert",
|
||||||
|
"type": 9
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"relations": [
|
||||||
|
{
|
||||||
|
"id": "2:7923194685831121399",
|
||||||
|
"name": "entitySoundsDetailList",
|
||||||
|
"targetId": "4:4417687023652744495"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4:4417687023652744495",
|
||||||
|
"lastPropertyId": "7:3184593639987712609",
|
||||||
|
"name": "EntitySoundsDetail",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"id": "1:8661368180635646655",
|
||||||
|
"name": "id",
|
||||||
|
"type": 6,
|
||||||
|
"flags": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2:1592243912345810464",
|
||||||
|
"name": "name",
|
||||||
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3:4698482079418305236",
|
||||||
|
"name": "covert",
|
||||||
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4:4993413492996791852",
|
||||||
|
"name": "soundsPath",
|
||||||
|
"type": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5:6369449011390216196",
|
||||||
|
"name": "isLike",
|
||||||
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6:6434336433645459276",
|
||||||
|
"name": "isCustomization",
|
||||||
|
"type": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7:3184593639987712609",
|
||||||
|
"name": "colorIndex",
|
||||||
|
"type": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"relations": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastEntityId": "4:4417687023652744495",
|
||||||
|
"lastIndexId": "0:0",
|
||||||
|
"lastRelationId": "2:7923194685831121399",
|
||||||
|
"lastSequenceId": "0:0",
|
||||||
|
"modelVersion": 5,
|
||||||
|
"modelVersionParserMinimum": 5,
|
||||||
|
"retiredEntityUids": [
|
||||||
|
8407318924071742,
|
||||||
|
3291095796857804749
|
||||||
|
],
|
||||||
|
"retiredIndexUids": [],
|
||||||
|
"retiredPropertyUids": [
|
||||||
|
3102693164112875939,
|
||||||
|
1199147246499509324,
|
||||||
|
7954483026570234729,
|
||||||
|
1980648303218983721,
|
||||||
|
4412998170453317817,
|
||||||
|
8606939009768073387,
|
||||||
|
9206178868285963197,
|
||||||
|
2627505466161450469,
|
||||||
|
8487142908259107486,
|
||||||
|
5933482487640104252,
|
||||||
|
5318713824755369776
|
||||||
|
],
|
||||||
|
"retiredRelationUids": [
|
||||||
|
1942152868705305926
|
||||||
|
],
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
32
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
# 保留Processor类,这些类用于在编译时生成ObjectBox需要的代码
|
||||||
|
-keep @io.objectbox.annotation.processor.Processor class * {
|
||||||
|
*;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 保留ObjectBox的关键方法和构造函数
|
||||||
|
-keepclassmembers class * extends io.objectbox.Box {
|
||||||
|
<init>(...);
|
||||||
|
<methods>;
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.sounds.funny.theprankapp
|
||||||
|
|
||||||
|
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.sounds.funny.theprankapp", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
57
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?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.READ_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" /> <!-- Android 13+ 单独的音频访问权限 -->
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name="com.prank.funky.voice.App"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/logo"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/logo"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.ThePrankApp"
|
||||||
|
tools:targetApi="31">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.recordSounds.CustomActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.recordSounds.RecordSoundsActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.collection.CollectionActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.playSounds.PlaySoundsActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.soundsList.ListActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.home.HomeActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/Theme.ThePrankApp" />
|
||||||
|
<activity
|
||||||
|
android:name="com.prank.funky.voice.welcome.WelcomeActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
3791
app/src/main/assets/pranksounds.json
Normal file
42
app/src/main/java/com/prank/funky/voice/App.kt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package com.prank.funky.voice
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import com.prank.funky.voice.objectBox.DbBaseFunction
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySounds
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.Collections
|
||||||
|
|
||||||
|
class App : Application() {
|
||||||
|
companion object{
|
||||||
|
lateinit var mApp:App
|
||||||
|
val TAG = "+++++++++++++"
|
||||||
|
|
||||||
|
var entitySoundsList: List<EntitySounds>? = null
|
||||||
|
}
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
mApp = this
|
||||||
|
DbBaseFunction.init(this)
|
||||||
|
if (entitySoundsList != null) return
|
||||||
|
try {
|
||||||
|
val open = getAssets().open("pranksounds.json")
|
||||||
|
val string: String = Util.getString(open)
|
||||||
|
if (!string.isEmpty()) {
|
||||||
|
entitySoundsList = Util.getBean(string)
|
||||||
|
Util.showLog(entitySoundsList?.size.toString())
|
||||||
|
entitySoundsList?.let {
|
||||||
|
Collections.shuffle(it)
|
||||||
|
for (category in it) {
|
||||||
|
for (info1 in category.entitySoundsDetailList!!) {
|
||||||
|
info1.isLike = false
|
||||||
|
DbBaseFunction.getSoundsBox().put(info1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
package com.prank.funky.voice.collection
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.prank.funky.voice.utils.RecyclerSpace
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import com.prank.funky.voice.objectBox.DbBaseFunction
|
||||||
|
import com.prank.funky.voice.playSounds.PlaySoundsActivity
|
||||||
|
|
||||||
|
class CollectionActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var recyclerView: RecyclerView
|
||||||
|
private lateinit var emptyLayout: LinearLayout
|
||||||
|
private lateinit var collectionAdapter: CollectionAdapter
|
||||||
|
private val mLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result ->
|
||||||
|
if (result.resultCode == RESULT_OK) {
|
||||||
|
val data = result.data
|
||||||
|
val value = data?.getBooleanExtra(KEY_DELETE_FAVORITE, false)
|
||||||
|
if (value == true) {
|
||||||
|
queryLikeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val KEY_DELETE_FAVORITE = "is_delete_favorite"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_collection)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
findViewById<FrameLayout?>(R.id.framelayout_back).setOnClickListener { finish() }
|
||||||
|
|
||||||
|
recyclerView = findViewById(R.id.favorite_recyclerview)
|
||||||
|
emptyLayout = findViewById(R.id.empty_favorite)
|
||||||
|
|
||||||
|
recyclerView.run {
|
||||||
|
val itemHelper = RecyclerSpace(5, 5, 3)
|
||||||
|
addItemDecoration(itemHelper)
|
||||||
|
setLayoutManager(GridLayoutManager(this@CollectionActivity, 3))
|
||||||
|
collectionAdapter = CollectionAdapter(this@CollectionActivity) { data, soundsIndex ->
|
||||||
|
mLauncher.launch(Intent(this@CollectionActivity, PlaySoundsActivity::class.java).apply {
|
||||||
|
putExtra(PlaySoundsActivity.Companion.KEY_SOUNDS_DETAIL_DATA, data)
|
||||||
|
putExtra(PlaySoundsActivity.Companion.KEY_SOUNDS_DETAIL_INDEX, soundsIndex)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
queryLikeData()
|
||||||
|
setAdapter(collectionAdapter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun queryLikeData() {
|
||||||
|
val allLike = DbBaseFunction.getAllLike()
|
||||||
|
Util.showLog("-----like---updateData allLike=${allLike.size}")
|
||||||
|
showFavoriteEmptyView(allLike.isEmpty())
|
||||||
|
collectionAdapter.updateData(allLike)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showFavoriteEmptyView(isEmpty: Boolean) {
|
||||||
|
emptyLayout.isVisible = isEmpty
|
||||||
|
recyclerView.isVisible = !isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.prank.funky.voice.collection
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.prank.funky.voice.databinding.CollectionAdapterBinding
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySoundsDetail
|
||||||
|
import com.prank.funky.voice.utils.BaseAdapter
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
|
||||||
|
class CollectionAdapter(
|
||||||
|
context: Context,
|
||||||
|
var onClickIntent: (sounds: EntitySoundsDetail, soundsIndex: Int) -> Unit
|
||||||
|
) :
|
||||||
|
BaseAdapter<EntitySoundsDetail, CollectionAdapterBinding>(context) {
|
||||||
|
override fun getViewBinding(parent: ViewGroup?): CollectionAdapterBinding {
|
||||||
|
return CollectionAdapterBinding.inflate(
|
||||||
|
LayoutInflater.from(parent?.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val itemHolder = holder as VHolder<CollectionAdapterBinding>
|
||||||
|
val entitySoundsDetail: EntitySoundsDetail = data[position]
|
||||||
|
itemHolder.vb.run {
|
||||||
|
entitySoundsDetail.run {
|
||||||
|
root.background = ContextCompat.getDrawable(mContext, Util.mainBgs[colorIndex])
|
||||||
|
if(!isCustomization){
|
||||||
|
val covert: String = entitySoundsDetail.covert.toString()
|
||||||
|
Glide.with(mContext).load(covert).into(imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
textView.text = entitySoundsDetail.name
|
||||||
|
root.setOnClickListener {
|
||||||
|
onClickIntent(entitySoundsDetail, colorIndex)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
58
app/src/main/java/com/prank/funky/voice/home/HomeActivity.kt
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package com.prank.funky.voice.home
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.prank.funky.voice.App
|
||||||
|
import com.prank.funky.voice.utils.RecyclerSpace
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import com.prank.funky.voice.collection.CollectionActivity
|
||||||
|
import com.prank.funky.voice.soundsList.ListActivity
|
||||||
|
import com.prank.funky.voice.recordSounds.CustomActivity
|
||||||
|
|
||||||
|
class HomeActivity : AppCompatActivity() {
|
||||||
|
private lateinit var recycler:RecyclerView
|
||||||
|
private lateinit var layoutFavorite:FrameLayout
|
||||||
|
private lateinit var layoutRecorder:FrameLayout
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_home)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
recycler= findViewById(R.id.recycler_view)
|
||||||
|
layoutFavorite= findViewById(R.id.frame_layout_favorite)
|
||||||
|
layoutRecorder= findViewById(R.id.frame_layout_record)
|
||||||
|
recycler.run {
|
||||||
|
val itemHelper = RecyclerSpace(5, 5, 3)
|
||||||
|
addItemDecoration(itemHelper)
|
||||||
|
setLayoutManager(GridLayoutManager(this@HomeActivity, 2))
|
||||||
|
setAdapter(HomeAdapter(this@HomeActivity){ data, soundsIndex->
|
||||||
|
startActivity(Intent(this@HomeActivity, ListActivity::class.java).apply {
|
||||||
|
putExtra(ListActivity.Companion.KEY_SOUNDS_DATA,data)
|
||||||
|
putExtra(ListActivity.Companion.KEY_SOUNDS_INDEX,soundsIndex)
|
||||||
|
})
|
||||||
|
|
||||||
|
}.apply {
|
||||||
|
Util.showLog("------Main--updateData")
|
||||||
|
updateData(App.Companion.entitySoundsList)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
layoutFavorite.setOnClickListener {
|
||||||
|
startActivity(Intent(this@HomeActivity, CollectionActivity::class.java))
|
||||||
|
}
|
||||||
|
layoutRecorder.setOnClickListener {
|
||||||
|
startActivity(Intent(this@HomeActivity, CustomActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
app/src/main/java/com/prank/funky/voice/home/HomeAdapter.kt
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package com.prank.funky.voice.home
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.prank.funky.voice.databinding.HomeAdapterBinding
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySounds
|
||||||
|
import com.prank.funky.voice.utils.BaseAdapter
|
||||||
|
import com.prank.funky.voice.utils.RecyclerSpace
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
|
||||||
|
class HomeAdapter(context: Context, var onClickIntent: (entitySounds: EntitySounds, soundsIndex:Int) -> Unit) :
|
||||||
|
BaseAdapter<EntitySounds, HomeAdapterBinding>(context) {
|
||||||
|
override fun getViewBinding(parent: ViewGroup?): HomeAdapterBinding {
|
||||||
|
return HomeAdapterBinding.inflate(
|
||||||
|
LayoutInflater.from(parent?.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val itemHolder = holder as VHolder<HomeAdapterBinding>
|
||||||
|
val i = position % 4
|
||||||
|
itemHolder.vb.run {
|
||||||
|
val layoutParams = root.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
|
if(position == 0||position == 1){
|
||||||
|
layoutParams.setMargins(0, RecyclerSpace.Companion.dpToPx(10f).toInt(), 0, 0)
|
||||||
|
}else{
|
||||||
|
layoutParams.setMargins(0, 0, 0, 0)
|
||||||
|
}
|
||||||
|
root.layoutParams = layoutParams
|
||||||
|
root.background = ContextCompat.getDrawable(mContext, Util.mainBgs[i])
|
||||||
|
val entitySounds: EntitySounds = data[position]
|
||||||
|
val covert: String = entitySounds.covert.toString()
|
||||||
|
Glide.with(mContext).load(covert).into(imageView)
|
||||||
|
textView.text = entitySounds.name
|
||||||
|
root.setOnClickListener(View.OnClickListener {
|
||||||
|
onClickIntent(entitySounds,i)
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
package com.prank.funky.voice.objectBox
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import io.objectbox.Box
|
||||||
|
import io.objectbox.BoxStore
|
||||||
|
import io.objectbox.query.Query
|
||||||
|
import java.util.Collections
|
||||||
|
|
||||||
|
object DbBaseFunction {
|
||||||
|
|
||||||
|
|
||||||
|
lateinit var boxStore: BoxStore
|
||||||
|
fun init(context: Context?) {
|
||||||
|
boxStore = MyObjectBox.builder()
|
||||||
|
.androidContext(context)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
fun getSoundsBox(): Box<EntitySoundsDetail> {
|
||||||
|
return boxStore.boxFor(EntitySoundsDetail::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getAllLike(): List<EntitySoundsDetail> {
|
||||||
|
val query: Query<EntitySoundsDetail> =
|
||||||
|
getSoundsBox().query(EntitySoundsDetail_.isLike.equal(true))
|
||||||
|
.build()
|
||||||
|
val data: List<EntitySoundsDetail> = query.find()
|
||||||
|
query.close()
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAllCustomization(): List<EntitySoundsDetail> {
|
||||||
|
val query: Query<EntitySoundsDetail> = getSoundsBox()
|
||||||
|
.query(EntitySoundsDetail_.isCustomization.equal(true)).build()
|
||||||
|
val data: List<EntitySoundsDetail> = query.find()
|
||||||
|
query.close()
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getMore(): List<EntitySoundsDetail?> {
|
||||||
|
val query: Query<EntitySoundsDetail?> = getSoundsBox()
|
||||||
|
.query(EntitySoundsDetail_.isCustomization.equal(false)).build()
|
||||||
|
val data: List<EntitySoundsDetail?> = query.find()
|
||||||
|
query.close()
|
||||||
|
Collections.shuffle(data)
|
||||||
|
return data.subList(0, 11)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkLike(info: EntitySoundsDetail): Boolean {
|
||||||
|
val query: Query<EntitySoundsDetail> = getSoundsBox()
|
||||||
|
.query(EntitySoundsDetail_.name.equal(info.name)).build()
|
||||||
|
val data: EntitySoundsDetail? = query.findFirst()
|
||||||
|
query.close()
|
||||||
|
return data?.isLike ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkName(name: String?): Boolean {
|
||||||
|
val query: Query<EntitySoundsDetail> =
|
||||||
|
getSoundsBox().query(EntitySoundsDetail_.name.equal(name)).build()
|
||||||
|
val data: EntitySoundsDetail? = query.findFirst()
|
||||||
|
query.close()
|
||||||
|
return if (data != null) {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addLike(info: EntitySoundsDetail) {
|
||||||
|
info.isLike = true
|
||||||
|
getSoundsBox().put(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeLike(info: EntitySoundsDetail) {
|
||||||
|
info.isLike = false
|
||||||
|
getSoundsBox().put(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.prank.funky.voice.objectBox
|
||||||
|
|
||||||
|
import io.objectbox.annotation.Entity
|
||||||
|
import io.objectbox.annotation.Id
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class EntitySounds : Serializable {
|
||||||
|
@JvmField
|
||||||
|
@Id
|
||||||
|
var id: Long = 0
|
||||||
|
@JvmField
|
||||||
|
var name: String? = null
|
||||||
|
@JvmField
|
||||||
|
var covert: String? = null
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var entitySoundsDetailList: List<EntitySoundsDetail>? = null
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.prank.funky.voice.objectBox
|
||||||
|
|
||||||
|
import io.objectbox.annotation.Entity
|
||||||
|
import io.objectbox.annotation.Id
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class EntitySoundsDetail : Serializable {
|
||||||
|
@JvmField
|
||||||
|
@Id
|
||||||
|
var id: Long = 0
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var name: String? = null
|
||||||
|
@JvmField
|
||||||
|
var covert: String? = null
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var soundsPath: String? = null
|
||||||
|
@JvmField
|
||||||
|
var isLike: Boolean = false
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var isCustomization: Boolean = false
|
||||||
|
@JvmField
|
||||||
|
var colorIndex: Int = 0
|
||||||
|
}
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
package com.prank.funky.voice.playSounds
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
import androidx.core.animation.doOnEnd
|
||||||
|
import com.prank.funky.voice.utils.RecyclerSpace
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
|
||||||
|
class CustomerRippleView @JvmOverloads constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null
|
||||||
|
) : View(context, attrs) {
|
||||||
|
|
||||||
|
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||||
|
color = Color.parseColor("#FFFFFF")
|
||||||
|
style = Paint.Style.FILL
|
||||||
|
}
|
||||||
|
|
||||||
|
private val ripples = mutableListOf<Ripple>()
|
||||||
|
private var maxRadius = 200f
|
||||||
|
private val rippleDuration = 1000L
|
||||||
|
private val rippleDelay = 300L
|
||||||
|
|
||||||
|
private var curisRunning = false
|
||||||
|
private var isPaused = false
|
||||||
|
|
||||||
|
private val rippleRunnable = object : Runnable {
|
||||||
|
override fun run() {
|
||||||
|
if (!curisRunning || isPaused) return
|
||||||
|
val ripple = Ripple()
|
||||||
|
ripples.add(ripple)
|
||||||
|
ripple.start()
|
||||||
|
Util.showLog("-------start rippleRunnable")
|
||||||
|
postDelayed(this, rippleDelay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMaxRadius(radiusDp: Float) {
|
||||||
|
maxRadius = RecyclerSpace.Companion.dpToPx(radiusDp)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setColor(color: Int) {
|
||||||
|
paint.color = color
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startRipple() {
|
||||||
|
if (curisRunning) return
|
||||||
|
curisRunning = true
|
||||||
|
isPaused = false
|
||||||
|
post(rippleRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopRipple() {
|
||||||
|
curisRunning = false
|
||||||
|
isPaused = false
|
||||||
|
removeCallbacks(rippleRunnable)
|
||||||
|
ripples.forEach { it.cancel() }
|
||||||
|
ripples.clear()
|
||||||
|
invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pauseRipple() {
|
||||||
|
isPaused = true
|
||||||
|
ripples.forEach { it.pause() }
|
||||||
|
removeCallbacks(rippleRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resumeRipple() {
|
||||||
|
if (!curisRunning || !isPaused) return
|
||||||
|
isPaused = false
|
||||||
|
ripples.forEach { it.resume() }
|
||||||
|
post(rippleRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDraw(canvas: Canvas) {
|
||||||
|
super.onDraw(canvas)
|
||||||
|
val centerX = width / 2f
|
||||||
|
val centerY = height / 2f
|
||||||
|
val iterator = ripples.iterator()
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
val ripple = iterator.next()
|
||||||
|
if (!ripple.isRunning) {
|
||||||
|
iterator.remove()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
paint.alpha = (255 * (1 - ripple.progress)).toInt()
|
||||||
|
canvas.drawCircle(centerX, centerY, maxRadius * ripple.progress, paint)
|
||||||
|
}
|
||||||
|
if (ripples.isNotEmpty()) invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class Ripple {
|
||||||
|
var progress = 0f
|
||||||
|
var isRunning = true
|
||||||
|
private var animator: ValueAnimator? = null
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
animator = ValueAnimator.ofFloat(0f, 1f).apply {
|
||||||
|
duration = rippleDuration
|
||||||
|
addUpdateListener {
|
||||||
|
progress = it.animatedValue as Float
|
||||||
|
invalidate()
|
||||||
|
}
|
||||||
|
doOnEnd {
|
||||||
|
this@Ripple.isRunning = false
|
||||||
|
}
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pause() {
|
||||||
|
if (animator?.isRunning == true) {
|
||||||
|
animator?.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resume() {
|
||||||
|
if (animator?.isPaused == true) {
|
||||||
|
animator?.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancel() {
|
||||||
|
animator?.cancel()
|
||||||
|
isRunning = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,285 @@
|
|||||||
|
package com.prank.funky.voice.playSounds
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.media.AudioManager
|
||||||
|
import android.media.MediaPlayer
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.ProgressBar
|
||||||
|
import android.widget.SeekBar
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.OnBackPressedCallback
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import com.prank.funky.voice.objectBox.DbBaseFunction
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySoundsDetail
|
||||||
|
import com.prank.funky.voice.collection.CollectionActivity
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class PlaySoundsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var textViewTitle: TextView
|
||||||
|
private lateinit var ImaggBg: FrameLayout
|
||||||
|
private lateinit var mSoundsImage: ImageView
|
||||||
|
private lateinit var loadPlayPb: ProgressBar
|
||||||
|
private lateinit var playSoundsBtn: ImageView
|
||||||
|
private lateinit var volumeBar: SeekBar
|
||||||
|
private lateinit var timerLayout: FrameLayout
|
||||||
|
private lateinit var looperLayout: FrameLayout
|
||||||
|
private lateinit var favoriteLayout: FrameLayout
|
||||||
|
private lateinit var imageFavorite: ImageView
|
||||||
|
private lateinit var imageClock: ImageView
|
||||||
|
private lateinit var imageLoop: ImageView
|
||||||
|
private var mediaPlayer: MediaPlayer? = null
|
||||||
|
private var volumeBroadcastReceiver: BroadcastReceiver? = null
|
||||||
|
private var clockTimer: PopupWindowsTimer? = null
|
||||||
|
private var countDownTimer: CountDownTimer? = null
|
||||||
|
private lateinit var playAnime: CustomerRippleView
|
||||||
|
private lateinit var playFrame: FrameLayout
|
||||||
|
private var isPause = false
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val KEY_SOUNDS_DETAIL_INDEX = "sounds_detail_index"
|
||||||
|
val KEY_SOUNDS_DETAIL_DATA = "sounds_detail_data"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var soundsIndex: Int = 0
|
||||||
|
private var entitySoundsDetail: EntitySoundsDetail? = null
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_play_sounds)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||||
|
override fun handleOnBackPressed() {
|
||||||
|
Util.showLog("-----------handleOnBackPressed")
|
||||||
|
backIntent()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
textViewTitle = findViewById(R.id.sounds_name)
|
||||||
|
ImaggBg = findViewById(R.id.sounds_img)
|
||||||
|
loadPlayPb = findViewById(R.id.play_loading)
|
||||||
|
mSoundsImage = findViewById(R.id.image)
|
||||||
|
playSoundsBtn = findViewById(R.id.btn_play)
|
||||||
|
playFrame = findViewById(R.id.frame_layout_btn_play)
|
||||||
|
playAnime = findViewById(R.id.rippleView)
|
||||||
|
volumeBar = findViewById(R.id.volume_seekbar)
|
||||||
|
timerLayout = findViewById(R.id.frameLayout_timer)
|
||||||
|
looperLayout = findViewById(R.id.frameLayout_loop)
|
||||||
|
favoriteLayout = findViewById(R.id.framelayout_favorite)
|
||||||
|
imageFavorite = findViewById(R.id.image_favorite)
|
||||||
|
imageClock = findViewById(R.id.image_clock)
|
||||||
|
imageLoop = findViewById(R.id.image_loop)
|
||||||
|
|
||||||
|
soundsIndex = intent.getIntExtra(KEY_SOUNDS_DETAIL_INDEX, 0)
|
||||||
|
when (soundsIndex) {
|
||||||
|
0 -> playAnime.setColor(getColor(R.color.main_color1))
|
||||||
|
1 -> playAnime.setColor(getColor(R.color.main_color2))
|
||||||
|
2 -> playAnime.setColor(getColor(R.color.main_color3))
|
||||||
|
3 -> playAnime.setColor(getColor(R.color.main_color4))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImaggBg.background =
|
||||||
|
ContextCompat.getDrawable(this@PlaySoundsActivity, Util.mainBgs[soundsIndex])
|
||||||
|
entitySoundsDetail = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
intent.getSerializableExtra(KEY_SOUNDS_DETAIL_DATA, EntitySoundsDetail::class.java)
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
intent.getSerializableExtra(KEY_SOUNDS_DETAIL_DATA) as? EntitySoundsDetail
|
||||||
|
}
|
||||||
|
|
||||||
|
Util.syncCurrentVolume(this@PlaySoundsActivity, volumeBar)
|
||||||
|
entitySoundsDetail?.run {
|
||||||
|
soundsPath?.let { initMediaPlayer(it) }
|
||||||
|
val checkLike = DbBaseFunction.checkLike(this)
|
||||||
|
Util.showLog("check like = $checkLike")
|
||||||
|
imageFavorite.setSelected(checkLike)
|
||||||
|
textViewTitle.text = name
|
||||||
|
|
||||||
|
covert?.let {
|
||||||
|
Glide.with(this@PlaySoundsActivity).load(it)
|
||||||
|
.placeholder(R.drawable.icon_music)
|
||||||
|
.into(mSoundsImage)
|
||||||
|
} ?: Glide.with(this@PlaySoundsActivity).load(R.drawable.icon_music)
|
||||||
|
.into(mSoundsImage)
|
||||||
|
|
||||||
|
}
|
||||||
|
setAllClick()
|
||||||
|
volumeBroadcastReceiver = object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
if (intent.action == "android.media.VOLUME_CHANGED_ACTION") {
|
||||||
|
val audioManager = context.getSystemService(AUDIO_SERVICE) as AudioManager
|
||||||
|
val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||||
|
volumeBar.progress = currentVolume
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val filter = IntentFilter("android.media.VOLUME_CHANGED_ACTION")
|
||||||
|
registerReceiver(volumeBroadcastReceiver, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun backIntent() {
|
||||||
|
val intent = Intent().apply {
|
||||||
|
putExtra(CollectionActivity.Companion.KEY_DELETE_FAVORITE, !imageFavorite.isSelected)
|
||||||
|
}
|
||||||
|
setResult(RESULT_OK, intent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setAllClick() {
|
||||||
|
findViewById<FrameLayout>(R.id.framelayout_back).setOnClickListener {
|
||||||
|
Util.showLog("-----------finish")
|
||||||
|
backIntent()
|
||||||
|
|
||||||
|
}
|
||||||
|
favoriteLayout.setOnClickListener {
|
||||||
|
imageFavorite.isSelected = !imageFavorite.isSelected
|
||||||
|
|
||||||
|
entitySoundsDetail?.let {
|
||||||
|
if (imageFavorite.isSelected) {
|
||||||
|
DbBaseFunction.addLike(it.apply {
|
||||||
|
colorIndex = soundsIndex
|
||||||
|
})
|
||||||
|
|
||||||
|
} else {
|
||||||
|
DbBaseFunction.removeLike(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
looperLayout.setOnClickListener {
|
||||||
|
imageLoop.isSelected = !imageLoop.isSelected
|
||||||
|
mediaPlayer?.isLooping = imageLoop.isSelected
|
||||||
|
}
|
||||||
|
timerLayout.setOnClickListener {
|
||||||
|
clockTimer = clockTimer ?: PopupWindowsTimer(this@PlaySoundsActivity) {
|
||||||
|
clockTimer?.hidePop()
|
||||||
|
if (it == -1L) {
|
||||||
|
imageClock.isSelected = false
|
||||||
|
stopCountDown()
|
||||||
|
} else {
|
||||||
|
imageClock.isSelected = true
|
||||||
|
startCountDown(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clockTimer?.showDown(timerLayout)
|
||||||
|
}
|
||||||
|
playSoundsBtn.setOnClickListener { view ->
|
||||||
|
mediaPlayer?.let {
|
||||||
|
if (playSoundsBtn.isSelected) {
|
||||||
|
if (it.isPlaying) {
|
||||||
|
it.pause()
|
||||||
|
isPause = true
|
||||||
|
playAnime.pauseRipple()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!it.isPlaying) {
|
||||||
|
it.start()
|
||||||
|
if (isPause) {
|
||||||
|
playAnime.resumeRipple()
|
||||||
|
} else {
|
||||||
|
playAnime.startRipple()
|
||||||
|
}
|
||||||
|
isPause = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playSoundsBtn.setSelected(!playSoundsBtn.isSelected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startCountDown(time: Long) {
|
||||||
|
stopCountDown()
|
||||||
|
countDownTimer = object : CountDownTimer(time, 1000) {
|
||||||
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinish() {
|
||||||
|
imageClock.isSelected = false
|
||||||
|
clockTimer?.setOffSelected()
|
||||||
|
if (!mediaPlayer!!.isPlaying) {
|
||||||
|
playSoundsBtn.setSelected(true)
|
||||||
|
mediaPlayer!!.start()
|
||||||
|
playAnime.startRipple()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownTimer?.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopCountDown() {
|
||||||
|
if (countDownTimer != null) {
|
||||||
|
countDownTimer!!.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initMediaPlayer(url: String) {
|
||||||
|
showPlayBtn(false)
|
||||||
|
Util.showLog("url = $url")
|
||||||
|
mediaPlayer = MediaPlayer()
|
||||||
|
try {
|
||||||
|
mediaPlayer!!.reset()
|
||||||
|
mediaPlayer!!.setDataSource(url)
|
||||||
|
mediaPlayer!!.prepareAsync()
|
||||||
|
mediaPlayer!!.setOnPreparedListener { showPlayBtn(true) }
|
||||||
|
mediaPlayer!!.setOnCompletionListener {
|
||||||
|
playSoundsBtn.setSelected(false)
|
||||||
|
playAnime.stopRipple()
|
||||||
|
isPause = false
|
||||||
|
}
|
||||||
|
} catch (ioException: IOException) {
|
||||||
|
showPlayBtn(false)
|
||||||
|
Toast.makeText(this, "----------prepare fail", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showPlayBtn(showBtn: Boolean) {
|
||||||
|
if (showBtn) {
|
||||||
|
playFrame.visibility = View.VISIBLE
|
||||||
|
loadPlayPb.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
playFrame.visibility = View.GONE
|
||||||
|
loadPlayPb.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
volumeBroadcastReceiver?.let { unregisterReceiver(it) }
|
||||||
|
stopCountDown()
|
||||||
|
playAnime.stopRipple()
|
||||||
|
isPause = false
|
||||||
|
mediaPlayer?.apply {
|
||||||
|
stop()
|
||||||
|
reset()
|
||||||
|
release()
|
||||||
|
}
|
||||||
|
mediaPlayer = null
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
package com.prank.funky.voice.playSounds
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.PopupWindow
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.view.size
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
|
||||||
|
|
||||||
|
class PopupWindowsTimer(var context: Context, var onClickTimer:(time:Long)->Unit):View.OnClickListener {
|
||||||
|
private lateinit var tvOff: TextView
|
||||||
|
private lateinit var tv15s: TextView
|
||||||
|
private lateinit var tv30s: TextView
|
||||||
|
private lateinit var tv1Min: TextView
|
||||||
|
private lateinit var tv5Min: TextView
|
||||||
|
private lateinit var linearLayoutTimer:LinearLayout
|
||||||
|
private lateinit var popupWindow:PopupWindow
|
||||||
|
|
||||||
|
init {
|
||||||
|
|
||||||
|
initPopupWindows(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initPopupWindows(context: Context) {
|
||||||
|
|
||||||
|
val popupView = LayoutInflater.from(context).inflate(R.layout.dialog_timer, null)
|
||||||
|
|
||||||
|
popupWindow = PopupWindow(
|
||||||
|
popupView,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
popupWindow.setBackgroundDrawable(null)
|
||||||
|
popupWindow.isOutsideTouchable = true
|
||||||
|
|
||||||
|
|
||||||
|
tvOff = popupView.findViewById(R.id.tv_off)
|
||||||
|
tv15s = popupView.findViewById(R.id.tv_15s)
|
||||||
|
tv30s = popupView.findViewById(R.id.tv_30s)
|
||||||
|
tv1Min = popupView.findViewById(R.id.tv_1m)
|
||||||
|
tv5Min = popupView.findViewById(R.id.tv_5m)
|
||||||
|
linearLayoutTimer = popupView.findViewById(R.id.layout_time)
|
||||||
|
tvOff.setOnClickListener(this)
|
||||||
|
tv15s.setOnClickListener(this)
|
||||||
|
tv30s.setOnClickListener(this)
|
||||||
|
tv1Min.setOnClickListener(this)
|
||||||
|
tv5Min.setOnClickListener(this)
|
||||||
|
|
||||||
|
setSelected(tvOff)
|
||||||
|
}
|
||||||
|
fun showDown(view: View) {
|
||||||
|
val location = IntArray(2)
|
||||||
|
view.getLocationOnScreen(location)
|
||||||
|
|
||||||
|
val x = location[0]
|
||||||
|
val y = location[1]
|
||||||
|
val popupHeight = popupWindow.height
|
||||||
|
|
||||||
|
Log.d("-------------", "--------x=$x---y=$y----popupHeight=$popupHeight")
|
||||||
|
popupWindow.showAsDropDown(
|
||||||
|
view, 50,
|
||||||
|
20,
|
||||||
|
Gravity.NO_GRAVITY
|
||||||
|
)
|
||||||
|
}
|
||||||
|
fun hidePop() {
|
||||||
|
popupWindow.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOffSelected() {
|
||||||
|
setSelected(tvOff)
|
||||||
|
}
|
||||||
|
private fun setSelected(tv: TextView) {
|
||||||
|
val childCount: Int = linearLayoutTimer.size
|
||||||
|
for (i in 0..<childCount) {
|
||||||
|
val child: View = linearLayoutTimer.getChildAt(i)
|
||||||
|
if (child is TextView) {
|
||||||
|
val tvTimer: TextView = child as TextView
|
||||||
|
if (tvTimer == tv) {
|
||||||
|
tvTimer.setSelected(true)
|
||||||
|
} else {
|
||||||
|
tvTimer.setSelected(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?) {
|
||||||
|
if (v is TextView) {
|
||||||
|
val v1: TextView = v
|
||||||
|
val string: String = v1.getText().toString()
|
||||||
|
when (string) {
|
||||||
|
"off" -> onClickTimer(-1)
|
||||||
|
"15 sec" -> onClickTimer(15 * 1000L)
|
||||||
|
"30 sec" -> onClickTimer(30 * 1000L)
|
||||||
|
"1 min" -> onClickTimer(60 * 1000L)
|
||||||
|
"5 min" -> onClickTimer(5 * 60 * 1000L)
|
||||||
|
}
|
||||||
|
setSelected(v1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.prank.funky.voice.utils.RecyclerSpace
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import com.prank.funky.voice.objectBox.DbBaseFunction
|
||||||
|
import com.prank.funky.voice.playSounds.PlaySoundsActivity
|
||||||
|
|
||||||
|
class CustomActivity : AppCompatActivity() {
|
||||||
|
private lateinit var tvImport: TextView
|
||||||
|
private lateinit var tvRecording: TextView
|
||||||
|
private lateinit var recyclerViewCustom: RecyclerView
|
||||||
|
|
||||||
|
private lateinit var importManager: ImportManager
|
||||||
|
private var saveSoundsDialog: SaveSoundsDialog? = null
|
||||||
|
private lateinit var customAdapter: CustomAdapter
|
||||||
|
|
||||||
|
private lateinit var recordManager: RecordManager
|
||||||
|
private lateinit var emptyLayout: LinearLayout
|
||||||
|
private var importSoundsUri: Uri? = null
|
||||||
|
|
||||||
|
private val mLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result ->
|
||||||
|
if (result.resultCode == RESULT_OK) {
|
||||||
|
val data = result.data
|
||||||
|
val value = data?.getBooleanExtra(KEY_SAVE_SOUNDS_OK, false)
|
||||||
|
if (value == true) {
|
||||||
|
queryCustomData()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
companion object{
|
||||||
|
val KEY_SAVE_SOUNDS_OK="save_sounds_ok"
|
||||||
|
}
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_custom)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
tvImport = findViewById(R.id.text_import)
|
||||||
|
tvRecording = findViewById(R.id.text_recording)
|
||||||
|
recyclerViewCustom = findViewById(R.id.custom_recyclerview)
|
||||||
|
emptyLayout = findViewById(R.id.empty_custom)
|
||||||
|
|
||||||
|
|
||||||
|
importManager = ImportManager(this) { localUri, oldName ->
|
||||||
|
Util.showLog("-----选择-- -$localUri")
|
||||||
|
importSoundsUri = localUri
|
||||||
|
showSaveDialog(oldName)
|
||||||
|
|
||||||
|
}
|
||||||
|
importManager.registerLaunchers()
|
||||||
|
|
||||||
|
recordManager = RecordManager(this@CustomActivity){
|
||||||
|
mLauncher.launch(Intent(this@CustomActivity, RecordSoundsActivity::class.java))
|
||||||
|
}
|
||||||
|
recordManager.registerLaunchers()
|
||||||
|
|
||||||
|
recyclerViewCustom.run {
|
||||||
|
val itemHelper = RecyclerSpace(5, 5, 3)
|
||||||
|
addItemDecoration(itemHelper)
|
||||||
|
setLayoutManager(GridLayoutManager(this@CustomActivity, 3))
|
||||||
|
customAdapter = CustomAdapter(this@CustomActivity) { data, soundsIndex ->
|
||||||
|
startActivity(Intent(this@CustomActivity, PlaySoundsActivity::class.java).apply {
|
||||||
|
putExtra(PlaySoundsActivity.Companion.KEY_SOUNDS_DETAIL_DATA, data)
|
||||||
|
putExtra(PlaySoundsActivity.Companion.KEY_SOUNDS_DETAIL_INDEX, soundsIndex)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
queryCustomData()
|
||||||
|
setAdapter(customAdapter)
|
||||||
|
}
|
||||||
|
setAllClick()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun queryCustomData() {
|
||||||
|
val allCustom = DbBaseFunction.getAllCustomization()
|
||||||
|
Util.showLog("-----Custom---=${allCustom.size}")
|
||||||
|
showCustomEmptyView(allCustom.isEmpty())
|
||||||
|
customAdapter.updateData(allCustom)
|
||||||
|
}
|
||||||
|
private fun setAllClick() {
|
||||||
|
findViewById<FrameLayout?>(R.id.framelayout_back).setOnClickListener { finish() }
|
||||||
|
tvImport.setOnClickListener {
|
||||||
|
importManager.requestPermissionAndPick()
|
||||||
|
}
|
||||||
|
tvRecording.setOnClickListener {
|
||||||
|
recordManager.request()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSaveDialog(oldName: String? = "") {
|
||||||
|
saveSoundsDialog = saveSoundsDialog ?: SaveSoundsDialog{ newName->
|
||||||
|
importSoundsUri?.let { uri->
|
||||||
|
Util.copyFileFromLocalUri(this@CustomActivity, uri)?.let{ path->
|
||||||
|
Util.saveSoundsDb(this@CustomActivity,path,newName){ ok->
|
||||||
|
if(ok){
|
||||||
|
queryCustomData()
|
||||||
|
Util.showLog("-------save-----ok--${newName}")
|
||||||
|
Toast.makeText(this@CustomActivity,getString(R.string.save_audio_ok),Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
saveSoundsDialog?.dismiss()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oldName != null) {
|
||||||
|
saveSoundsDialog?.updateDefaultName(oldName)
|
||||||
|
}
|
||||||
|
saveSoundsDialog?.show(supportFragmentManager, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showCustomEmptyView(isEmpty: Boolean) {
|
||||||
|
emptyLayout.isVisible = isEmpty
|
||||||
|
recyclerViewCustom.isVisible = !isEmpty
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.prank.funky.voice.utils.BaseAdapter
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySoundsDetail
|
||||||
|
import com.prank.funky.voice.databinding.CustomAudioAdapterBinding
|
||||||
|
|
||||||
|
class CustomAdapter(
|
||||||
|
context: Context,
|
||||||
|
var onClickIntent: (sounds: EntitySoundsDetail, soundsIndex: Int) -> Unit
|
||||||
|
) :
|
||||||
|
BaseAdapter<EntitySoundsDetail, CustomAudioAdapterBinding>(context) {
|
||||||
|
override fun getViewBinding(parent: ViewGroup?): CustomAudioAdapterBinding {
|
||||||
|
return CustomAudioAdapterBinding.inflate(
|
||||||
|
LayoutInflater.from(parent?.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val itemHolder = holder as VHolder<CustomAudioAdapterBinding>
|
||||||
|
val entitySoundsDetail: EntitySoundsDetail = data[position]
|
||||||
|
|
||||||
|
itemHolder.vb.run {
|
||||||
|
if(position == data.size-1){
|
||||||
|
bottomPlaceholder.visibility = View.VISIBLE
|
||||||
|
}else{
|
||||||
|
bottomPlaceholder.visibility = View.GONE
|
||||||
|
}
|
||||||
|
entitySoundsDetail.run {
|
||||||
|
textView.text = entitySoundsDetail.name
|
||||||
|
root.setOnClickListener {
|
||||||
|
onClickIntent(entitySoundsDetail, colorIndex)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,106 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.DocumentsContract
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
|
|
||||||
|
class ImportManager(
|
||||||
|
private val activity: Activity,
|
||||||
|
private val onAudioPicked: (Uri,String) -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
|
private lateinit var permissionLauncher: ActivityResultLauncher<Array<String>>
|
||||||
|
private lateinit var audioPickerLauncher: ActivityResultLauncher<String>
|
||||||
|
|
||||||
|
fun registerLaunchers() {
|
||||||
|
// 文件选择器
|
||||||
|
audioPickerLauncher = (activity as ComponentActivity)
|
||||||
|
.registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
|
||||||
|
uri?.let {
|
||||||
|
val pair = getAudioInfoFromUri(activity, it)
|
||||||
|
onAudioPicked(pair.first,pair.second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限请求
|
||||||
|
permissionLauncher = (activity as ComponentActivity)
|
||||||
|
.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { result ->
|
||||||
|
if (result.values.all { it }) {
|
||||||
|
openAudioPicker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestPermissionAndPick() {
|
||||||
|
val permissions = when {
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
|
||||||
|
arrayOf(Manifest.permission.READ_MEDIA_AUDIO)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (permissions.all {
|
||||||
|
ContextCompat.checkSelfPermission(activity, it) == PackageManager.PERMISSION_GRANTED
|
||||||
|
}) {
|
||||||
|
openAudioPicker()
|
||||||
|
} else {
|
||||||
|
permissionLauncher.launch(permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openAudioPicker() {
|
||||||
|
audioPickerLauncher.launch("audio/*")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fun getAudioInfoFromUri(context: Context, uri: Uri): Pair<Uri,String> {
|
||||||
|
var queryUri = uri
|
||||||
|
|
||||||
|
// 处理 DocumentProvider 的 URI
|
||||||
|
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||||
|
val docId = DocumentsContract.getDocumentId(uri) // 例如 "audio:1000000683"
|
||||||
|
val split = docId.split(":")
|
||||||
|
if (split.size == 2 && split[0] == "audio") {
|
||||||
|
val id = split[1]
|
||||||
|
queryUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
||||||
|
.buildUpon()
|
||||||
|
.appendPath(id)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var title: String ="unknown"
|
||||||
|
var duration: Long? = null
|
||||||
|
|
||||||
|
val projection = arrayOf(
|
||||||
|
MediaStore.Audio.Media.TITLE,
|
||||||
|
MediaStore.Audio.Media.DURATION
|
||||||
|
)
|
||||||
|
|
||||||
|
context.contentResolver.query(queryUri, projection, null, null, null)?.use { cursor ->
|
||||||
|
if (cursor.moveToFirst()) {
|
||||||
|
title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE))
|
||||||
|
duration =
|
||||||
|
cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri to title
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.media.MediaRecorder
|
||||||
|
import android.os.Build
|
||||||
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
class RecordHelper(var context: Context) {
|
||||||
|
private var mediaRecorder: MediaRecorder? = null
|
||||||
|
private var tempFileName: String? = null
|
||||||
|
private var isRecording = false
|
||||||
|
|
||||||
|
init {
|
||||||
|
val dir = context.cacheDir
|
||||||
|
val file = File(dir, "temp_audio.mp3")
|
||||||
|
tempFileName = file.absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getRecordStatus() = isRecording
|
||||||
|
fun startRecording() {
|
||||||
|
if (isRecording) return
|
||||||
|
mediaRecorder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
MediaRecorder(context)
|
||||||
|
} else {
|
||||||
|
MediaRecorder() // 旧版本依然可用
|
||||||
|
}
|
||||||
|
mediaRecorder?.run {
|
||||||
|
setAudioSource(MediaRecorder.AudioSource.MIC)
|
||||||
|
setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
|
||||||
|
setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
|
||||||
|
setOutputFile(tempFileName)
|
||||||
|
try {
|
||||||
|
prepare()
|
||||||
|
start()
|
||||||
|
isRecording = true
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stopRecording() {
|
||||||
|
if (!isRecording) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
mediaRecorder?.stop()
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
mediaRecorder?.release()
|
||||||
|
mediaRecorder = null
|
||||||
|
isRecording = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTempPath(): String? {
|
||||||
|
return tempFileName
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.result.ActivityResultCallback
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
|
class RecordManager(private val activity: Activity, var startRecord:()->Unit) {
|
||||||
|
private var requestRecordAudioLauncher: ActivityResultLauncher<String>? = null
|
||||||
|
fun registerLaunchers() {
|
||||||
|
requestRecordAudioLauncher =
|
||||||
|
(activity as ComponentActivity).registerForActivityResult<String, Boolean>(
|
||||||
|
RequestPermission(),
|
||||||
|
ActivityResultCallback<Boolean> { isGranted: Boolean ->
|
||||||
|
if (isGranted) {
|
||||||
|
startRecord()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
activity,
|
||||||
|
"Recording permission denied",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun request() {
|
||||||
|
val permissions = Manifest.permission.RECORD_AUDIO
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, permissions)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
requestRecordAudioLauncher!!.launch(permissions)
|
||||||
|
} else {
|
||||||
|
startRecord()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.SystemClock
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import com.prank.funky.voice.playSounds.CustomerRippleView
|
||||||
|
|
||||||
|
class RecordSoundsActivity : AppCompatActivity() {
|
||||||
|
private lateinit var tvStart: TextView
|
||||||
|
private lateinit var recordTime: TextView
|
||||||
|
private lateinit var customerRippleView: CustomerRippleView
|
||||||
|
private var record: RecordHelper? = null
|
||||||
|
|
||||||
|
private var startTime: Long = 0
|
||||||
|
private var elapsedTime: Long = 0
|
||||||
|
private var handler: Handler? = null
|
||||||
|
private var runnable: Runnable? = null
|
||||||
|
|
||||||
|
private var saveSoundsDialog: SaveSoundsDialog? = null
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_record)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
findViewById<FrameLayout>(R.id.frame_back).setOnClickListener {
|
||||||
|
backIntent(false)
|
||||||
|
}
|
||||||
|
tvStart = findViewById(R.id.text_start)
|
||||||
|
recordTime = findViewById(R.id.record_time)
|
||||||
|
customerRippleView = findViewById(R.id.rippleView)
|
||||||
|
customerRippleView.run {
|
||||||
|
setColor(getColor(R.color.color_DCC8FF))
|
||||||
|
setMaxRadius(120F)
|
||||||
|
}
|
||||||
|
handler = Handler(mainLooper)
|
||||||
|
setAllClick()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setAllClick() {
|
||||||
|
tvStart.setOnClickListener {
|
||||||
|
if (record?.getRecordStatus() == true) {
|
||||||
|
stopRecord()
|
||||||
|
} else {
|
||||||
|
startRecord()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startRecord() {
|
||||||
|
tvStart.text = getString(R.string.stop)
|
||||||
|
record = record ?: RecordHelper(this@RecordSoundsActivity)
|
||||||
|
record?.startRecording()
|
||||||
|
customerRippleView.startRipple()
|
||||||
|
runnable = runnable ?: object : Runnable {
|
||||||
|
@SuppressLint("DefaultLocale")
|
||||||
|
override fun run() {
|
||||||
|
val currentTime = SystemClock.elapsedRealtime()
|
||||||
|
elapsedTime = currentTime - startTime
|
||||||
|
val milliseconds = (elapsedTime % 1000).toInt() / 10
|
||||||
|
val seconds = (elapsedTime / 1000).toInt() % 60
|
||||||
|
val minutes = (elapsedTime / (1000 * 60)).toInt() % 60
|
||||||
|
recordTime.text = String.format(
|
||||||
|
"%02d : %02d : %02d",
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
milliseconds
|
||||||
|
)
|
||||||
|
handler?.postDelayed(this, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startTime = SystemClock.elapsedRealtime()
|
||||||
|
handler?.post(runnable!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopRecord() {
|
||||||
|
record?.stopRecording()
|
||||||
|
customerRippleView.stopRipple()
|
||||||
|
handler?.removeCallbacks(runnable!!)
|
||||||
|
showSaveDialog()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showSaveDialog() {
|
||||||
|
saveSoundsDialog = saveSoundsDialog ?: SaveSoundsDialog({
|
||||||
|
backIntent(false)
|
||||||
|
}) { newName ->
|
||||||
|
record?.getTempPath()?.let {
|
||||||
|
Util.saveSoundsDb(this@RecordSoundsActivity, it, newName) { ok ->
|
||||||
|
if (ok) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@RecordSoundsActivity, getString(R.string.save_audio_ok),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
saveSoundsDialog?.dismiss()
|
||||||
|
backIntent(ok)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
saveSoundsDialog?.show(supportFragmentManager, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun backIntent(saveOk: Boolean) {
|
||||||
|
val intent = Intent().apply {
|
||||||
|
putExtra(CustomActivity.KEY_SAVE_SOUNDS_OK, saveOk)
|
||||||
|
}
|
||||||
|
setResult(RESULT_OK, intent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
record?.stopRecording()
|
||||||
|
customerRippleView.stopRipple()
|
||||||
|
runnable?.let {
|
||||||
|
handler?.removeCallbacks(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
package com.prank.funky.voice.recordSounds
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.prank.funky.voice.objectBox.DbBaseFunction
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
|
||||||
|
class SaveSoundsDialog(var clickCancel: (() -> Unit)? = null, var clickSave: (newName: String) -> Unit) : DialogFragment() {
|
||||||
|
|
||||||
|
private lateinit var et: EditText
|
||||||
|
private lateinit var cancel: TextView
|
||||||
|
private lateinit var save: TextView
|
||||||
|
private var oleName: String? = null
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
|
||||||
|
val view = inflater.inflate(R.layout.dialog_save_audio, container, false)
|
||||||
|
et = view.findViewById(R.id.edit_name)
|
||||||
|
cancel = view.findViewById(R.id.text_cancel)
|
||||||
|
save = view.findViewById(R.id.text_save)
|
||||||
|
oleName?.let { et.setText(it) }
|
||||||
|
init()
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDefaultName(oldName: String) {
|
||||||
|
oleName = oldName
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun init() {
|
||||||
|
|
||||||
|
dialog?.run {
|
||||||
|
val window = dialog!!.window
|
||||||
|
window!!.setBackgroundDrawableResource(R.color.color_transparent)
|
||||||
|
window.decorView.setPadding(0, 0, 0, 0)
|
||||||
|
val wlp = window.attributes
|
||||||
|
wlp.gravity = Gravity.CENTER
|
||||||
|
wlp.width = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
|
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
|
window.attributes = wlp
|
||||||
|
|
||||||
|
setCancelable(false)
|
||||||
|
setCanceledOnTouchOutside(false)
|
||||||
|
save.setOnClickListener {
|
||||||
|
val name: String = et.text.toString().trim()
|
||||||
|
val checkName = DbBaseFunction.checkName(name)
|
||||||
|
if(!checkName){
|
||||||
|
requireContext().let {
|
||||||
|
Toast.makeText(
|
||||||
|
it,
|
||||||
|
getString(R.string.name_repeat),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
clickSave(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
cancel.setOnClickListener {
|
||||||
|
dismiss()
|
||||||
|
clickCancel?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
package com.prank.funky.voice.soundsList
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
import com.prank.funky.voice.utils.RecyclerSpace
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySounds
|
||||||
|
import com.prank.funky.voice.playSounds.PlaySoundsActivity
|
||||||
|
|
||||||
|
class ListActivity : AppCompatActivity() {
|
||||||
|
private lateinit var textViewTitle: TextView
|
||||||
|
private lateinit var recyclerView: RecyclerView
|
||||||
|
|
||||||
|
private var soundsIndex:Int = 0
|
||||||
|
private var soundData: EntitySounds? = null
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val KEY_SOUNDS_INDEX = "color_index"
|
||||||
|
val KEY_SOUNDS_DATA = "sounds_data"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_list)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
|
findViewById<FrameLayout>(R.id.framelayout_back).setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
textViewTitle = findViewById(R.id.text_title)
|
||||||
|
recyclerView = findViewById(R.id.sounds_list_recyclerview)
|
||||||
|
soundsIndex = intent.getIntExtra(KEY_SOUNDS_INDEX, 0)
|
||||||
|
|
||||||
|
|
||||||
|
soundData = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
intent.getSerializableExtra(KEY_SOUNDS_DATA, EntitySounds::class.java)
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
intent.getSerializableExtra(KEY_SOUNDS_DATA) as? EntitySounds
|
||||||
|
}
|
||||||
|
soundData?.run {
|
||||||
|
textViewTitle.text = name
|
||||||
|
recyclerView.run {
|
||||||
|
val itemHelper = RecyclerSpace(5, 5, 3)
|
||||||
|
addItemDecoration(itemHelper)
|
||||||
|
setLayoutManager(GridLayoutManager(this@ListActivity, 3))
|
||||||
|
setAdapter(ListAdapter(this@ListActivity,soundsIndex){ data, soundsIndex->
|
||||||
|
startActivity(Intent(this@ListActivity, PlaySoundsActivity::class.java).apply {
|
||||||
|
putExtra(PlaySoundsActivity.Companion.KEY_SOUNDS_DETAIL_DATA,data)
|
||||||
|
putExtra(PlaySoundsActivity.Companion.KEY_SOUNDS_DETAIL_INDEX,soundsIndex)
|
||||||
|
})
|
||||||
|
|
||||||
|
}.apply {
|
||||||
|
Util.showLog("---list-----updateData")
|
||||||
|
updateData(entitySoundsDetailList)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.prank.funky.voice.soundsList
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.prank.funky.voice.databinding.ListAdapterBinding
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySoundsDetail
|
||||||
|
import com.prank.funky.voice.utils.BaseAdapter
|
||||||
|
import com.prank.funky.voice.utils.Util
|
||||||
|
|
||||||
|
class ListAdapter(context: Context, var soundsIndex:Int, var onClickIntent: (sounds: EntitySoundsDetail, soundsIndex:Int) -> Unit) :
|
||||||
|
BaseAdapter<EntitySoundsDetail, ListAdapterBinding>(context) {
|
||||||
|
override fun getViewBinding(parent: ViewGroup?): ListAdapterBinding {
|
||||||
|
return ListAdapterBinding.inflate(
|
||||||
|
LayoutInflater.from(parent?.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
val itemHolder = holder as VHolder<ListAdapterBinding>
|
||||||
|
|
||||||
|
itemHolder.vb.run {
|
||||||
|
root.background = ContextCompat.getDrawable(mContext, Util.mainBgs[soundsIndex])
|
||||||
|
val entitySoundsDetail: EntitySoundsDetail = data[position]
|
||||||
|
val covert: String = entitySoundsDetail.covert.toString()
|
||||||
|
Glide.with(mContext).load(covert).into(imageView)
|
||||||
|
textView.text = entitySoundsDetail.name
|
||||||
|
root.setOnClickListener {
|
||||||
|
onClickIntent(entitySoundsDetail, soundsIndex)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
50
app/src/main/java/com/prank/funky/voice/utils/BaseAdapter.kt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package com.prank.funky.voice.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
|
||||||
|
abstract class BaseAdapter<K, T : ViewBinding?>(protected var mContext: Context) :
|
||||||
|
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
protected var data: MutableList<K> = ArrayList()
|
||||||
|
|
||||||
|
var isLoadingAdded = false
|
||||||
|
protected set
|
||||||
|
|
||||||
|
|
||||||
|
fun addData(data: List<K>?) {
|
||||||
|
this.data.addAll(data!!)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateData(data: List<K>?) {
|
||||||
|
this.data.clear()
|
||||||
|
this.data.addAll(data!!)
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val viewBinding = getViewBinding(parent)
|
||||||
|
return VHolder(viewBinding)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun getViewBinding(parent: ViewGroup?): T
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return if (position == data.size && isLoadingAdded) TYPE_FOOTER else TYPE_ITEM
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return data.size + if (isLoadingAdded) 1 else 0
|
||||||
|
}
|
||||||
|
|
||||||
|
class VHolder<V : ViewBinding?>(val vb: V) : RecyclerView.ViewHolder(
|
||||||
|
vb!!.root
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
protected const val TYPE_ITEM = 0
|
||||||
|
protected const val TYPE_FOOTER = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
package com.prank.funky.voice.utils
|
||||||
|
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
|
||||||
|
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||||
|
import com.prank.funky.voice.App
|
||||||
|
|
||||||
|
|
||||||
|
class RecyclerSpace(v: Int, h: Int, ex: Int) : ItemDecoration() {
|
||||||
|
private val v: Int
|
||||||
|
private val h: Int
|
||||||
|
private val ex: Int
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.v = Math.round(dpToPx(v.toFloat()))
|
||||||
|
this.h = Math.round(dpToPx(h.toFloat()))
|
||||||
|
this.ex = Math.round(dpToPx(ex.toFloat()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemOffsets(
|
||||||
|
outRect: Rect,
|
||||||
|
view: View,
|
||||||
|
parent: RecyclerView,
|
||||||
|
state: RecyclerView.State
|
||||||
|
) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state)
|
||||||
|
var spanCount = 1
|
||||||
|
var spanSize = 1
|
||||||
|
var spanIndex = 0
|
||||||
|
|
||||||
|
val childAdapterPosition = parent.getChildAdapterPosition(view)
|
||||||
|
val layoutManager = parent.layoutManager
|
||||||
|
if (layoutManager is StaggeredGridLayoutManager) {
|
||||||
|
val layoutParams = view.layoutParams as StaggeredGridLayoutManager.LayoutParams
|
||||||
|
spanCount = layoutManager.spanCount
|
||||||
|
if (layoutParams.isFullSpan) {
|
||||||
|
spanSize = spanCount
|
||||||
|
}
|
||||||
|
spanIndex = layoutParams.spanIndex
|
||||||
|
} else if (layoutManager is GridLayoutManager) {
|
||||||
|
val gridLayoutManager = layoutManager
|
||||||
|
val layoutParams = view.layoutParams as GridLayoutManager.LayoutParams
|
||||||
|
spanCount = gridLayoutManager.spanCount
|
||||||
|
spanSize = gridLayoutManager.spanSizeLookup.getSpanSize(childAdapterPosition)
|
||||||
|
spanIndex = layoutParams.spanIndex
|
||||||
|
} else if (layoutManager is LinearLayoutManager) {
|
||||||
|
outRect.left = v
|
||||||
|
outRect.right = v
|
||||||
|
outRect.bottom = h
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spanSize == spanCount) {
|
||||||
|
outRect.left = v + ex
|
||||||
|
outRect.right = v + ex
|
||||||
|
outRect.bottom = h
|
||||||
|
} else {
|
||||||
|
val itemAllSpacing = (v * (spanCount + 1) + ex * 2) / spanCount
|
||||||
|
val left = v * (spanIndex + 1) - itemAllSpacing * spanIndex + ex
|
||||||
|
val right = itemAllSpacing - left
|
||||||
|
outRect.left = left
|
||||||
|
outRect.right = right
|
||||||
|
outRect.bottom = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun dpToPx(dpValue: Float): Float {
|
||||||
|
val density: Float = App.Companion.mApp.resources.displayMetrics.density
|
||||||
|
return density * dpValue + 0.5f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
187
app/src/main/java/com/prank/funky/voice/utils/Util.kt
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
package com.prank.funky.voice.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.media.AudioManager
|
||||||
|
import android.net.Uri
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.SeekBar
|
||||||
|
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.prank.funky.voice.objectBox.DbBaseFunction
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySounds
|
||||||
|
import com.prank.funky.voice.objectBox.EntitySoundsDetail
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONException
|
||||||
|
import java.io.BufferedReader
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.io.StringWriter
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import com.prank.funky.voice.App
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
|
||||||
|
object Util {
|
||||||
|
|
||||||
|
val mainBgs: IntArray = intArrayOf(
|
||||||
|
R.drawable.bg_main_shape1,
|
||||||
|
R.drawable.bg_main_shape2,
|
||||||
|
R.drawable.bg_main_shape3,
|
||||||
|
R.drawable.bg_main_shape4
|
||||||
|
)
|
||||||
|
|
||||||
|
fun getString(input: InputStream): String {
|
||||||
|
try {
|
||||||
|
val charArray = CharArray(input.available())
|
||||||
|
var count = 0
|
||||||
|
val stringWriter = StringWriter()
|
||||||
|
val inputStreamReader = InputStreamReader(input)
|
||||||
|
val bufferedReader = BufferedReader(inputStreamReader)
|
||||||
|
while ((bufferedReader.read(charArray).also { count = it }) != -1) {
|
||||||
|
stringWriter.write(charArray, 0, count)
|
||||||
|
}
|
||||||
|
return stringWriter.toString()
|
||||||
|
} catch (exception: IOException) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBean(str: String?): List<EntitySounds>? {
|
||||||
|
try {
|
||||||
|
val data: MutableList<EntitySounds> = ArrayList<EntitySounds>()
|
||||||
|
val jsonArray = JSONArray(str)
|
||||||
|
|
||||||
|
for (i in 0..<jsonArray.length()) {
|
||||||
|
val jsonObject = jsonArray.getJSONObject(i)
|
||||||
|
val listArray = jsonObject.getJSONArray("list")
|
||||||
|
val list: MutableList<EntitySoundsDetail> = ArrayList<EntitySoundsDetail>()
|
||||||
|
for (k in 0..<listArray.length()) {
|
||||||
|
val listBean = listArray.getJSONObject(k)
|
||||||
|
list.add(EntitySoundsDetail().apply {
|
||||||
|
soundsPath = listBean.getString("mp3Url")
|
||||||
|
covert = listBean.getString("preUrl")
|
||||||
|
name = listBean.getString("title")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
data.add(EntitySounds().apply {
|
||||||
|
covert = jsonObject.getString("categoryUrl")
|
||||||
|
entitySoundsDetailList = list
|
||||||
|
name = jsonObject.getString("categoryName")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
} catch (jo: JSONException) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showLog(msg: String) {
|
||||||
|
Log.d(App.Companion.TAG, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun syncCurrentVolume(context: Context, seekBar: SeekBar) {
|
||||||
|
val audioManager = context.getSystemService(AppCompatActivity.AUDIO_SERVICE) as AudioManager
|
||||||
|
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||||
|
seekBar.max = maxVolume
|
||||||
|
seekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||||
|
seekBar.setOnSeekBarChangeListener(object : OnSeekBarChangeListener {
|
||||||
|
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyFileFromLocalUri(context: Context, uri: Uri): String? {
|
||||||
|
val contentResolver = context.contentResolver
|
||||||
|
try {
|
||||||
|
contentResolver.openInputStream(uri).use { inputStream ->
|
||||||
|
FileOutputStream(
|
||||||
|
File(
|
||||||
|
context.cacheDir,
|
||||||
|
"temp_audio_file.mp3"
|
||||||
|
)
|
||||||
|
).use { outputStream ->
|
||||||
|
if (inputStream == null) {
|
||||||
|
Log.e("SaveActivity", "Input stream is null")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
var bytesRead: Int
|
||||||
|
while ((inputStream!!.read(buffer).also { bytesRead = it }) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead)
|
||||||
|
}
|
||||||
|
return File(context.cacheDir, "temp_audio_file.mp3").absolutePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Log.e("SaveActivity", "Error reading file from URI", e)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存导入的音频
|
||||||
|
*/
|
||||||
|
fun saveSoundsDb(
|
||||||
|
context: Context,
|
||||||
|
entitySoundsDetail: EntitySoundsDetail,
|
||||||
|
newName: String,
|
||||||
|
saveResult: (ok: Boolean) -> Unit
|
||||||
|
) {
|
||||||
|
entitySoundsDetail.soundsPath?.let { uri ->
|
||||||
|
copyFileFromLocalUri(context, uri.toUri())?.let { cachePath ->
|
||||||
|
val cacheDir: File = context.cacheDir
|
||||||
|
val sourceFile: File = File(cachePath)
|
||||||
|
val destinationFile = File(cacheDir, "$newName.mp3")
|
||||||
|
if (sourceFile.renameTo(destinationFile)) {
|
||||||
|
DbBaseFunction.getSoundsBox()
|
||||||
|
.put(entitySoundsDetail.apply { soundsPath = destinationFile.absolutePath })
|
||||||
|
saveResult(true)
|
||||||
|
showLog("-------save-------${newName}")
|
||||||
|
} else {
|
||||||
|
saveResult(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
} ?: saveResult(false)
|
||||||
|
} ?: saveResult(false)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun saveSoundsDb(
|
||||||
|
context: Context,
|
||||||
|
fileCachePath: String,
|
||||||
|
newName: String,
|
||||||
|
saveResult: (ok: Boolean) -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
|
val sourceFile: File = File(fileCachePath)
|
||||||
|
val destinationFile = File(context.cacheDir, "$newName.mp3")
|
||||||
|
if (sourceFile.renameTo(destinationFile)) {
|
||||||
|
DbBaseFunction.getSoundsBox().put( EntitySoundsDetail().apply {
|
||||||
|
soundsPath = destinationFile.absolutePath
|
||||||
|
isCustomization = true
|
||||||
|
isLike = false
|
||||||
|
name =newName
|
||||||
|
})
|
||||||
|
saveResult(true)
|
||||||
|
showLog("-------save-------${newName} ${destinationFile.absolutePath}")
|
||||||
|
} else {
|
||||||
|
saveResult(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.prank.funky.voice.welcome
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.widget.ProgressBar
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import com.prank.funky.voice.home.HomeActivity
|
||||||
|
import com.prank.funky.voice.R
|
||||||
|
|
||||||
|
class WelcomeActivity : AppCompatActivity() {
|
||||||
|
private lateinit var pb: ProgressBar
|
||||||
|
private lateinit var tv_progress: TextView
|
||||||
|
private val count = 2000L
|
||||||
|
private var countDownTimer:CountDownTimer? = null
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(R.layout.activity_welcome)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
|
pb = findViewById(R.id.load_pb)
|
||||||
|
tv_progress = findViewById(R.id.text_progress)
|
||||||
|
|
||||||
|
countDownTimer = object : CountDownTimer(count,100){
|
||||||
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
val progressPercentage: Int = ((100 * millisUntilFinished) / count).toInt()
|
||||||
|
val progressInt = 100 - progressPercentage
|
||||||
|
tv_progress.text = getString(R.string.welcome_progress, progressInt)
|
||||||
|
pb.progress = progressInt
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinish() {
|
||||||
|
tv_progress.text = getString(R.string.welcome_progress, 100)
|
||||||
|
pb.progress = 100
|
||||||
|
startActivity(Intent(this@WelcomeActivity, HomeActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
countDownTimer?.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
countDownTimer?.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="@color/gray_color" android:state_selected="false"/>
|
||||||
|
<item android:color="@color/white" android:state_selected="true"/>
|
||||||
|
</selector>
|
||||||
@ -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/black" android:width="1dp"/>
|
||||||
|
</shape>
|
||||||
@ -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="15dp" />
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
</shape>
|
||||||
6
app/src/main/res/drawable/bg_main_shape1.xml
Normal 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="15dp" />
|
||||||
|
<solid android:color="@color/main_color1" />
|
||||||
|
</shape>
|
||||||
6
app/src/main/res/drawable/bg_main_shape2.xml
Normal 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="15dp" />
|
||||||
|
<solid android:color="@color/main_color2" />
|
||||||
|
</shape>
|
||||||
6
app/src/main/res/drawable/bg_main_shape3.xml
Normal 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="15dp" />
|
||||||
|
<solid android:color="@color/main_color3" />
|
||||||
|
</shape>
|
||||||
6
app/src/main/res/drawable/bg_main_shape4.xml
Normal 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="15dp" />
|
||||||
|
<solid android:color="@color/main_color4" />
|
||||||
|
</shape>
|
||||||
20
app/src/main/res/drawable/bg_main_stoke_bg.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
<solid android:color="@color/main_color2" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_pressed="false">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
<gradient android:startColor="@color/main_color1"
|
||||||
|
android:endColor="@color/main_color5"
|
||||||
|
android:angle="135"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
|
||||||
|
|
||||||
6
app/src/main/res/drawable/bg_playsounds_oval1.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/color_95FFFFFF"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
30
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal 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>
|
||||||
9
app/src/main/res/drawable/icon_back_black.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M395.2,513.6l323.1,-312.4c19.1,-18.4 19.1,-48.3 0,-66.7 -19.1,-18.4 -49.9,-18.4 -69,0L291.8,480.3c-19.1,18.4 -19.1,48.3 0,66.7l357.6,345.7c9.5,9.2 22,13.8 34.5,13.8 12.5,0 25,-4.6 34.5,-13.8 19.1,-18.4 19.1,-48.2 0,-66.7L395.2,513.6z"
|
||||||
|
android:fillColor="@color/black"/>
|
||||||
|
</vector>
|
||||||
15
app/src/main/res/drawable/icon_favorite.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M510.4,298.9C394.7,30.2 65.6,92.9 63.4,404.8c-1.3,180.3 434.6,455.2 447.7,499.8 11.9,-46.3 448,-322.6 446.7,-501.7 -2.2,-312.7 -337,-362.1 -447.4,-104z"
|
||||||
|
android:fillColor="@color/main_colorE61B1B"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M425.2,824.7c39.9,47.1 82.4,67.9 86,80 11.9,-46.3 448,-322.6 446.7,-501.7 -0.7,-101 -36.1,-174.5 -87.4,-219C762.9,90.4 275.6,538.5 425.2,824.7z"
|
||||||
|
android:fillColor="@color/main_colorE61B1B"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M511.1,904.6c8.6,-47 448,-322.6 446.7,-501.7 -0.3,-50.5 -9.4,-94.1 -24.7,-130.7S355.8,729.6 511.1,904.6z"
|
||||||
|
android:fillColor="@color/main_colorE61B1B"/>
|
||||||
|
</vector>
|
||||||
15
app/src/main/res/drawable/icon_music.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<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="M137.2,2.9c-12.8,0 -26.3,5.1 -35.7,15.3a54.1,54.1 0,0 0,-15.3 35.7v918.2c0,12.8 5.1,26.3 15.3,35.7 10.2,10.2 22.9,15.3 35.7,15.3h748.2c12.7,0 26.3,-5.1 35.7,-15.3 9.7,-9.4 15.2,-22.2 15.3,-35.7L936.4,292L647.3,2.9h-510.1zM137.2,2.9"
|
||||||
|
android:fillColor="#B27FF5"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M935.7,292L697.6,292c-12.8,0 -26.4,-5.1 -35.7,-15.3A49,49 0,0 1,646.6 241L646.6,3L935.7,292zM935.7,292"
|
||||||
|
android:fillColor="#DCC8FF"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M671.4,300.9l-215.4,66c-26.2,7.6 -47.1,34.8 -47.1,60.7v226.9s-15.7,-10.5 -50.4,-5.5c-51.2,7.3 -92.5,46.4 -92.5,87.4 0,41.1 41.3,66.3 92.5,59 51.2,-7.4 88.4,-45.2 88.4,-86.2L447,490.1c0,-18.1 21.9,-26 21.9,-26l190.5,-59.7s21.1,-7.1 21.1,12.3v180.8s-19.4,-11 -54.2,-7.1c-51.2,6.3 -92.4,44.6 -92.4,85.7 0,41 41.3,66.9 92.4,60.9 51.2,-6.3 92.5,-44.5 92.5,-85.6L718.8,334.4c-0.2,-25.7 -21.4,-40.8 -47.4,-33.5zM671.4,300.9"
|
||||||
|
android:fillColor="#FFFFFF"/>
|
||||||
|
</vector>
|
||||||
15
app/src/main/res/drawable/icon_playsounds_collection.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M510.4,298.9C394.7,30.2 65.6,92.9 63.4,404.8c-1.3,180.3 434.6,455.2 447.7,499.8 11.9,-46.3 448,-322.6 446.7,-501.7 -2.2,-312.7 -337,-362.1 -447.4,-104z"
|
||||||
|
android:fillColor="@color/gray_color"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M425.2,824.7c39.9,47.1 82.4,67.9 86,80 11.9,-46.3 448,-322.6 446.7,-501.7 -0.7,-101 -36.1,-174.5 -87.4,-219C762.9,90.4 275.6,538.5 425.2,824.7z"
|
||||||
|
android:fillColor="@color/gray_color"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M511.1,904.6c8.6,-47 448,-322.6 446.7,-501.7 -0.3,-50.5 -9.4,-94.1 -24.7,-130.7S355.8,729.6 511.1,904.6z"
|
||||||
|
android:fillColor="@color/gray_color"/>
|
||||||
|
</vector>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/white"
|
||||||
|
android:pathData="M512,64C264.6,64 64,264.6 64,512s200.6,448 448,448 448,-200.6 448,-448S759.4,64 512,64zM512,884c-205.4,0 -372,-166.6 -372,-372s166.6,-372 372,-372 372,166.6 372,372 -166.6,372 -372,372z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/white"
|
||||||
|
android:pathData="M686.7,638.6L544.1,535.5V288c0,-4.4 -3.6,-8 -8,-8H488c-4.4,0 -8,3.6 -8,8v275.4c0,2.6 1.2,5 3.3,6.5l165.4,120.6c3.6,2.6 8.6,1.8 11.2,-1.7l28.6,-39c2.6,-3.7 1.8,-8.7 -1.8,-11.2z"/>
|
||||||
|
</vector>
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray_color"
|
||||||
|
android:pathData="M512,64C264.6,64 64,264.6 64,512s200.6,448 448,448 448,-200.6 448,-448S759.4,64 512,64zM512,884c-205.4,0 -372,-166.6 -372,-372s166.6,-372 372,-372 372,166.6 372,372 -166.6,372 -372,372z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/gray_color"
|
||||||
|
android:pathData="M686.7,638.6L544.1,535.5V288c0,-4.4 -3.6,-8 -8,-8H488c-4.4,0 -8,3.6 -8,8v275.4c0,2.6 1.2,5 3.3,6.5l165.4,120.6c3.6,2.6 8.6,1.8 11.2,-1.7l28.6,-39c2.6,-3.7 1.8,-8.7 -1.8,-11.2z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_playsounds_loop_gray.xml
Normal 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/gray_color"
|
||||||
|
android:pathData="M199.7,583.7c15.4,-5.1 25.6,-20.5 20.5,-35.8 -5.1,-15.4 -5.1,-35.8 -5.1,-51.2 0,-102.4 87,-189.4 189.4,-189.4L665.6,307.2v51.2c0,15.4 10.2,20.5 25.6,15.4l117.8,-71.7c15.4,-10.2 15.4,-20.5 0,-30.7l-117.8,-76.8c-15.4,-15.4 -25.6,-10.2 -25.6,5.1v51.2L404.5,250.9c-66.6,0 -128,25.6 -174.1,71.7 -46.1,46.1 -71.7,107.5 -71.7,174.1 0,20.5 5.1,46.1 10.2,66.6 5.1,10.2 15.4,20.5 25.6,20.5h5.1zM199.7,583.7M844.8,409.6c-5.1,-10.2 -15.4,-20.5 -25.6,-20.5h-5.1c-15.4,5.1 -25.6,20.5 -20.5,35.8 5.1,15.4 5.1,35.8 5.1,51.2 0,107.5 -87,194.6 -194.6,194.6h-256v-51.2c0,-15.4 -10.2,-20.5 -25.6,-15.4L204.8,681c-15.4,10.2 -15.4,20.5 0,30.7l117.8,76.8c15.4,10.2 25.6,5.1 25.6,-15.4v-51.2h261.1c66.6,0 128,-25.6 174.1,-71.7 46.1,-46.1 71.7,-107.5 71.7,-174.1 0,-20.5 -5.1,-46.1 -10.2,-66.6zM844.8,409.6"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_playsounds_loop_light.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="64dp"
|
||||||
|
android:height="64dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/white"
|
||||||
|
android:pathData="M199.7,583.7c15.4,-5.1 25.6,-20.5 20.5,-35.8 -5.1,-15.4 -5.1,-35.8 -5.1,-51.2 0,-102.4 87,-189.4 189.4,-189.4L665.6,307.2v51.2c0,15.4 10.2,20.5 25.6,15.4l117.8,-71.7c15.4,-10.2 15.4,-20.5 0,-30.7l-117.8,-76.8c-15.4,-15.4 -25.6,-10.2 -25.6,5.1v51.2L404.5,250.9c-66.6,0 -128,25.6 -174.1,71.7 -46.1,46.1 -71.7,107.5 -71.7,174.1 0,20.5 5.1,46.1 10.2,66.6 5.1,10.2 15.4,20.5 25.6,20.5h5.1zM199.7,583.7M844.8,409.6c-5.1,-10.2 -15.4,-20.5 -25.6,-20.5h-5.1c-15.4,5.1 -25.6,20.5 -20.5,35.8 5.1,15.4 5.1,35.8 5.1,51.2 0,107.5 -87,194.6 -194.6,194.6h-256v-51.2c0,-15.4 -10.2,-20.5 -25.6,-15.4L204.8,681c-15.4,10.2 -15.4,20.5 0,30.7l117.8,76.8c15.4,10.2 25.6,5.1 25.6,-15.4v-51.2h261.1c66.6,0 128,-25.6 174.1,-71.7 46.1,-46.1 71.7,-107.5 71.7,-174.1 0,-20.5 -5.1,-46.1 -10.2,-66.6zM844.8,409.6"/>
|
||||||
|
</vector>
|
||||||
16
app/src/main/res/drawable/icon_playsounds_pause.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<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/black"
|
||||||
|
android:pathData="M512,42.7c258.8,0 469.3,210.5 469.3,469.3s-210.5,469.3 -469.3,469.3 -469.3,-210.5 -469.3,-469.3 210.5,-469.3 469.3,-469.3z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/white"
|
||||||
|
android:pathData="M384,312.9c31.3,0 56.9,25.6 56.9,56.9v284.4c0,31.3 -25.6,56.9 -56.9,56.9s-56.9,-25.6 -56.9,-56.9v-284.4c0,-31.3 25.6,-56.9 56.9,-56.9z"
|
||||||
|
android:strokeAlpha="0.6" />
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/white"
|
||||||
|
android:pathData="M640,312.9c31.3,0 56.9,25.6 56.9,56.9v284.4c0,31.3 -25.6,56.9 -56.9,56.9s-56.9,-25.6 -56.9,-56.9v-284.4c0,-31.3 25.6,-56.9 56.9,-56.9z" />
|
||||||
|
</vector>
|
||||||
8
app/src/main/res/drawable/icon_playsounds_pb_thumb.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/main_color4" />
|
||||||
|
<size
|
||||||
|
android:width="12dp"
|
||||||
|
android:height="12dp" />
|
||||||
|
</shape>
|
||||||
12
app/src/main/res/drawable/icon_playsounds_play.xml
Normal 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="M512.5,512m-418.9,0a418.9,418.9 0,1 0,837.7 0,418.9 418.9,0 1,0 -837.7,0Z"
|
||||||
|
android:fillColor="@color/black"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M683.6,470l-231.4,-133.6c-32.3,-18.6 -72.7,4.7 -72.7,42v267.2c0,37.3 40.4,60.6 72.7,42l231.4,-133.6c32.3,-18.7 32.3,-65.3 0,-84z"
|
||||||
|
android:fillColor="@color/white"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_playsounds_volum.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="21dp"
|
||||||
|
android:height="18dp"
|
||||||
|
android:viewportWidth="21"
|
||||||
|
android:viewportHeight="18">
|
||||||
|
<path
|
||||||
|
android:pathData="M1.5,3.996H3.27C3.742,3.997 4.199,3.83 4.56,3.526L8.25,0.396C8.493,0.19 8.789,0.058 9.105,0.015C9.42,-0.028 9.741,0.02 10.03,0.154C10.319,0.287 10.564,0.5 10.736,0.768C10.908,1.036 10.999,1.348 11,1.666V16.326C10.999,16.645 10.908,16.956 10.736,17.224C10.564,17.492 10.319,17.705 10.03,17.838C9.741,17.972 9.42,18.02 9.105,17.977C8.789,17.934 8.493,17.802 8.25,17.596L4.56,14.466C4.199,14.162 3.742,13.996 3.27,13.996H1.5C1.102,13.996 0.721,13.838 0.439,13.557C0.158,13.276 0,12.894 0,12.496V5.496C0,5.098 0.158,4.717 0.439,4.436C0.721,4.154 1.102,3.996 1.5,3.996ZM14.77,13.766C15.397,13.14 15.895,12.397 16.234,11.578C16.573,10.76 16.748,9.882 16.748,8.996C16.748,8.11 16.573,7.233 16.234,6.414C15.895,5.596 15.397,4.852 14.77,4.226C14.629,4.086 14.439,4.007 14.24,4.007C14.041,4.007 13.851,4.086 13.71,4.226C13.569,4.367 13.491,4.557 13.491,4.756C13.491,4.955 13.569,5.146 13.71,5.286C14.198,5.773 14.585,6.351 14.849,6.988C15.113,7.625 15.25,8.307 15.25,8.996C15.25,9.685 15.113,10.368 14.849,11.005C14.585,11.641 14.198,12.219 13.71,12.706C13.569,12.847 13.491,13.038 13.491,13.236C13.491,13.435 13.569,13.626 13.71,13.766C13.778,13.838 13.861,13.894 13.952,13.932C14.043,13.97 14.141,13.988 14.24,13.986C14.339,13.987 14.436,13.967 14.527,13.93C14.618,13.892 14.701,13.836 14.77,13.766ZM17.07,16.816C16.971,16.817 16.874,16.798 16.782,16.76C16.691,16.723 16.609,16.667 16.54,16.596C16.469,16.527 16.413,16.445 16.375,16.354C16.336,16.263 16.316,16.165 16.316,16.066C16.316,15.967 16.336,15.87 16.375,15.779C16.413,15.688 16.469,15.605 16.54,15.536C18.274,13.802 19.249,11.449 19.249,8.996C19.249,6.543 18.274,4.191 16.54,2.456C16.469,2.387 16.413,2.305 16.375,2.214C16.336,2.123 16.316,2.025 16.316,1.926C16.316,1.827 16.336,1.73 16.375,1.639C16.413,1.548 16.469,1.465 16.54,1.396C16.681,1.256 16.871,1.177 17.07,1.177C17.269,1.177 17.459,1.256 17.6,1.396C18.599,2.394 19.392,3.578 19.932,4.882C20.473,6.187 20.751,7.584 20.751,8.996C20.751,10.408 20.473,11.806 19.932,13.11C19.392,14.414 18.599,15.599 17.6,16.596C17.531,16.666 17.448,16.722 17.357,16.76C17.266,16.797 17.169,16.817 17.07,16.816Z"
|
||||||
|
android:fillColor="@color/black"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/icon_recorder.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="256dp"
|
||||||
|
android:height="256dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M512,683.5c130.6,0 235.5,-102.4 235.5,-233L747.5,256c0,-130.6 -105,-233 -235.5,-233s-235.5,102.4 -235.5,233v194.6c0,130.6 102.4,233 235.5,233zM880.6,401.9c0,-23 -20.5,-43.5 -46.1,-43.5s-43.5,20.5 -43.5,43.5c0,5.1 0,10.2 2.6,12.8v33.3c0,151 -125.4,276.5 -281.6,276.5 -153.6,0 -281.6,-125.4 -281.6,-276.5L230.4,409.6c0,-2.6 2.6,-5.1 2.6,-10.2 0,-23 -20.5,-43.5 -43.5,-43.5 -25.6,0 -43.5,20.5 -43.5,43.5v64c0,186.9 140.8,335.4 320,361v87h-122.9c-25.6,0 -46.1,20.5 -46.1,46.1s20.5,43.5 46.1,43.5h332.8c28.2,0 43.5,-17.9 43.5,-43.5 0,-23 -17.9,-46.1 -43.5,-46.1h-122.9v-87c184.3,-20.5 327.7,-174.1 327.7,-361v-61.4zM880.6,401.9"
|
||||||
|
android:fillColor="@color/white"/>
|
||||||
|
</vector>
|
||||||
21
app/src/main/res/drawable/icon_recording.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<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="M513.1,504.6m-450.8,0a450.8,450.8 0,1 0,901.6 0,450.8 450.8,0 1,0 -901.6,0Z"
|
||||||
|
android:fillColor="#E9ECFF"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M513.1,182c-178.2,0 -322.7,144.4 -322.7,322.7 0,178.2 144.4,322.7 322.7,322.7 178.2,0 322.7,-144.4 322.7,-322.7 0,-178.2 -144.4,-322.7 -322.7,-322.7zM419.1,397.9c0,-51.9 42,-94 94,-94 51.9,0 94,42 94,94v96.3c0,51.9 -42,94 -94,94 -51.9,0 -94,-42 -94,-94v-96.3zM684.5,492.5c0,86.5 -63.3,158.4 -145.7,171.2v46.7c0,14.1 -11.5,25.6 -25.6,25.6s-25.6,-11.5 -25.6,-25.6v-46.5C404.5,651.7 340.4,579.5 340.4,492.5v-12.8c0,-14.1 11.5,-25.6 25.6,-25.6s25.6,11.5 25.6,25.6v12.8c0,67.3 54.2,122 120.8,122 66.7,0 120.8,-54.7 120.8,-122v-12.8c0,-14.1 11.5,-25.6 25.6,-25.6s25.6,11.5 25.6,25.6v12.8z"
|
||||||
|
android:fillColor="#6C6CEA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M799.6,356.4c-53.7,-103.6 -161.8,-174.4 -286.6,-174.4 -178.2,0 -322.7,144.4 -322.7,322.7 0,117.1 62.4,219.6 155.8,276.2 1.1,0 2.3,0.1 3.4,0.1 240.1,0 436.4,-187.8 450,-424.4zM419.1,397.9c0,-51.9 42,-94 94,-94 51.9,0 94,42 94,94v96.3c0,51.9 -42,94 -94,94 -51.9,0 -94,-42 -94,-94v-96.3zM538.8,663.7v46.7c0,14.1 -11.5,25.6 -25.6,25.6s-25.6,-11.5 -25.6,-25.6v-46.5C404.5,651.7 340.4,579.5 340.4,492.5v-12.8c0,-14.1 11.5,-25.6 25.6,-25.6s25.6,11.5 25.6,25.6v12.8c0,67.3 54.2,122 120.8,122 66.7,0 120.8,-54.7 120.8,-122v-12.8c0,-14.1 11.5,-25.6 25.6,-25.6s25.6,11.5 25.6,25.6v12.8c0.1,86.5 -63.2,158.4 -145.6,171.2z"
|
||||||
|
android:fillColor="#757BF2"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M190.4,504.6c0,40.9 7.7,79.9 21.5,115.9 4.8,0.2 9.5,0.3 14.3,0.3 51.9,0 101.8,-8.8 148.2,-24.9a172.9,172.9 0,0 1,-34.1 -103.3v-12.8c0,-14.1 11.5,-25.6 25.6,-25.6s25.6,11.5 25.6,25.6v12.8c0,31.9 12.2,61 32.2,82.8 8.4,-4.1 16.6,-8.4 24.7,-13.1 -18.1,-17.1 -29.4,-41.3 -29.4,-68.1v-96.3c0,-51.9 42,-94 94,-94 51.9,0 94,42 94,94v13.6a448.5,448.5 0,0 0,66.8 -186.6,321 321,0 0,0 -160.7,-42.9c-178.1,0 -322.6,144.5 -322.6,322.7z"
|
||||||
|
android:fillColor="#8486F8"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M194.5,453.8c152.2,-27.8 277.7,-132 335.3,-271.5 -5.5,-0.3 -11.1,-0.4 -16.6,-0.4 -160.9,0 -294.2,117.8 -318.6,271.9z"
|
||||||
|
android:fillColor="#8D92F8"/>
|
||||||
|
</vector>
|
||||||
57
app/src/main/res/drawable/image_favorite_empty.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<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="M64,826.6c0,70.6 203.2,128 454.2,128s454.1,-57.2 454.1,-128 -203.1,-128 -454.1,-128S64,756.1 64,826.6zM64,826.6"
|
||||||
|
android:fillColor="#DEDEDE"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M795.6,740.3L600,912l-7,-332.3 208,-123.4zM795.6,740.3"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M593.8,908.6L228.8,802L228.8,678.6l307.7,90.6c20.2,-142 37,-197.4 49.4,-167.5s15,132.3 8,306.9zM588.5,574.4l-97.9,-21.3 -6.3,-69.5L484.2,365.4l306.9,85.6h10.5zM588.5,574.4"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M490.6,557.6l-254.9,-70.6 254.9,-123.4zM490.6,557.6"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M878.6,618.5l-74.8,-152.5v132.3zM878.6,618.5"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M489.8,562.1a4.3,4.3 0,0 1,-4.5 -4.5L485.3,372.6a4.5,4.5 0,1 1,9 0L494.2,557.6a4.4,4.4 0,0 1,-4.5 4.5zM489.8,562.1"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M588.5,584.9h-0.8L229.6,493.3c-1.8,-0.8 -3.4,-1.8 -3.4,-3.4a4.7,4.7 0,0 1,2.6 -4.4l260.2,-124.5a1.8,1.8 0,0 1,2.6 0l311.4,86.4a4.3,4.3 0,0 1,1.6 8L591.1,584c-0.8,0 -1.8,1 -2.6,1zM243.8,487.3l344,88 202.5,-122.4 -299.8,-83.8zM243.8,487.3"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M600,918.3h-1.8a3.5,3.5 0,0 1,-2.6 -3.4L584,580.7c0,-1.8 0.8,-3.4 1.8,-3.4l213.4,-128.6a4.5,4.5 0,0 1,4.5 0,4.4 4.4,0 0,1 2.6,3.4v290.1a5.3,5.3 0,0 1,-1.8 3.4l-201.9,172.8zM593,582.3L603.4,904l193.2,-164.8v-280zM593,582.3"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M600,918.3h-0.8l-369.3,-107.7a5.4,5.4 0,0 1,-3.4 -4.5L226.5,677.6a4.3,4.3 0,0 1,4.5 -4.5,4.2 4.2,0 0,1 4.4,4.5v126l360.7,105.8v-0.8a4.5,4.5 0,1 1,9 0v6.3a3.8,3.8 0,0 1,-1.8 3.4zM600,918.3"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M530.2,768.4L161.6,655.5l68.8,-166.7 358.1,91.6zM530.2,768.4"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M530.2,772.9h-0.8L160,660c-0.8,0 -1.8,-0.8 -2.6,-2.6a2.8,2.8 0,0 1,0 -3.4l68.8,-166.6a4.1,4.1 0,0 1,5.2 -2.6L589.5,576a4.2,4.2 0,0 1,2.6 1.8,2.8 2.8,0 0,1 0,3.4l-58.3,189c0,1.6 -1.8,2.6 -3.6,2.6zM166.9,652.9L528,763.1l56,-179.8 -351,-89zM876.7,627.4h-0.8l-74.8,-21.3a5.4,5.4 0,0 1,-3.4 -4.5L797.7,451c0,-1.8 1.8,-3.4 3.4,-4.5a4.6,4.6 0,0 1,5.3 2.6l74.8,155.9v17.6a3.6,3.6 0,0 1,-1.8 3.4,2.6 2.6,0 0,1 -2.6,1.4zM806.1,598.3l65.9,19.4L872,608.8l-66.2,-137.6z"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M880,86.6c-6.3,-8.9 -49.4,0.8 -68.7,30 -5.3,8.9 -11.6,36.2 -7.1,29.9 11.5,-16.8 32.6,-7.1 48.6,-20.2 13.1,-11.3 32.6,-32.6 27.3,-40zM880,86.6"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M804.3,149.4h-1.8c-4.5,-2.6 4.5,-28.1 7.1,-33.6a85.4,85.4 0,0 1,59.8 -34.4,12.9 12.9,0 0,1 11.5,4.5c8,11.5 -26.5,42.2 -27.3,42.2a42.2,42.2 0,0 1,-25.5 9c-8.9,1.8 -17.5,2.6 -22.8,10.5a1.2,1.2 0,0 1,-1 1.8zM870.5,84.9a76.6,76.6 0,0 0,-56.5 32,104 104,0 0,0 -8,24 35,35 0,0 1,22.8 -8.9,44.3 44.3,0 0,0 22.9,-8c15,-13.1 29.9,-32 26.5,-36.2 -0.8,-1.5 -3.7,-2.6 -8,-2.6zM870.5,84.9"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M826.4,127.4l-3.4,-2.6c16,-20.2 34.4,-36.2 73.2,-46.7 3.4,-0.8 5.3,-1.8 6.3,-1.8s1.8,-0.8 7.1,-0.8l0.8,4.5a26.4,26.4 0,0 1,-6.3 0.8,65.7 65.7,0 0,0 -6.3,1.8c-38.1,9.4 -56,24 -71.4,44.9zM826.4,127.4M856,149.4c30.6,49.2 31.4,107.1 2.1,139a112.6,112.6 0,0 1,-37 24c4.3,-22.8 -1.3,-51 -11.8,-65.3a20.9,20.9 0,0 0,-14.3 -9.5,29 29,0 0,0 -24,10.6 44.9,44.9 0,0 0,-16 36.2,42.4 42.4,0 0,0 21.8,32l0.6,0.6a53.4,53.4 0,0 0,39.4 1.8c-13.8,52.3 -76.9,79 -84.3,81.7l1.8,4.4a182.5,182.5 0,0 0,59.8 -38.6,86.4 86.4,0 0,0 26.5,-48.8 101.4,101.4 0,0 0,41 -26.2c30.5,-33 30.5,-92.8 -1.3,-144.6zM817.8,314.6a50.3,50.3 0,0 1,-38 -0.6l-1,-1.7c-15.4,-9.7 -18.8,-20.8 -18.8,-28.2a43.7,43.7 0,0 1,14.5 -33,28.6 28.6,0 0,1 20.6,-9.4 18.5,18.5 0,0 1,11.9 8,88.6 88.6,0 0,1 11.4,64z"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M137.4,831.1c-0.8,9 -37.8,19.4 -64,7.1 -9,-3.4 -24,-20.2 -18.6,-17.6 16,6.3 27.3,-8 44.9,-6.3 14.4,2.6 38.1,9.8 38.1,16.8zM137.4,831.1"
|
||||||
|
android:fillColor="#cccccc"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M100.3,846.1a78.2,78.2 0,0 1,-28.3 -5.2c-6.3,-2.6 -22.9,-16 -20.2,-20.2 0,0 0.8,-2.6 4.5,-0.8a28.2,28.2 0,0 0,22.1 -1.8,38.8 38.8,0 0,1 22.8,-3.4c8,0.8 40,8 40,18.6 0,2.6 -1.8,5.3 -6.3,7.1a130.1,130.1 0,0 1,-34.4 5.8zM58.1,824a60.9,60.9 0,0 0,15 12.3,69.4 69.4,0 0,0 57.2,-1.8c2.6,-1.8 3.4,-2.6 3.4,-3.4 0,-4.5 -18.6,-11.5 -36.2,-14.2a52.9,52.9 0,0 0,-20.2 3.4,28.5 28.5,0 0,1 -19.1,3.7zM58.1,824"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M150.7,832.7a123.2,123.2 0,0 0,-43.3 -1.8,78.2 78.2,0 0,1 -32.6,-1.8l1.8,-4.5a73.5,73.5 0,0 0,31 1.8,127.1 127.1,0 0,1 44.1,1.8zM150.7,832.7"
|
||||||
|
android:fillColor="#AAAAAA"/>
|
||||||
|
</vector>
|
||||||
@ -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/icon_playsounds_collection" android:state_selected="false" />
|
||||||
|
<item android:drawable="@drawable/icon_favorite" android:state_selected="true" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
6
app/src/main/res/drawable/selector_playsounds_looper.xml
Normal 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/icon_playsounds_loop_gray" android:state_selected="false" />
|
||||||
|
<item android:drawable="@drawable/icon_playsounds_loop_light" android:state_selected="true" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
@ -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/icon_playsounds_play" android:state_selected="false" />
|
||||||
|
<item android:drawable="@drawable/icon_playsounds_pause" android:state_selected="true" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
6
app/src/main/res/drawable/selector_playsounds_timer.xml
Normal 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/icon_playsounds_countdowm_timer_gray" android:state_selected="false" />
|
||||||
|
<item android:drawable="@drawable/icon_playsounds_countdowm_timer" android:state_selected="true" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
21
app/src/main/res/drawable/volume_progress.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@android:id/background">
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
<solid android:color="@color/gray_color" /> <!-- 背景颜色 -->
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:id="@android:id/progress">
|
||||||
|
<clip>
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
|
||||||
|
<gradient
|
||||||
|
android:endColor="@color/main_color4"
|
||||||
|
android:startColor="@color/main_color1" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</clip>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
6
app/src/main/res/drawable/welcome_bg.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<solid android:color="@color/main_color1" />
|
||||||
|
</shape>
|
||||||
21
app/src/main/res/drawable/welcome_progress.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@android:id/background">
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
<solid android:color="@color/gray_color" /> <!-- 背景颜色 -->
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:id="@android:id/progress">
|
||||||
|
<clip>
|
||||||
|
<shape>
|
||||||
|
<corners android:radius="10dp" />
|
||||||
|
|
||||||
|
<gradient
|
||||||
|
android:endColor="@color/white"
|
||||||
|
android:startColor="@color/white" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
</clip>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
67
app/src/main/res/layout/activity_collection.xml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?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:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.prank.funky.voice.collection.CollectionActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/like_title"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/framelayout_back"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignTop="@id/title"
|
||||||
|
android:layout_alignBottom="@id/title"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="26dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_back_black" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/favorite_recyclerview"
|
||||||
|
android:layout_below="@id/title"/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/empty_favorite"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/title"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:src="@drawable/image_favorite_empty" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:text="@string/string_favorite_empty"
|
||||||
|
android:textColor="@color/gray_color"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
111
app/src/main/res/layout/activity_custom.xml
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.prank.funky.voice.recordSounds.CustomActivity">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/record_title"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/framelayout_back"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignTop="@id/title"
|
||||||
|
android:layout_alignBottom="@id/title"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="26dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_back_black" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/custom_recyclerview"
|
||||||
|
android:layout_below="@id/framelayout_back"/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/empty_custom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/title"
|
||||||
|
android:layout_above="@id/linear_bottom"
|
||||||
|
android:gravity="center"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:src="@drawable/image_favorite_empty" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:text="@string/string_custom_empty"
|
||||||
|
android:textColor="@color/gray_color"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_bottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/text_import"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:text="@string/import_audio"
|
||||||
|
android:textColor="@color/white" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:id="@+id/text_recording"
|
||||||
|
android:text="@string/recording_audio"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg"
|
||||||
|
android:gravity="center" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
58
app/src/main/res/layout/activity_home.xml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.prank.funky.voice.home.HomeActivity">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_above="@id/linear_bottom" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_bottom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="90dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/frame_layout_favorite"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_favorite" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="90dp"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/frame_layout_record"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_recorder" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
40
app/src/main/res/layout/activity_list.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?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:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.prank.funky.voice.soundsList.ListActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:id="@+id/text_title"
|
||||||
|
android:textColor="@color/black"/>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:id="@+id/framelayout_back"
|
||||||
|
android:layout_alignBottom="@id/text_title"
|
||||||
|
android:layout_alignTop="@id/text_title"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="26dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_back_black"/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/sounds_list_recyclerview"
|
||||||
|
android:layout_below="@id/text_title"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
181
app/src/main/res/layout/activity_play_sounds.xml
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.prank.funky.voice.playSounds.PlaySoundsActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/sounds_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/framelayout_back"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignTop="@id/sounds_name"
|
||||||
|
android:layout_alignBottom="@id/sounds_name"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="26dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_back_black" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/sounds_img"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="240dp"
|
||||||
|
android:layout_below="@id/framelayout_back"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:layout_marginTop="45dp"
|
||||||
|
android:layout_marginEnd="25dp"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image"
|
||||||
|
android:layout_width="210dp"
|
||||||
|
android:layout_height="190dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@mipmap/ic_launcher" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearlayout_play_btn"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/sounds_img"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:layout_marginBottom="15dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/play_loading"
|
||||||
|
android:layout_width="34dp"
|
||||||
|
android:layout_height="34dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminateTint="@color/black" />
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frame_layout_btn_play"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.prank.funky.voice.playSounds.CustomerRippleView
|
||||||
|
android:id="@+id/rippleView"
|
||||||
|
android:layout_width="150dp"
|
||||||
|
android:layout_height="150dp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btn_play"
|
||||||
|
android:layout_width="72dp"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/selector_playsounds_paly_btn" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/framelayout_favorite"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_alignTop="@id/frameLayout_loop"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_toEndOf="@id/frameLayout_loop"
|
||||||
|
android:background="@drawable/bg_playsounds_oval1">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_favorite"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/selector_playsounds_favorite" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frameLayout_loop"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_alignTop="@id/frameLayout_timer"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_toEndOf="@id/frameLayout_timer"
|
||||||
|
android:background="@drawable/bg_playsounds_oval1">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_loop"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/selector_playsounds_looper" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frameLayout_timer"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_below="@id/layout_volume"
|
||||||
|
android:layout_alignStart="@id/layout_volume"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:background="@drawable/bg_playsounds_oval1">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_clock"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/selector_playsounds_timer" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/layout_volume"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="52dp"
|
||||||
|
android:layout_below="@id/linearlayout_play_btn"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/im"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:src="@drawable/icon_playsounds_volum" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/volume_seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toEndOf="@id/im"
|
||||||
|
android:maxHeight="5dp"
|
||||||
|
android:progress="10"
|
||||||
|
android:progressDrawable="@drawable/volume_progress"
|
||||||
|
android:thumb="@drawable/icon_playsounds_pb_thumb" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</RelativeLayout>
|
||||||
85
app/src/main/res/layout/activity_record.xml
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context="com.prank.funky.voice.recordSounds.RecordSoundsActivity">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/record_title"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frame_back"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignTop="@id/title"
|
||||||
|
android:layout_alignBottom="@id/title"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="26dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_back_black" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/frame_im"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_below="@id/frame_back"
|
||||||
|
android:layout_marginTop="90dp"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.prank.funky.voice.playSounds.CustomerRippleView
|
||||||
|
android:id="@+id/rippleView"
|
||||||
|
android:layout_width="240dp"
|
||||||
|
android:layout_height="240dp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/btn_play"
|
||||||
|
android:layout_width="170dp"
|
||||||
|
android:layout_height="170dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:src="@drawable/icon_recording" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/record_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_below="@id/frame_im"
|
||||||
|
android:text="@string/time_start"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:id="@+id/text_start"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg"
|
||||||
|
android:text="@string/start"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:layout_below="@id/record_time"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:textSize="22sp"
|
||||||
|
android:layout_marginTop="30dp"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
40
app/src/main/res/layout/activity_welcome.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?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:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/welcome_bg"
|
||||||
|
tools:context="com.prank.funky.voice.welcome.WelcomeActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="120dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="200dp"
|
||||||
|
android:id="@+id/logo_im"
|
||||||
|
android:src="@mipmap/logo"/>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="15dp"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:progress="100"
|
||||||
|
android:id="@+id/load_pb"
|
||||||
|
android:layout_marginBottom="55dp"
|
||||||
|
android:layout_marginStart="40dp"
|
||||||
|
android:layout_marginEnd="40dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginTop="22dp"
|
||||||
|
android:progressDrawable="@drawable/welcome_progress" />
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:layout_alignTop="@id/load_pb"
|
||||||
|
android:text="1%"
|
||||||
|
android:gravity="center"
|
||||||
|
android:id="@+id/text_progress"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:textColor="@color/black"/>
|
||||||
|
</RelativeLayout>
|
||||||
31
app/src/main/res/layout/collection_adapter.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:background="@drawable/bg_main_shape1">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="55dp"
|
||||||
|
android:layout_height="55dp"
|
||||||
|
android:id="@+id/image_view"
|
||||||
|
android:src="@drawable/icon_music"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:contentDescription="@string/app_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:textColor="@color/white"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
44
app/src/main/res/layout/custom_audio_adapter.xml
Normal 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"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_main_shape1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:paddingBottom="5dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_view"
|
||||||
|
android:layout_width="55dp"
|
||||||
|
android:layout_height="55dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:contentDescription="@string/app_name"
|
||||||
|
android:src="@drawable/icon_music" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:id="@+id/bottom_placeholder"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_height="70dp" />
|
||||||
|
</LinearLayout>
|
||||||
74
app/src/main/res/layout/dialog_save_audio.xml
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_dialog_save_audio_background">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/save_title"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="17sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/edit_name"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/title"
|
||||||
|
android:layout_margin="26dp"
|
||||||
|
android:background="@drawable/bg_dialog_edittext_background"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingStart="5dp"
|
||||||
|
android:paddingEnd="5dp"
|
||||||
|
android:padding="11dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:hint="@string/save_audio_name_hint"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textColorHint="@color/gray_color" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linear_bottom"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/edit_name"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="10dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="10dp">
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:id="@+id/text_cancel"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:text="@string/dialog_save_cancel"
|
||||||
|
android:textColor="@color/color_F2F0F0" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="120dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="40dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:id="@+id/text_save"
|
||||||
|
android:text="@string/dialog_save"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg"
|
||||||
|
android:gravity="center" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
115
app/src/main/res/layout/dialog_timer.xml
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?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"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_main_stoke_bg"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/countdown"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_time"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/title"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_off"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:text="@string/clock_off"
|
||||||
|
android:textColor="@color/selector_clock_timer_display_color"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:background="@color/gray_color" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_15s"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:text="@string/clock_15"
|
||||||
|
android:textColor="@color/selector_clock_timer_display_color"
|
||||||
|
android:textSize="13sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:background="@color/gray_color" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_30s"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:text="@string/clock_30"
|
||||||
|
android:textColor="@color/selector_clock_timer_display_color"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:background="@color/gray_color" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_1m"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:text="@string/clock_1min"
|
||||||
|
android:textColor="@color/selector_clock_timer_display_color"
|
||||||
|
android:textSize="13sp"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="5dp"
|
||||||
|
android:layout_marginEnd="5dp"
|
||||||
|
android:background="@color/gray_color" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_5m"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:padding="7dp"
|
||||||
|
android:text="@string/clock_5min"
|
||||||
|
android:textColor="@color/selector_clock_timer_display_color"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
26
app/src/main/res/layout/home_adapter.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
|
android:background="@drawable/bg_main_shape1">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="85dp"
|
||||||
|
android:layout_height="85dp"
|
||||||
|
android:id="@+id/image_view"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:contentDescription="@string/app_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="17sp"
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:textColor="@color/white"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
26
app/src/main/res/layout/list_adapter.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:background="@drawable/bg_main_shape1">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="55dp"
|
||||||
|
android:layout_height="55dp"
|
||||||
|
android:id="@+id/image_view"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:contentDescription="@string/app_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:textColor="@color/white"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/logo.png
Normal file
|
After Width: | Height: | Size: 227 KiB |
26
app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!-- <color name="purple_200">#FFBB86FC</color>-->
|
||||||
|
<!-- <color name="purple_500">#FF6200EE</color>-->
|
||||||
|
<!-- <color name="purple_700">#FF3700B3</color>-->
|
||||||
|
<!-- <color name="teal_200">#FF03DAC5</color>-->
|
||||||
|
<!-- <color name="teal_700">#FF018786</color>-->
|
||||||
|
<color name="black">#FF000000</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
<!-- <color name="dark_color">#2D3743</color>-->
|
||||||
|
<color name="main_color1">#707CC4</color>
|
||||||
|
<color name="main_color2">#EA4C78</color>
|
||||||
|
<color name="main_color3">#C3D401</color>
|
||||||
|
<color name="main_color4">#018ED2</color>
|
||||||
|
<color name="main_color5">#93D5EB</color>
|
||||||
|
|
||||||
|
<!-- <color name="main_colorEDBDCB">#EDBDCB</color>-->
|
||||||
|
<color name="main_colorE61B1B">#E61B1B</color>
|
||||||
|
|
||||||
|
<color name="gray_color">#9B9B9B</color>
|
||||||
|
<color name="color_F2F0F0">#E9E3E3</color>
|
||||||
|
<color name="color_transparent">#00000000</color>
|
||||||
|
<color name="color_DCC8FF">#DCC8FF</color>
|
||||||
|
|
||||||
|
<color name="color_95FFFFFF">#29000000</color>
|
||||||
|
</resources>
|
||||||
27
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">FunkyVoice</string>
|
||||||
|
<string name="welcome_progress">%d%%</string>
|
||||||
|
|
||||||
|
<string name="clock_off">off</string>
|
||||||
|
<string name="clock_15">15 sec</string>
|
||||||
|
<string name="clock_30">30 sec</string>
|
||||||
|
<string name="clock_1min">1 min</string>
|
||||||
|
<string name="clock_5min">5 min</string>
|
||||||
|
<string name="like_title">Favorite</string>
|
||||||
|
<string name="record_title">Custom Audio</string>
|
||||||
|
<string name="save_title">Save Audio</string>
|
||||||
|
<string name="string_favorite_empty">There is no sound in the favorites</string>
|
||||||
|
<string name="string_custom_empty">You haven\'t created any custom audio yet</string>
|
||||||
|
<string name="import_audio">Import Audio</string>
|
||||||
|
<string name="recording_audio">Recording Audio</string>
|
||||||
|
<string name="start_audio">Start Audio</string>
|
||||||
|
<string name="dialog_save_cancel">Cancel</string>
|
||||||
|
<string name="dialog_save">Save</string>
|
||||||
|
<string name="save_audio_name_hint">Give your created sound a name</string>
|
||||||
|
<string name="save_audio_ok">Audio saved successfully</string>
|
||||||
|
<string name="name_repeat">An audio with the same name already exists!</string>
|
||||||
|
<string name="start">Start</string>
|
||||||
|
<string name="stop">Stop</string>
|
||||||
|
<string name="time_start">00 : 00 : 00</string>
|
||||||
|
<string name="countdown">Countdown to Prank</string>
|
||||||
|
</resources>
|
||||||
5
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="Theme.ThePrankApp" parent="Theme.AppCompat.Light.NoActionBar" />
|
||||||
|
</resources>
|
||||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample backup rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/guide/topics/data/autobackup
|
||||||
|
for details.
|
||||||
|
Note: This file is ignored for devices older than API 31
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore
|
||||||
|
-->
|
||||||
|
<full-backup-content>
|
||||||
|
<!--
|
||||||
|
<include domain="sharedpref" path="."/>
|
||||||
|
<exclude domain="sharedpref" path="device.xml"/>
|
||||||
|
-->
|
||||||
|
</full-backup-content>
|
||||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample data extraction rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||||
|
for details.
|
||||||
|
-->
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
-->
|
||||||
|
</cloud-backup>
|
||||||
|
<!--
|
||||||
|
<device-transfer>
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
</device-transfer>
|
||||||
|
-->
|
||||||
|
</data-extraction-rules>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.sounds.funny.theprankapp
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
11
build.gradle.kts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.application) apply false
|
||||||
|
alias(libs.plugins.kotlin.android) apply false
|
||||||
|
alias(libs.plugins.kotlin.compose) apply false
|
||||||
|
}
|
||||||
|
buildscript{
|
||||||
|
dependencies{
|
||||||
|
classpath("io.objectbox:objectbox-gradle-plugin:4.0.3")
|
||||||
|
}
|
||||||
|
}
|
||||||
23
gradle.properties
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
# IDE (e.g. Android Studio) users:
|
||||||
|
# Gradle settings configured through the IDE *will override*
|
||||||
|
# any settings specified in this file.
|
||||||
|
# For more details on how to configure your build environment visit
|
||||||
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||||
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
|
# This option should only be used with decoupled projects. For more details, visit
|
||||||
|
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||||
|
# org.gradle.parallel=true
|
||||||
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
|
# Android operating system, and which are packaged with your app's APK
|
||||||
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
|
android.useAndroidX=true
|
||||||
|
# Kotlin code style for this project: "official" or "obsolete":
|
||||||
|
kotlin.code.style=official
|
||||||
|
# Enables namespacing of each library's R class so that its R class includes only the
|
||||||
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
|
# thereby reducing the size of the R class for that library
|
||||||
|
android.nonTransitiveRClass=true
|
||||||