diff --git a/app/build.gradle b/app/build.gradle index 9ff2760..43bfe96 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/release/app-release.apk b/app/release/app-release.apk index 1998968..3ec8828 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 3c5b757..1d79554 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -10,8 +10,8 @@ { "type": "SINGLE", "filters": [], - "versionCode": 9, - "versionName": "1.7", + "versionCode": 10, + "versionName": "1.8", "outputFile": "app-release.apk" } ] diff --git a/app/src/main/java/top/fumiama/simpledict/MainActivity.kt b/app/src/main/java/top/fumiama/simpledict/MainActivity.kt index 6d8f3cc..eb8df47 100644 --- a/app/src/main/java/top/fumiama/simpledict/MainActivity.kt +++ b/app/src/main/java/top/fumiama/simpledict/MainActivity.kt @@ -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 { - val selectSet = dict.keys.filter { it.contains(text, true) }.toSet() + - dict.filterValues { it?.contains(text, true) ?: false }.let { - val newSet = mutableSetOf() - 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() + 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") } } diff --git a/app/src/main/res/drawable-anydpi/bg_dere.xml b/app/src/main/res/drawable-anydpi/bg_dere.xml new file mode 100644 index 0000000..b73d2f6 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/bg_dere.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi/bg_rnd.xml b/app/src/main/res/drawable-anydpi/bg_rnd.xml new file mode 100644 index 0000000..f2cce62 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/bg_rnd.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-anydpi/ic_setting.xml b/app/src/main/res/drawable-anydpi/ic_setting.xml new file mode 100644 index 0000000..ee24892 --- /dev/null +++ b/app/src/main/res/drawable-anydpi/ic_setting.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8017324..679a03f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,6 +1,7 @@ @@ -15,10 +16,35 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent"> + + + + + + + + diff --git a/app/src/main/res/layout/dialog_input.xml b/app/src/main/res/layout/dialog_input.xml new file mode 100644 index 0000000..4d23acc --- /dev/null +++ b/app/src/main/res/layout/dialog_input.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/line_word.xml b/app/src/main/res/layout/line_word.xml index 51d56c2..78a7db1 100644 --- a/app/src/main/res/layout/line_word.xml +++ b/app/src/main/res/layout/line_word.xml @@ -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"