mirror of
https://github.com/fumiama/simple-dict-android.git
synced 2026-06-05 00:30:24 +08:00
1. 增加小部件
2. 调整间距 3. 增加设置 4. 界面美化
This commit is contained in:
@@ -12,8 +12,8 @@ android {
|
||||
applicationId "top.fumiama.simpledict"
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 30
|
||||
versionCode 9
|
||||
versionName '1.7'
|
||||
versionCode 10
|
||||
versionName '1.8'
|
||||
resConfigs "zh", "zh-rCN"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
Binary file not shown.
@@ -10,8 +10,8 @@
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"versionCode": 9,
|
||||
"versionName": "1.7",
|
||||
"versionCode": 10,
|
||||
"versionName": "1.8",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -4,9 +4,7 @@ import android.annotation.SuppressLint
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.speech.RecognizerIntent
|
||||
import android.text.SpannableString
|
||||
import android.text.Spanned
|
||||
import android.text.style.StrikethroughSpan
|
||||
@@ -18,16 +16,22 @@ import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.view.children
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.lapism.search.internal.SearchLayout
|
||||
import com.lapism.search.util.SearchUtils
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.dialog_input.view.*
|
||||
import kotlinx.android.synthetic.main.line_word.view.*
|
||||
import java.io.FileNotFoundException
|
||||
import java.lang.Exception
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private val dict = SimpleDict(Client("127.0.0.1", 8000), "fumiama")
|
||||
private var host = "127.0.0.1"
|
||||
private var port = 80
|
||||
private var pwd = "demo"
|
||||
private var dict: SimpleDict? = null
|
||||
private var hasLiked = false
|
||||
private var cm: ClipboardManager? = null
|
||||
private var ad: ListViewHolder.RecyclerViewAdapter? = null
|
||||
@@ -35,6 +39,12 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
getSharedPreferences("remote", MODE_PRIVATE)?.apply {
|
||||
if(contains("host")) getString("host", host)?.apply { host = this }
|
||||
if(contains("port")) getInt("port", port).apply { port = this }
|
||||
if(contains("pwd")) getString("pwd", pwd)?.apply { pwd = this }
|
||||
}
|
||||
dict = SimpleDict(Client(host, port), pwd)
|
||||
ad = LikeViewHolder(ffr).RecyclerViewAdapter()
|
||||
cm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
ffr.apply {
|
||||
@@ -58,6 +68,7 @@ class MainActivity : AppCompatActivity() {
|
||||
val adapter = SearchViewHolder(recyclerView, findViewById(R.id.search_search_edit_text)).RecyclerViewAdapter()
|
||||
setAdapter(adapter)
|
||||
navigationIconSupport = SearchLayout.NavigationIconSupport.SEARCH
|
||||
setMicIconImageResource(R.drawable.ic_setting)
|
||||
setOnNavigationClickListener(object : SearchLayout.OnNavigationClickListener {
|
||||
override fun onNavigationClick(hasFocus: Boolean) {
|
||||
if (hasFocus()) {
|
||||
@@ -77,22 +88,59 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onQueryTextSubmit(query: CharSequence): Boolean {
|
||||
if(query.isNotEmpty()) {
|
||||
val key = query.toString()
|
||||
val data = dict[key]
|
||||
val data = dict?.get(key)
|
||||
showDictAlert(key, data, recyclerView.children.toList().let {
|
||||
val i = it.map { it.ta.text }.indexOf(key)
|
||||
if(i >= 0) it[i] else null
|
||||
}) { adapter.refresh() }
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
})
|
||||
setOnMicClickListener(object : SearchLayout.OnMicClickListener {
|
||||
override fun onMicClick() {
|
||||
if (SearchUtils.isVoiceSearchAvailable(this@MainActivity)) {
|
||||
/*if (SearchUtils.isVoiceSearchAvailable(this@MainActivity)) {
|
||||
SearchUtils.setVoiceSearch(this@MainActivity, "please speak")
|
||||
}
|
||||
}*/
|
||||
val t = layoutInflater.inflate(R.layout.dialog_input, null, false)
|
||||
AlertDialog.Builder(this@MainActivity)
|
||||
.setView(t)
|
||||
.setTitle("提示")
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
val info = t.diet.text.toString()
|
||||
try {
|
||||
val h = info.substringBefore(':')
|
||||
val l = info.substringAfter(':')
|
||||
val p = l.substringBefore('_').toInt()
|
||||
val w = l.substringAfter('_')
|
||||
if (h != "" && p > 0 && p < 65536 && w != "") {
|
||||
getSharedPreferences("remote", MODE_PRIVATE)?.edit {
|
||||
putString("host", h)
|
||||
putInt("port", p)
|
||||
putString("pwd", w)
|
||||
apply()
|
||||
Toast.makeText(this@MainActivity, "下次生效", Toast.LENGTH_SHORT).show()
|
||||
return@setPositiveButton
|
||||
}
|
||||
throw FileNotFoundException("getSharedPreferences named \"remote\" error.")
|
||||
} else throw IllegalArgumentException()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this@MainActivity, "格式非法", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||
.show()
|
||||
}
|
||||
})
|
||||
|
||||
setOnClearClickListener(object : SearchLayout.OnClearClickListener {
|
||||
override fun onClearClick() {
|
||||
Toast.makeText(this@MainActivity, "clear", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
setOnFocusChangeListener(object : SearchLayout.OnFocusChangeListener {
|
||||
override fun onFocusChange(hasFocus: Boolean) {
|
||||
navigationIconSupport = if (hasFocus) SearchLayout.NavigationIconSupport.ARROW
|
||||
@@ -110,7 +158,7 @@ class MainActivity : AppCompatActivity() {
|
||||
else super.onBackPressed()
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
/*override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when(requestCode) {
|
||||
SearchUtils.SPEECH_REQUEST_CODE -> data?.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS)?.let {
|
||||
@@ -120,11 +168,11 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
private fun fetchThread() {
|
||||
Thread{
|
||||
dict.fetchDict {
|
||||
dict?.fetchDict {
|
||||
runOnUiThread {
|
||||
Toast.makeText(this@MainActivity, "刷新成功", Toast.LENGTH_SHORT).show()
|
||||
ffsw.isRefreshing = false
|
||||
@@ -134,22 +182,23 @@ class MainActivity : AppCompatActivity() {
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun showDictAlert(key: String, data: String?, line: View?, refresh: (()->Unit)?=null) {
|
||||
private fun showDictAlert(key: String, data: String?, line: View?) {
|
||||
val hintAdd = if(data != null && data != "null") "重设" else "添加"
|
||||
hasLiked = false
|
||||
AlertDialog.Builder(this@MainActivity)
|
||||
.setTitle(key)
|
||||
.setMessage(data)
|
||||
.setPositiveButton(hintAdd) { _, _ ->
|
||||
val t = EditText(this@MainActivity)
|
||||
t.setText(data)
|
||||
val t = layoutInflater.inflate(R.layout.dialog_input, null, false)
|
||||
t.diet.setText(data)
|
||||
t.dit.text = "更改将立即生效"
|
||||
AlertDialog.Builder(this@MainActivity)
|
||||
.setTitle("$hintAdd$key")
|
||||
.setView(t)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
val newText = t.text.toString()
|
||||
if (t.text.isNotEmpty() && newText != data) Thread {
|
||||
dict[key] = newText
|
||||
val newText = t.diet.text.toString()
|
||||
if (t.diet.text.isNotEmpty() && newText != data) Thread {
|
||||
dict?.set(key, newText)
|
||||
line?.tb?.text = newText
|
||||
}.start()
|
||||
else Toast.makeText(this, "未更改", Toast.LENGTH_SHORT).show()
|
||||
@@ -159,7 +208,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
.setNeutralButton("删除") { _, _ ->
|
||||
Thread{
|
||||
dict -= key
|
||||
dict?.minusAssign(key)
|
||||
line?.apply {
|
||||
val delKey = SpannableString(key)
|
||||
val delData = SpannableString(data)
|
||||
@@ -178,17 +227,16 @@ class MainActivity : AppCompatActivity() {
|
||||
inner class SearchViewHolder(itemView: View, private val editText: EditText) : ListViewHolder(itemView) {
|
||||
inner class RecyclerViewAdapter : ListViewHolder.RecyclerViewAdapter() {
|
||||
override fun getKeys() = filter(editText.text)
|
||||
override fun getValue(key: String) = dict[key]
|
||||
override fun getValue(key: String) = dict?.get(key)
|
||||
private fun filter(text: CharSequence): List<String> {
|
||||
val selectSet = dict.keys.filter { it.contains(text, true) }.toSet() +
|
||||
dict.filterValues { it?.contains(text, true) ?: false }.let {
|
||||
val newSet = mutableSetOf<String>()
|
||||
it.keys.forEach {
|
||||
newSet += it
|
||||
}
|
||||
newSet
|
||||
}
|
||||
return selectSet.toList().let { if (it.size > 50) it.subList(0, 49) else it }
|
||||
val selectSet = dict?.keys?.filter { it.contains(text, true) }?.toSet()?.plus(dict?.filterValues { it?.contains(text, true) ?: false }.let {
|
||||
val newSet = mutableSetOf<String>()
|
||||
it?.keys?.forEach {
|
||||
newSet += it
|
||||
}
|
||||
newSet
|
||||
})
|
||||
return selectSet?.toList()?.let { if (it.size > 50) it.subList(0, 49) else it }?: emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,11 +244,13 @@ class MainActivity : AppCompatActivity() {
|
||||
inner class LikeViewHolder(itemView: View) : ListViewHolder(itemView) {
|
||||
inner class RecyclerViewAdapter: ListViewHolder.RecyclerViewAdapter(){
|
||||
override fun getKeys() = getSharedPreferences("dict", MODE_PRIVATE).all.keys.toTypedArray().let{
|
||||
val end = dict.latestKeys.size
|
||||
val start = if(end > 5) end - 5 else 0
|
||||
(dict.latestKeys.copyOfRange(start, end) + it).toList()
|
||||
dict?.let { d ->
|
||||
val end = d.latestKeys.size
|
||||
val start = if(end > 5) end - 5 else 0
|
||||
(d.latestKeys.copyOfRange(start, end) + it).toList()
|
||||
}?: emptyList()
|
||||
}
|
||||
override fun getValue(key: String) = dict[key]?:getSharedPreferences("dict", MODE_PRIVATE).getString(key, "null")
|
||||
override fun getValue(key: String) = dict?.get(key)?:getSharedPreferences("dict", MODE_PRIVATE).getString(key, "null")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
app/src/main/res/drawable-anydpi/bg_dere.xml
Normal file
10
app/src/main/res/drawable-anydpi/bg_dere.xml
Normal file
File diff suppressed because one or more lines are too long
33
app/src/main/res/drawable-anydpi/bg_rnd.xml
Normal file
33
app/src/main/res/drawable-anydpi/bg_rnd.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?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" >
|
||||
<!-- 填充的颜色 -->
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<!-- 设置按钮的四个角为弧形 -->
|
||||
<!-- android:radius 弧形的半径 -->
|
||||
<corners android:radius="16dip" />
|
||||
<!-- padding:Button里面的文字与Button边界的间隔 -->
|
||||
<padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:state_pressed="false">
|
||||
<shape android:shape="rectangle" >
|
||||
<!-- 填充的颜色 -->
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<!-- 设置按钮的四个角为弧形 -->
|
||||
<!-- android:radius 弧形的半径 -->
|
||||
<corners android:radius="16dip" />
|
||||
<!-- stroke 设置边框显示 -->
|
||||
<stroke
|
||||
android:dashGap="0dp"
|
||||
android:width="1dp"
|
||||
android:color="?attr/colorOnSurface" />
|
||||
<!-- padding:Button里面的文字与Button边界的间隔 -->
|
||||
<padding android:bottom="1dp" android:left="1dp" android:right="1dp" android:top="1dp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
10
app/src/main/res/drawable-anydpi/ic_setting.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_setting.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="?android:textColorSecondary"
|
||||
android:pathData="M944 552l-182 331a74 74 0 0 1-65 38h-362a74 74 0 0 1-65-38l-182-331a75 75 0 0 1 0-73l182-331a74 74 0 0 1 65-38h362a74 74 0 0 1 65 38l182 331a75 75 0 0 1 0 73z m-56-31a11 11 0 0 0 0-10l-182-331a11 11 0 0 0-9-5H336a11 11 0 0 0-9 5l-182 331a11 11 0 0 0 0 10l182 331a11 11 0 0 0 9 5h362a11 11 0 0 0 9-5l182-331zM514 683c-94 0-171-76-171-171s76-171 171-171c94 0 171 76 171 171s-76 171-171 171z m0-64c59 0 107-48 107-107s-48-107-107-107-107 48-107 107 48 107 107 107z"/>
|
||||
</vector>
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
@@ -15,10 +16,35 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/ffr"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="32dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ffr"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/bg_dere" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="@font/nisi"
|
||||
android:text="hv#st"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/ffr"
|
||||
app:layout_constraintEnd_toStartOf="@+id/imageView" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/ffr"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
|
||||
58
app/src/main/res/layout/dialog_input.xml
Normal file
58
app/src/main/res/layout/dialog_input.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:background="@drawable/bg_rnd"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/bg_dere" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dit"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="请输入:服务器地址:端口_口令"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/diet"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/diet"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:ems="10"
|
||||
android:inputType="textPersonName"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@+id/dit"
|
||||
app:layout_constraintStart_toStartOf="@+id/dit"
|
||||
app:layout_constraintTop_toBottomOf="@+id/dit" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -17,8 +17,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:fontFamily="@font/nisi"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textSize="30sp"
|
||||
|
||||
Reference in New Issue
Block a user