parent
cf08b06d4e
commit
aaf262fb9d
@ -0,0 +1,62 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"id": 1, |
||||||
|
"name": "度小美", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 2, |
||||||
|
"name": "度小宇", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 3, |
||||||
|
"name": "度逍遙", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 4, |
||||||
|
"name": "度丫丫", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 5, |
||||||
|
"name": "度小嬌", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 6, |
||||||
|
"name": "度米朵", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 7, |
||||||
|
"name": "度博文", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 8, |
||||||
|
"name": "度小童", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 9, |
||||||
|
"name": "度小萌", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 10, |
||||||
|
"name": "百度騷男", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 11, |
||||||
|
"name": "百度評書", |
||||||
|
"url": "" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"id": 12, |
||||||
|
"name": "百度主持", |
||||||
|
"url": "" |
||||||
|
} |
||||||
|
] |
@ -0,0 +1,28 @@ |
|||||||
|
package io.legado.app.data.dao |
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData |
||||||
|
import androidx.room.* |
||||||
|
import io.legado.app.data.entities.HttpTTS |
||||||
|
|
||||||
|
@Dao |
||||||
|
interface HttpTTSDao { |
||||||
|
|
||||||
|
@get:Query("select * from httpTTS order by name") |
||||||
|
val all: List<HttpTTS> |
||||||
|
|
||||||
|
@Query("select * from httpTTS order by name") |
||||||
|
fun observeAll(): LiveData<List<HttpTTS>> |
||||||
|
|
||||||
|
@Query("select * from httpTTS where id = :id") |
||||||
|
fun get(id: Long): HttpTTS? |
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE) |
||||||
|
fun insert(vararg httpTTS: HttpTTS) |
||||||
|
|
||||||
|
@Delete |
||||||
|
fun delete(vararg httpTTS: HttpTTS) |
||||||
|
|
||||||
|
@Update |
||||||
|
fun update(vararg httpTTS: HttpTTS) |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
package io.legado.app.data.entities |
||||||
|
|
||||||
|
import androidx.room.Entity |
||||||
|
import androidx.room.PrimaryKey |
||||||
|
|
||||||
|
@Entity(tableName = "httpTTS") |
||||||
|
data class HttpTTS( |
||||||
|
@PrimaryKey |
||||||
|
val id: Long = System.currentTimeMillis(), |
||||||
|
var name: String = "", |
||||||
|
var url: String = "" |
||||||
|
) |
@ -0,0 +1,161 @@ |
|||||||
|
package io.legado.app.ui.book.read.config |
||||||
|
|
||||||
|
import android.annotation.SuppressLint |
||||||
|
import android.content.Context |
||||||
|
import android.os.Bundle |
||||||
|
import android.util.DisplayMetrics |
||||||
|
import android.view.LayoutInflater |
||||||
|
import android.view.MenuItem |
||||||
|
import android.view.View |
||||||
|
import android.view.ViewGroup |
||||||
|
import androidx.appcompat.widget.Toolbar |
||||||
|
import androidx.lifecycle.LiveData |
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager |
||||||
|
import io.legado.app.App |
||||||
|
import io.legado.app.R |
||||||
|
import io.legado.app.base.BaseDialogFragment |
||||||
|
import io.legado.app.base.adapter.ItemViewHolder |
||||||
|
import io.legado.app.base.adapter.SimpleRecyclerAdapter |
||||||
|
import io.legado.app.constant.PreferKey |
||||||
|
import io.legado.app.data.entities.HttpTTS |
||||||
|
import io.legado.app.lib.dialogs.alert |
||||||
|
import io.legado.app.lib.dialogs.cancelButton |
||||||
|
import io.legado.app.lib.dialogs.customView |
||||||
|
import io.legado.app.lib.dialogs.okButton |
||||||
|
import io.legado.app.lib.theme.primaryColor |
||||||
|
import io.legado.app.service.help.ReadAloud |
||||||
|
import io.legado.app.utils.* |
||||||
|
import kotlinx.android.synthetic.main.dialog_http_tts_edit.view.* |
||||||
|
import kotlinx.android.synthetic.main.dialog_recycler_view.* |
||||||
|
import kotlinx.android.synthetic.main.item_http_tts.view.* |
||||||
|
import org.jetbrains.anko.sdk27.listeners.onClick |
||||||
|
|
||||||
|
class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { |
||||||
|
|
||||||
|
override fun onStart() { |
||||||
|
super.onStart() |
||||||
|
val dm = DisplayMetrics() |
||||||
|
activity?.windowManager?.defaultDisplay?.getMetrics(dm) |
||||||
|
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onCreateView( |
||||||
|
inflater: LayoutInflater, |
||||||
|
container: ViewGroup?, |
||||||
|
savedInstanceState: Bundle? |
||||||
|
): View? { |
||||||
|
return inflater.inflate(R.layout.dialog_recycler_view, container) |
||||||
|
} |
||||||
|
|
||||||
|
lateinit var adapter: Adapter |
||||||
|
private var httpTTSData: LiveData<List<HttpTTS>>? = null |
||||||
|
var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine) |
||||||
|
|
||||||
|
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { |
||||||
|
initView() |
||||||
|
initMenu() |
||||||
|
initData() |
||||||
|
} |
||||||
|
|
||||||
|
private fun initView() { |
||||||
|
tool_bar.setBackgroundColor(primaryColor) |
||||||
|
tool_bar.setTitle(R.string.speak_engine) |
||||||
|
recycler_view.layoutManager = LinearLayoutManager(requireContext()) |
||||||
|
adapter = Adapter(requireContext()) |
||||||
|
recycler_view.adapter = adapter |
||||||
|
tv_footer_left.setText(R.string.local_tts) |
||||||
|
tv_footer_left.visible() |
||||||
|
tv_footer_left.onClick { |
||||||
|
removePref(PreferKey.speakEngine) |
||||||
|
dismiss() |
||||||
|
} |
||||||
|
tv_ok.visible() |
||||||
|
tv_ok.onClick { |
||||||
|
putPrefLong(PreferKey.speakEngine, engineId) |
||||||
|
dismiss() |
||||||
|
} |
||||||
|
tv_cancel.visible() |
||||||
|
tv_cancel.onClick { |
||||||
|
dismiss() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private fun initMenu() { |
||||||
|
tool_bar.inflateMenu(R.menu.speak_engine) |
||||||
|
tool_bar.menu.applyTint(requireContext()) |
||||||
|
tool_bar.setOnMenuItemClickListener(this) |
||||||
|
} |
||||||
|
|
||||||
|
private fun initData() { |
||||||
|
httpTTSData?.removeObservers(this) |
||||||
|
httpTTSData = App.db.httpTTSDao().observeAll() |
||||||
|
httpTTSData?.observe(this, { |
||||||
|
adapter.setItems(it) |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
override fun onMenuItemClick(item: MenuItem?): Boolean { |
||||||
|
when (item?.itemId) { |
||||||
|
R.id.menu_add -> editHttpTTS() |
||||||
|
} |
||||||
|
return true |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("InflateParams") |
||||||
|
private fun editHttpTTS(v: HttpTTS? = null) { |
||||||
|
val httpTTS = v?.copy() ?: HttpTTS() |
||||||
|
requireContext().alert(titleResource = R.string.speak_engine) { |
||||||
|
var rootView: View? = null |
||||||
|
customView { |
||||||
|
LayoutInflater.from(requireContext()) |
||||||
|
.inflate(R.layout.dialog_http_tts_edit, null).apply { |
||||||
|
rootView = this |
||||||
|
tv_name.setText(httpTTS.name) |
||||||
|
tv_url.setText(httpTTS.url) |
||||||
|
} |
||||||
|
} |
||||||
|
cancelButton() |
||||||
|
okButton { |
||||||
|
rootView?.apply { |
||||||
|
httpTTS.name = tv_name.text.toString() |
||||||
|
httpTTS.url = tv_url.text.toString() |
||||||
|
App.db.httpTTSDao().insert(httpTTS) |
||||||
|
ReadAloud.upReadAloudClass() |
||||||
|
} |
||||||
|
} |
||||||
|
}.show().applyTint() |
||||||
|
} |
||||||
|
|
||||||
|
inner class Adapter(context: Context) : |
||||||
|
SimpleRecyclerAdapter<HttpTTS>(context, R.layout.item_http_tts) { |
||||||
|
|
||||||
|
override fun convert(holder: ItemViewHolder, item: HttpTTS, payloads: MutableList<Any>) { |
||||||
|
holder.itemView.apply { |
||||||
|
cb_name.text = item.name |
||||||
|
cb_name.isChecked = item.id == engineId |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun registerListener(holder: ItemViewHolder) { |
||||||
|
holder.itemView.apply { |
||||||
|
cb_name.onClick { |
||||||
|
getItem(holder.layoutPosition)?.let { httpTTS -> |
||||||
|
engineId = httpTTS.id |
||||||
|
notifyItemRangeChanged(0, getActualItemCount()) |
||||||
|
} |
||||||
|
} |
||||||
|
iv_edit.onClick { |
||||||
|
editHttpTTS(getItem(holder.layoutPosition)) |
||||||
|
} |
||||||
|
iv_menu_delete.onClick { |
||||||
|
getItem(holder.layoutPosition)?.let { httpTTS -> |
||||||
|
App.db.httpTTSDao().delete(httpTTS) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:orientation="vertical" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:paddingTop="10dp" |
||||||
|
android:paddingStart="10dp" |
||||||
|
android:paddingEnd="10dp"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.TextInputLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:hint="@string/name"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.EditText |
||||||
|
android:id="@+id/tv_name" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" /> |
||||||
|
|
||||||
|
</io.legado.app.ui.widget.text.TextInputLayout> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.TextInputLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:hint="url" |
||||||
|
tools:ignore="HardcodedText"> |
||||||
|
|
||||||
|
<io.legado.app.ui.widget.text.EditText |
||||||
|
android:id="@+id/tv_url" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" /> |
||||||
|
|
||||||
|
</io.legado.app.ui.widget.text.TextInputLayout> |
||||||
|
|
||||||
|
</LinearLayout> |
@ -0,0 +1,37 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:gravity="center" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:padding="8dp"> |
||||||
|
|
||||||
|
<io.legado.app.lib.theme.view.ATERadioButton |
||||||
|
android:id="@+id/cb_name" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_weight="1" |
||||||
|
tools:ignore="RtlSymmetry" /> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView |
||||||
|
android:id="@+id/iv_edit" |
||||||
|
android:layout_width="36dp" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_gravity="center" |
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless" |
||||||
|
android:contentDescription="@string/edit" |
||||||
|
android:padding="6dp" |
||||||
|
android:src="@drawable/ic_edit" |
||||||
|
android:tint="@color/primaryText" /> |
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView |
||||||
|
android:id="@+id/iv_menu_delete" |
||||||
|
android:layout_width="36dp" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:padding="6dp" |
||||||
|
android:background="?attr/selectableItemBackgroundBorderless" |
||||||
|
android:src="@drawable/ic_clear_all" |
||||||
|
android:tint="@color/primaryText" |
||||||
|
tools:ignore="RtlHardcoded" /> |
||||||
|
</LinearLayout> |
@ -0,0 +1,11 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"> |
||||||
|
|
||||||
|
<item |
||||||
|
android:id="@+id/menu_add" |
||||||
|
android:icon="@drawable/ic_add" |
||||||
|
android:title="@string/add" |
||||||
|
app:showAsAction="always" /> |
||||||
|
|
||||||
|
</menu> |
Loading…
Reference in new issue