1
0
mirror of https://github.com/fumiama/simple-dict-android.git synced 2026-06-05 08:40:25 +08:00
1. 增加 删除、添加、修改后即时显示
2. 增加 最近5条建议
This commit is contained in:
fumiama
2021-02-20 13:49:54 +08:00
parent 11fa0836d8
commit e2ba37c14f
6 changed files with 76 additions and 53 deletions

View File

@@ -13,8 +13,8 @@ android {
applicationId "top.fumiama.simpledict"
minSdkVersion 26
targetSdkVersion 30
versionCode 6
versionName '1.4'
versionCode 7
versionName '1.5'
resConfigs "zh", "zh-rCN"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -25,20 +25,13 @@ import kotlinx.android.synthetic.main.line_word.view.*
class MainActivity : AppCompatActivity() {
private val dict = SimpleDict(Client("127.0.0.1", 8000), "fumiama")
private var hasLiked = false
private val fetchThread get() = Thread{
dict.fetchDict {
runOnUiThread {
Toast.makeText(this@MainActivity, "刷新成功", Toast.LENGTH_SHORT).show()
ffsw.isRefreshing = false
}
}
}
private var cm: ClipboardManager? = null
private var ad: ListViewHolder.RecyclerViewAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val ad = LikeViewHolder(ffr).RecyclerViewAdapter()
ad = LikeViewHolder(ffr).RecyclerViewAdapter()
cm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
ffr.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
@@ -48,23 +41,22 @@ class MainActivity : AppCompatActivity() {
}
ffsw.apply {
setOnRefreshListener {
ad.refresh()
fetchThread.start()
fetchThread()
}
isRefreshing = true
fetchThread.start()
fetchThread()
}
}
ffms.apply {
setAdapterLayoutManager(LinearLayoutManager(this@MainActivity))
val adapter = SearchViewHolder(findViewById(R.id.search_recycler_view)).RecyclerViewAdapter()
val adapter = SearchViewHolder(findViewById(R.id.search_recycler_view), findViewById(R.id.search_search_edit_text)).RecyclerViewAdapter()
setAdapter(adapter)
navigationIconSupport = SearchLayout.NavigationIconSupport.SEARCH
setOnNavigationClickListener(object : SearchLayout.OnNavigationClickListener {
override fun onNavigationClick(hasFocus: Boolean) {
if (hasFocus()) {
if(hasLiked) ad.refresh()
if(hasLiked) ad?.refresh()
clearFocus()
}
else requestFocus()
@@ -73,7 +65,7 @@ class MainActivity : AppCompatActivity() {
setTextHint(android.R.string.search_go)
setOnQueryTextListener(object : SearchLayout.OnQueryTextListener {
override fun onQueryTextChange(newText: CharSequence): Boolean {
if (newText.isNotEmpty()) adapter.filter(newText)
if (newText.isNotEmpty()) adapter.refresh()
return true
}
@@ -81,7 +73,7 @@ class MainActivity : AppCompatActivity() {
if(query.isNotEmpty()) {
val key = query.toString()
val data = dict[key]
showDictAlert(key, data)
showDictAlert(key, data) { adapter.refresh() }
}
return true
}
@@ -104,7 +96,7 @@ class MainActivity : AppCompatActivity() {
override fun onBackPressed() {
if(ffms.hasFocus()) {
if(hasLiked) (ffr.adapter as ListViewHolder.RecyclerViewAdapter).refresh()
if(hasLiked) ad?.refresh()
ffms.clearFocus()
}
else super.onBackPressed()
@@ -122,7 +114,19 @@ class MainActivity : AppCompatActivity() {
}
}
private fun showDictAlert(key: String, data: String?) {
private fun fetchThread() {
Thread{
dict.fetchDict {
runOnUiThread {
Toast.makeText(this@MainActivity, "刷新成功", Toast.LENGTH_SHORT).show()
ffsw.isRefreshing = false
ad?.refresh()
}
}
}.start()
}
private fun showDictAlert(key: String, data: String?, notify: ()->Unit) {
val hintAdd = if(data != null && data != "null") "重设" else "添加"
hasLiked = false
AlertDialog.Builder(this@MainActivity)
@@ -135,8 +139,10 @@ class MainActivity : AppCompatActivity() {
.setTitle("$hintAdd$key")
.setView(t)
.setPositiveButton(android.R.string.ok) { _, _ ->
if (t.text.isNotEmpty() && t.text.toString() != data) Thread {
dict[key] = t.text.toString()
val newText = t.text.toString()
if (t.text.isNotEmpty() && newText != data) Thread {
dict[key] = newText
notify()
}.start()
else Toast.makeText(this, "未更改", Toast.LENGTH_SHORT).show()
}
@@ -144,46 +150,48 @@ class MainActivity : AppCompatActivity() {
.show()
}
.setNeutralButton("删除") { _, _ ->
Thread{dict -= key}.start()
Thread{
dict -= key
notify()
}.start()
}
.setNegativeButton(android.R.string.cancel) { _, _ -> }
.show()
}
inner class SearchViewHolder(itemView: View) : ListViewHolder(itemView) {
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]
fun filter(text: CharSequence) {
Thread{
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
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
}
listKeys = selectSet.toList().let { if(it.size > 50) it.subList(0, 49) else it }
listKeys?.forEach {
Log.d("MyMain", "Select key: $it")
}
runOnUiThread { notifyDataSetChanged() }
}.start()
newSet
}
return selectSet.toList().let { if (it.size > 50) it.subList(0, 49) else it }
}
}
}
inner class LikeViewHolder(itemView: View) : ListViewHolder(itemView) {
inner class RecyclerViewAdapter: ListViewHolder.RecyclerViewAdapter(){
override fun getKeys() = getSharedPreferences("dict", MODE_PRIVATE).all.keys.toList()
override fun getValue(key: String) = getSharedPreferences("dict", MODE_PRIVATE).getString(key, "null")
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()
}
override fun getValue(key: String) = dict[key]?:getSharedPreferences("dict", MODE_PRIVATE).getString(key, "null")
}
}
open inner class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
open inner class RecyclerViewAdapter :
RecyclerView.Adapter<ListViewHolder>() {
var listKeys = getKeys()
private var listKeys: List<String>? = null
open fun getKeys(): List<String>? = null
open fun getValue(key: String): String? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
@@ -195,20 +203,22 @@ class MainActivity : AppCompatActivity() {
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
Log.d("MyMain", "Bind like at $position")
Log.d("MyMain", "Bind open at $position")
Thread{
listKeys?.apply {
if (position < size) {
val key = get(position)
val data = getValue(key)
val like = getSharedPreferences("dict", MODE_PRIVATE)?.contains(key) == true
runOnUiThread {
holder.itemView.apply {
Log.d("MyMain", "Like status of $key is $like")
holder.itemView.apply {
runOnUiThread {
ta.text = key
tb.text = data
if(like) vl.setBackgroundResource(R.drawable.ic_like_filled)
vl.setBackgroundResource(if(like) R.drawable.ic_like_filled else R.drawable.ic_like)
Log.d("MyMain", "Set like of $key: $like")
setOnClickListener {
showDictAlert(key, data)
showDictAlert(key, data) {refresh()}
}
setOnLongClickListener {
cm?.setPrimaryClip(ClipData.newPlainText("SimpleDict", "$key\n$data"))
@@ -239,10 +249,10 @@ class MainActivity : AppCompatActivity() {
override fun getItemCount() = listKeys?.size?:0
fun refresh() {
fun refresh() = Thread{
listKeys = getKeys()
runOnUiThread { notifyDataSetChanged() }
}
}.start()
}
}
}

View File

@@ -8,6 +8,7 @@ class SimpleDict(private val client: Client, private val pwd: String) { //must
val keys get() = dict.keys
//val values get() = dict.values
//val size get() = dict.size
var latestKeys = arrayOf<String>()
private val raw: ByteArray
get() {
var times = 3
@@ -61,7 +62,10 @@ class SimpleDict(private val client: Client, private val pwd: String) { //must
val dataEnd = 64 + dictBlock[127].toInt().let { if (it > 63) 63 else it }
val key = dictBlock.copyOf(keyLen).decodeToString()
val data = if (dataEnd > 64) dictBlock.copyOfRange(64, dataEnd).decodeToString() else null
dict[key] = data
if(key != "") {
dict[key] = data
latestKeys += key
}
Log.d("MySD", "Fetch $key=$data")
}
@@ -73,6 +77,7 @@ class SimpleDict(private val client: Client, private val pwd: String) { //must
}) {
val dictBlock = ByteArray(128)
dict = hashMapOf()
latestKeys = arrayOf()
raw.inputStream().let {
while (it.read(dictBlock, 0, 128) == 128) analyzeDictBlk(dictBlock)
doOnLoadSuccess()
@@ -86,6 +91,15 @@ class SimpleDict(private val client: Client, private val pwd: String) { //must
sendMessageWithDelay(key)
client.receiveMessage()
closeDict()
dict.remove(key)
val end = latestKeys.size-1
if(end > 0) latestKeys = latestKeys.let { oldArr ->
var index = -1
Array(end) {
if(oldArr[it] == key) index = it
return@Array if(index < 0 || (index > 0 && it < index)) oldArr[it] else oldArr[it+1]
}
}
}
operator fun get(key: String) = dict[key]

View File

@@ -38,7 +38,6 @@
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginEnd="16dp"
android:background="@drawable/ic_like"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"

Binary file not shown.

View File

@@ -10,8 +10,8 @@
{
"type": "SINGLE",
"filters": [],
"versionCode": 6,
"versionName": "1.4",
"versionCode": 7,
"versionName": "1.5",
"outputFile": "app-winrelease.apk"
}
]