mirror of
https://github.com/fumiama/simple-dict-android.git
synced 2026-06-09 20:40:49 +08:00
v1.0
This commit is contained in:
@@ -11,7 +11,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "top.fumiama.simpledict"
|
applicationId "top.fumiama.simpledict"
|
||||||
minSdkVersion 23
|
minSdkVersion 26
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
@@ -62,6 +62,7 @@ dependencies {
|
|||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.3'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.3'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.3'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.3.3'
|
||||||
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
@@ -93,7 +94,8 @@ andResGuard {
|
|||||||
"R.string.ga_trackingId",
|
"R.string.ga_trackingId",
|
||||||
"R.string.firebase_database_url",
|
"R.string.firebase_database_url",
|
||||||
"R.string.google_api_key",
|
"R.string.google_api_key",
|
||||||
"R.string.google_crash_reporting_api_key"
|
"R.string.google_crash_reporting_api_key",
|
||||||
|
"R.font.*"
|
||||||
]
|
]
|
||||||
compressFilePattern = [
|
compressFilePattern = [
|
||||||
"*.png",
|
"*.png",
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import java.io.IOException
|
|||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.net.Socket
|
import java.net.Socket
|
||||||
import java.nio.charset.Charset
|
|
||||||
|
|
||||||
class Client(val ip: String, val port: Int) {
|
class Client(val ip: String, val port: Int) {
|
||||||
//普通数据交互接口
|
//普通数据交互接口
|
||||||
@@ -58,24 +57,27 @@ class Client(val ip: String, val port: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun receiveMessage(): String? {
|
fun receiveRawMessage()= try {
|
||||||
var message: String? = ""
|
|
||||||
try {
|
|
||||||
if (isConnect) {
|
if (isConnect) {
|
||||||
Log.d("MyC", "开始接收服务端信息")
|
Log.d("MyC", "开始接收服务端信息")
|
||||||
val inMessage = ByteArray(1024) //设置接受缓冲,避免接受数据过长占用过多内存
|
val inMessage = ByteArray(1024) //设置接受缓冲,避免接受数据过长占用过多内存
|
||||||
val a = din?.read(inMessage) //a存储返回消息的长度
|
val a = din?.read(inMessage) //a存储返回消息的长度
|
||||||
if (a == null || a <= -1) return null
|
if (a == null || a <= -1) null
|
||||||
Log.d("MyC", "reply length:$a")
|
else {
|
||||||
message = inMessage.copyOf(a).decodeToString()
|
Log.d("MyC", "reply length:$a")
|
||||||
Log.d("MyC", message)
|
inMessage.copyOf(a)
|
||||||
} else Log.d("MyC", "no connect to receive message")
|
}
|
||||||
|
} else {
|
||||||
|
Log.d("MyC", "no connect to receive message")
|
||||||
|
null
|
||||||
|
}
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.d("MyC", "receive message failed")
|
Log.d("MyC", "receive message failed")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
null
|
||||||
}
|
}
|
||||||
return message
|
|
||||||
}
|
fun receiveMessage() = receiveRawMessage()?.decodeToString()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭连接
|
* 关闭连接
|
||||||
|
|||||||
@@ -1,91 +1,79 @@
|
|||||||
package top.fumiama.simpledict
|
package top.fumiama.simpledict
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.SharedPreferences
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.speech.RecognizerIntent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.lapism.search.internal.SearchLayout
|
import com.lapism.search.internal.SearchLayout
|
||||||
import com.lapism.search.util.SearchUtils
|
import com.lapism.search.util.SearchUtils
|
||||||
import kotlinx.android.synthetic.main.activity_main.*
|
import kotlinx.android.synthetic.main.activity_main.*
|
||||||
import kotlinx.android.synthetic.main.line_word.view.*
|
import kotlinx.android.synthetic.main.line_word.view.*
|
||||||
import java.lang.Thread.sleep
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
private var keys = arrayOf<String>()
|
private val dict = SimpleDict(Client("pan.fumiama.top", 43792), "fumiama")
|
||||||
private var datas = arrayOf<String?>()
|
private var hasLiked = false
|
||||||
private val dict = SimpleDict(Client("192.168.98.2", 8000))
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
val ad = LikeViewHolder(ffr).RecyclerViewAdapter()
|
||||||
|
ffr.apply {
|
||||||
|
layoutManager = LinearLayoutManager(this@MainActivity)
|
||||||
|
adapter = ad
|
||||||
|
setOnScrollChangeListener { _, _, scrollY, _, _ ->
|
||||||
|
ffsw.isEnabled = scrollY == 0
|
||||||
|
}
|
||||||
|
ffsw.apply {
|
||||||
|
setOnRefreshListener {
|
||||||
|
ad.refresh()
|
||||||
|
isRefreshing = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ffms.apply {
|
ffms.apply {
|
||||||
setAdapterLayoutManager(LinearLayoutManager(this@MainActivity))
|
setAdapterLayoutManager(LinearLayoutManager(this@MainActivity))
|
||||||
val adapter = ViewData(findViewById(R.id.search_recycler_view)).RecyclerViewAdapter()
|
val adapter = SearchViewHolder(findViewById(R.id.search_recycler_view)).RecyclerViewAdapter()
|
||||||
setAdapter(adapter)
|
setAdapter(adapter)
|
||||||
navigationIconSupport = SearchLayout.NavigationIconSupport.SEARCH
|
navigationIconSupport = SearchLayout.NavigationIconSupport.SEARCH
|
||||||
setOnNavigationClickListener(object : SearchLayout.OnNavigationClickListener {
|
setOnNavigationClickListener(object : SearchLayout.OnNavigationClickListener {
|
||||||
override fun onNavigationClick(hasFocus: Boolean) {
|
override fun onNavigationClick(hasFocus: Boolean) {
|
||||||
if (hasFocus()) clearFocus()
|
if (hasFocus()) {
|
||||||
|
if(hasLiked) ad.refresh()
|
||||||
|
clearFocus()
|
||||||
|
}
|
||||||
else requestFocus()
|
else requestFocus()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setTextHint(android.R.string.search_go)
|
setTextHint(android.R.string.search_go)
|
||||||
setOnQueryTextListener(object : SearchLayout.OnQueryTextListener {
|
setOnQueryTextListener(object : SearchLayout.OnQueryTextListener {
|
||||||
val sysTime get() = System.currentTimeMillis() / 1000
|
|
||||||
var lastVisitTime = sysTime
|
|
||||||
val isLast get() = sysTime - lastVisitTime > 1
|
|
||||||
var hasLoad = true
|
|
||||||
var key: CharSequence = ""
|
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
lastVisitTime = sysTime
|
|
||||||
hasLoad = false
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
Thread {
|
|
||||||
while (true) {
|
|
||||||
sleep(1)
|
|
||||||
if (isLast && !hasLoad) {
|
|
||||||
adapter.filter(key)
|
|
||||||
hasLoad = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onQueryTextChange(newText: CharSequence): Boolean {
|
override fun onQueryTextChange(newText: CharSequence): Boolean {
|
||||||
if (newText.isNotEmpty()) key = newText
|
if (newText.isNotEmpty()) adapter.filter(newText)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextSubmit(query: CharSequence): Boolean {
|
override fun onQueryTextSubmit(query: CharSequence): Boolean {
|
||||||
if(query.isNotEmpty()) Thread{
|
if(query.isNotEmpty()) {
|
||||||
val data = dict[query]
|
val key = query.toString()
|
||||||
runOnUiThread {
|
val data = dict[key]
|
||||||
showDictAlert(query.toString(), data)
|
showDictAlert(key, data)
|
||||||
}
|
}
|
||||||
}.start()
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setOnMicClickListener(object : SearchLayout.OnMicClickListener {
|
setOnMicClickListener(object : SearchLayout.OnMicClickListener {
|
||||||
override fun onMicClick() {
|
override fun onMicClick() {
|
||||||
if (SearchUtils.isVoiceSearchAvailable(this@MainActivity)) {
|
if (SearchUtils.isVoiceSearchAvailable(this@MainActivity)) {
|
||||||
SearchUtils.setVoiceSearch(this@MainActivity, "speak")
|
SearchUtils.setVoiceSearch(this@MainActivity, "please speak")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -99,11 +87,28 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if(ffms.hasFocus()) ffms.clearFocus()
|
if(ffms.hasFocus()) {
|
||||||
|
if(hasLiked) (ffr.adapter as ListViewHolder.RecyclerViewAdapter).refresh()
|
||||||
|
ffms.clearFocus()
|
||||||
|
}
|
||||||
else super.onBackPressed()
|
else super.onBackPressed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if(it.isNotEmpty()) {
|
||||||
|
ffms.requestFocus()
|
||||||
|
ffms.mSearchEditText?.setText(it[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showDictAlert(key: String, data: String?) {
|
private fun showDictAlert(key: String, data: String?) {
|
||||||
|
val like = getSharedPreferences("dict", MODE_PRIVATE)?.contains(key)?:false
|
||||||
|
hasLiked = false
|
||||||
AlertDialog.Builder(this@MainActivity)
|
AlertDialog.Builder(this@MainActivity)
|
||||||
.setTitle(key)
|
.setTitle(key)
|
||||||
.setMessage(data)
|
.setMessage(data)
|
||||||
@@ -120,55 +125,82 @@ class MainActivity : AppCompatActivity() {
|
|||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
.setNeutralButton("收藏") { _, _ ->
|
.setNeutralButton(if(like) "取消收藏" else "收藏") { _, _ ->
|
||||||
getSharedPreferences("dict", MODE_PRIVATE)?.edit()?.let {
|
getSharedPreferences("dict", MODE_PRIVATE)?.edit()?.apply {
|
||||||
it.putString(key, data)
|
if(like) remove(key) else putString(key, data)
|
||||||
it.apply()
|
hasLiked = true
|
||||||
|
apply()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewData(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class SearchViewHolder(itemView: View) : ListViewHolder(itemView) {
|
||||||
inner class RecyclerViewAdapter :
|
inner class RecyclerViewAdapter : ListViewHolder.RecyclerViewAdapter() {
|
||||||
RecyclerView.Adapter<ViewData>() {
|
override fun getValue(key: String) = dict[key]
|
||||||
var count = 0
|
fun filter(text: CharSequence) {
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewData {
|
Thread{
|
||||||
return ViewData(
|
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
|
||||||
|
}
|
||||||
|
listKeys = selectSet.toList()
|
||||||
|
listKeys?.forEach {
|
||||||
|
Log.d("MyMain", "Select key: $it")
|
||||||
|
}
|
||||||
|
runOnUiThread { notifyDataSetChanged() }
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open inner class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
open inner class RecyclerViewAdapter :
|
||||||
|
RecyclerView.Adapter<ListViewHolder>() {
|
||||||
|
var listKeys = getKeys()
|
||||||
|
open fun getKeys(): List<String>? = null
|
||||||
|
open fun getValue(key: String): String? = null
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
|
||||||
|
return ListViewHolder(
|
||||||
LayoutInflater.from(parent.context)
|
LayoutInflater.from(parent.context)
|
||||||
.inflate(R.layout.line_word, parent, false)
|
.inflate(R.layout.line_word, parent, false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
|
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: ViewData, position: Int) {
|
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
|
||||||
Log.d("MyMain", "Bind $position")
|
Log.d("MyMain", "Bind like at $position")
|
||||||
if(position < keys.size) {
|
listKeys?.apply {
|
||||||
holder.itemView.ta.text = keys[position]
|
if (position < size) {
|
||||||
if(position < datas.size) holder.itemView.tb.text = datas[position]
|
val key = get(position)
|
||||||
holder.itemView.setOnClickListener {
|
val data = getValue(key)
|
||||||
showDictAlert(keys[position], if(position < datas.size) datas[position] else "null")
|
holder.itemView.apply {
|
||||||
|
ta.text = key
|
||||||
|
tb.text = data
|
||||||
|
setOnClickListener {
|
||||||
|
showDictAlert(key, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount() = count
|
override fun getItemCount() = listKeys?.size?:0
|
||||||
|
|
||||||
fun filter(text: CharSequence) {
|
fun refresh() {
|
||||||
dict.pattern = text
|
listKeys = getKeys()
|
||||||
dict.keys.let {
|
|
||||||
count = it.size
|
|
||||||
if (count > 0) {
|
|
||||||
keys = arrayOf()
|
|
||||||
datas = arrayOf()
|
|
||||||
it.forEach {
|
|
||||||
keys += it
|
|
||||||
datas += dict[it]
|
|
||||||
Log.d("MyMain", "Get key: $it is ${datas.last()}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
runOnUiThread { notifyDataSetChanged() }
|
runOnUiThread { notifyDataSetChanged() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,97 @@
|
|||||||
package top.fumiama.simpledict
|
package top.fumiama.simpledict
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import java.lang.Thread.sleep
|
import java.lang.Thread.sleep
|
||||||
|
|
||||||
class SimpleDict(private val client: Client): HashMap<String, String>() { //must run in thread
|
class SimpleDict(private val client: Client, private val pwd: String) { //must run in thread
|
||||||
var pattern: CharSequence = "a"
|
private var dict = HashMap<String, String?>()
|
||||||
private var isInit = true
|
val keys get() = dict.keys
|
||||||
override val keys: MutableSet<String>
|
val values get() = dict.values
|
||||||
|
//val size get() = dict.size
|
||||||
|
private val raw: ByteArray?
|
||||||
get() {
|
get() {
|
||||||
val re = mutableSetOf<String>()
|
initDict()
|
||||||
if(isInit) {
|
client.sendMessage("cat")
|
||||||
isInit = false
|
sleep(233)
|
||||||
return re
|
val re = client.receiveRawMessage()
|
||||||
} else {
|
closeDict()
|
||||||
client.initConnect()
|
return re
|
||||||
client.sendMessage("lst")
|
|
||||||
sleep(233)
|
|
||||||
client.receiveMessage()
|
|
||||||
client.sendMessage(pattern)
|
|
||||||
client.receiveMessage()?.substringBeforeLast('\n')?.split('\n')?.forEach {
|
|
||||||
re.add(it)
|
|
||||||
}
|
|
||||||
client.sendMessage("quit")
|
|
||||||
client.closeConnect()
|
|
||||||
return re
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(key: String): String? {
|
init {
|
||||||
|
Thread{ fetchDict() }.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initDict() {
|
||||||
client.initConnect()
|
client.initConnect()
|
||||||
|
client.sendMessage(pwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun closeDict() {
|
||||||
|
client.sendMessage("quit")
|
||||||
|
client.closeConnect()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun analyzeDictBlk(dictBlock: ByteArray) {
|
||||||
|
Log.d("MySD", "Read block: ${dictBlock.decodeToString()}")
|
||||||
|
val keyLen = dictBlock[63].toInt().let { if (it > 63) 63 else it }
|
||||||
|
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
|
||||||
|
Log.d("MySD", "Fetch $key=$data")
|
||||||
|
}
|
||||||
|
|
||||||
|
//fun filterKeys(predicate: (String) -> Boolean) = dict.filterKeys(predicate)
|
||||||
|
fun filterValues(predicate: (String?) -> Boolean) = dict.filterValues(predicate)
|
||||||
|
|
||||||
|
fun fetchDict() {
|
||||||
|
val dictBlock = ByteArray(128)
|
||||||
|
raw?.inputStream()?.let {
|
||||||
|
var c = '1'
|
||||||
|
while (!it.read().toChar().isDigit()) Log.d("MySD", "Skip banner.")
|
||||||
|
while (c.isDigit()) {
|
||||||
|
c = it.read().toChar()
|
||||||
|
Log.d("MySD", "Skip digit $c.")
|
||||||
|
}
|
||||||
|
dictBlock[0] = c.toByte()
|
||||||
|
if(it.read(dictBlock, 1, 127) == 127) {
|
||||||
|
analyzeDictBlk(dictBlock)
|
||||||
|
while (it.read(dictBlock, 0, 128) == 128) analyzeDictBlk(dictBlock)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*fun keysWithPattern(pattern: String): MutableSet<String>{
|
||||||
|
val re = mutableSetOf<String>()
|
||||||
|
initDict()
|
||||||
|
client.sendMessage("lst")
|
||||||
|
sleep(233)
|
||||||
|
client.receiveMessage()
|
||||||
|
client.sendMessage(pattern)
|
||||||
|
client.receiveMessage()?.substringBeforeLast('\n')?.split('\n')?.forEach {
|
||||||
|
re.add(it)
|
||||||
|
}
|
||||||
|
closeDict()
|
||||||
|
return re
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getDirectly(key: String): String? {
|
||||||
|
initDict()
|
||||||
client.sendMessage("get")
|
client.sendMessage("get")
|
||||||
sleep(233)
|
sleep(233)
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
client.sendMessage(key)
|
client.sendMessage(key)
|
||||||
val re = client.receiveMessage()
|
val re = client.receiveMessage()
|
||||||
client.sendMessage("quit")
|
closeDict()
|
||||||
client.closeConnect()
|
|
||||||
return re
|
return re
|
||||||
}
|
}*/
|
||||||
|
|
||||||
override fun put(key: String, value: String): String? {
|
operator fun get(key: String) = dict[key]
|
||||||
val p = this[key]
|
|
||||||
client.initConnect()
|
operator fun set(key: String, value: String): String? {
|
||||||
|
val p = dict[key]
|
||||||
|
initDict()
|
||||||
client.sendMessage("set")
|
client.sendMessage("set")
|
||||||
sleep(233)
|
sleep(233)
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
@@ -48,8 +99,7 @@ class SimpleDict(private val client: Client): HashMap<String, String>() { //mu
|
|||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
client.sendMessage(value)
|
client.sendMessage(value)
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
client.sendMessage("quit")
|
closeDict()
|
||||||
client.closeConnect()
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
app/src/main/res/font/gotham.ttf
Normal file
BIN
app/src/main/res/font/gotham.ttf
Normal file
Binary file not shown.
@@ -1,13 +1,50 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".MainActivity">
|
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
|
||||||
<com.lapism.search.widget.MaterialSearchView
|
|
||||||
android:id="@+id/ffms"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:contentScrim="?attr/colorSurface"
|
||||||
|
|
||||||
|
app:toolbarId="@+id/toolbar">
|
||||||
|
|
||||||
|
<com.lapism.search.widget.MaterialSearchView
|
||||||
|
android:id="@+id/ffms"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_behavior="com.lapism.search.widget.SearchBehavior" />
|
||||||
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/ffsw"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||||
|
|
||||||
|
<androidx.core.widget.NestedScrollView
|
||||||
|
android:id="@+id/ffns"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/ffr"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@@ -15,9 +15,10 @@
|
|||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
|
android:fontFamily="@font/gotham"
|
||||||
android:text="TextView"
|
android:text="TextView"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
android:textColor="?attr/colorOnSurface"
|
||||||
android:textSize="18sp" />
|
android:textSize="22sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tb"
|
android:id="@+id/tb"
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Reference in New Issue
Block a user