mirror of
https://github.com/fumiama/simple-dict-android.git
synced 2026-06-10 21:24:20 +08:00
v1.3
This commit is contained in:
7
.idea/dictionaries/spayi.xml
generated
Normal file
7
.idea/dictionaries/spayi.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="spayi">
|
||||||
|
<words>
|
||||||
|
<w>recv</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
@@ -13,8 +13,9 @@ android {
|
|||||||
applicationId "top.fumiama.simpledict"
|
applicationId "top.fumiama.simpledict"
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 4
|
versionCode 5
|
||||||
versionName '1.2'
|
versionName '1.3'
|
||||||
|
resConfigs "zh", "zh-rCN"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.io.InputStream
|
|||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.net.Socket
|
import java.net.Socket
|
||||||
|
|
||||||
class Client(val ip: String, val port: Int) {
|
class Client(private val ip: String, private val port: Int) {
|
||||||
//普通数据交互接口
|
//普通数据交互接口
|
||||||
private var sc: Socket? = null
|
private var sc: Socket? = null
|
||||||
|
|
||||||
@@ -15,23 +15,22 @@ class Client(val ip: String, val port: Int) {
|
|||||||
private var din: InputStream? = null
|
private var din: InputStream? = null
|
||||||
|
|
||||||
//已连接标记
|
//已连接标记
|
||||||
var isConnect = false
|
private val isConnect get() = sc != null && din != null && dout != null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化普通交互连接
|
* 初始化普通交互连接
|
||||||
*/
|
*/
|
||||||
fun initConnect(){
|
fun initConnect(depth: Int = 0){
|
||||||
try {
|
if(depth > 3) Log.d("MyC", "connect server failed after $depth tries")
|
||||||
|
else try {
|
||||||
sc = Socket(ip, port) //通过socket连接服务器
|
sc = Socket(ip, port) //通过socket连接服务器
|
||||||
din = sc?.getInputStream() //获取输入流并转换为StreamReader,约定编码格式
|
din = sc?.getInputStream() //获取输入流并转换为StreamReader,约定编码格式
|
||||||
dout = sc?.getOutputStream() //获取输出流
|
dout = sc?.getOutputStream() //获取输出流
|
||||||
sc?.soTimeout = 10000 //设置连接超时限制
|
sc?.soTimeout = 2333 //设置连接超时限制
|
||||||
if (sc != null && din != null && dout != null) { //判断一下是否都连上,避免NullPointException
|
if (isConnect) Log.d("MyC", "connect server successful")
|
||||||
isConnect = true
|
else {
|
||||||
Log.d("MyC", "connect server successful")
|
Log.d("MyC", "connect server failed, now retry...")
|
||||||
} else {
|
initConnect(depth + 1)
|
||||||
Log.d("MyC", "connect server failed,now retry...")
|
|
||||||
initConnect()
|
|
||||||
}
|
}
|
||||||
} catch (e: IOException) { //获取输入输出流是可能报IOException的,所以必须try-catch
|
} catch (e: IOException) { //获取输入输出流是可能报IOException的,所以必须try-catch
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@@ -45,30 +44,31 @@ class Client(val ip: String, val port: Int) {
|
|||||||
fun sendMessage(message: CharSequence?) {
|
fun sendMessage(message: CharSequence?) {
|
||||||
try {
|
try {
|
||||||
if (isConnect) {
|
if (isConnect) {
|
||||||
if (dout != null && message != null) { //判断输出流或者消息是否为空,为空的话会产生nullpoint错误
|
if (message != null) { //判断输出流或者消息是否为空,为空的话会产生nullpoint错误
|
||||||
dout!!.write(message.toString().toByteArray())
|
dout?.write(message.toString().toByteArray())
|
||||||
dout!!.flush()
|
dout?.flush()
|
||||||
} else Log.d("MyC", "The message to be sent is empty or have no connect")
|
Log.d("MyC", "Send msg: $message")
|
||||||
|
} else Log.d("MyC", "The message to be sent is empty")
|
||||||
Log.d("MyC", "send message succeed")
|
Log.d("MyC", "send message succeed")
|
||||||
} else Log.d("MyC", "no connect to send message")
|
} else Log.d("MyC", "send message failed: no connect")
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.d("MyC", "send message to cilent failed")
|
Log.d("MyC", "send message failed: crash")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun receiveRawMessage() : ByteArray {
|
fun receiveRawMessage(totalSize: Int = -1, bufferSize: Int = 4096) : ByteArray {
|
||||||
var re = byteArrayOf()
|
var re = byteArrayOf()
|
||||||
try {
|
try {
|
||||||
if (isConnect) {
|
if (isConnect) {
|
||||||
Log.d("MyC", "开始接收服务端信息")
|
Log.d("MyC", "开始接收服务端信息")
|
||||||
val inMessage = ByteArray(4096) //设置接受缓冲,避免接受数据过长占用过多内存
|
val inMessage = ByteArray(bufferSize) //设置接受缓冲,避免接受数据过长占用过多内存
|
||||||
var a: Int
|
var a: Int
|
||||||
do {
|
do {
|
||||||
a = din?.read(inMessage)?:0 //a存储返回消息的长度
|
a = din?.read(inMessage)?:0 //a存储返回消息的长度
|
||||||
Log.d("MyC", "reply length:$a: ${inMessage.decodeToString()}")
|
|
||||||
re += inMessage.copyOf(a)
|
re += inMessage.copyOf(a)
|
||||||
} while (a == 4096)
|
Log.d("MyC", "reply length:$a: ${re.decodeToString()}")
|
||||||
|
} while (a == bufferSize || totalSize > re.size)
|
||||||
} else Log.d("MyC", "no connect to receive message")
|
} else Log.d("MyC", "no connect to receive message")
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.d("MyC", "receive message failed")
|
Log.d("MyC", "receive message failed")
|
||||||
@@ -87,10 +87,12 @@ class Client(val ip: String, val port: Int) {
|
|||||||
din?.close()
|
din?.close()
|
||||||
dout?.close()
|
dout?.close()
|
||||||
sc?.close()
|
sc?.close()
|
||||||
|
sc = null
|
||||||
|
din = null
|
||||||
|
dout = null
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
isConnect = false
|
|
||||||
Log.d("MyC", "关闭连接")
|
Log.d("MyC", "关闭连接")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ 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.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.textfield.TextInputLayout
|
||||||
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.*
|
||||||
@@ -21,6 +23,14 @@ import kotlinx.android.synthetic.main.line_word.view.*
|
|||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
private val dict = SimpleDict(Client("127.0.0.1", 8000), "fumiama")
|
private val dict = SimpleDict(Client("127.0.0.1", 8000), "fumiama")
|
||||||
private var hasLiked = false
|
private var hasLiked = false
|
||||||
|
private val fetchThread get() = Thread{
|
||||||
|
dict.fetchDict {
|
||||||
|
runOnUiThread {
|
||||||
|
Toast.makeText(this@MainActivity, "刷新成功", Toast.LENGTH_SHORT).show()
|
||||||
|
ffsw.isRefreshing = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -35,8 +45,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
ffsw.apply {
|
ffsw.apply {
|
||||||
setOnRefreshListener {
|
setOnRefreshListener {
|
||||||
ad.refresh()
|
ad.refresh()
|
||||||
isRefreshing = false
|
fetchThread.start()
|
||||||
}
|
}
|
||||||
|
isRefreshing = true
|
||||||
|
fetchThread.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,15 +119,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showDictAlert(key: String, data: String?) {
|
private fun showDictAlert(key: String, data: String?) {
|
||||||
val like = getSharedPreferences("dict", MODE_PRIVATE)?.contains(key)?:false
|
val hintAdd = if(data != null && data != "null") "重设" else "添加"
|
||||||
hasLiked = false
|
hasLiked = false
|
||||||
AlertDialog.Builder(this@MainActivity)
|
AlertDialog.Builder(this@MainActivity)
|
||||||
.setTitle(key)
|
.setTitle(key)
|
||||||
.setMessage(data)
|
.setMessage(data)
|
||||||
.setPositiveButton(if(data != "null") "重设" else "添加") { _, _ ->
|
.setPositiveButton(hintAdd) { _, _ ->
|
||||||
val t = EditText(this@MainActivity)
|
val t = EditText(this@MainActivity)
|
||||||
AlertDialog.Builder(this@MainActivity)
|
AlertDialog.Builder(this@MainActivity)
|
||||||
.setTitle("重设$key")
|
.setTitle("$hintAdd$key")
|
||||||
.setView(t)
|
.setView(t)
|
||||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
if (t.text.isNotEmpty()) Thread {
|
if (t.text.isNotEmpty()) Thread {
|
||||||
@@ -125,12 +137,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
.setNeutralButton(if(like) "取消收藏" else "收藏") { _, _ ->
|
.setNeutralButton("删除") { _, _ ->
|
||||||
getSharedPreferences("dict", MODE_PRIVATE)?.edit()?.apply {
|
Thread{dict -= key}.start()
|
||||||
if(like) remove(key) else putString(key, data)
|
|
||||||
hasLiked = true
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
.setNegativeButton(android.R.string.cancel) { _, _ -> }
|
||||||
.show()
|
.show()
|
||||||
@@ -182,19 +190,38 @@ class MainActivity : AppCompatActivity() {
|
|||||||
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
|
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
|
||||||
Log.d("MyMain", "Bind like at $position")
|
Log.d("MyMain", "Bind like at $position")
|
||||||
listKeys?.apply {
|
Thread{
|
||||||
if (position < size) {
|
listKeys?.apply {
|
||||||
val key = get(position)
|
if (position < size) {
|
||||||
val data = getValue(key)
|
val key = get(position)
|
||||||
holder.itemView.apply {
|
val data = getValue(key)
|
||||||
ta.text = key
|
val like = getSharedPreferences("dict", MODE_PRIVATE)?.contains(key) == true
|
||||||
tb.text = data
|
runOnUiThread {
|
||||||
setOnClickListener {
|
holder.itemView.apply {
|
||||||
showDictAlert(key, data)
|
ta.text = key
|
||||||
|
tb.text = data
|
||||||
|
if(like) vl.setBackgroundResource(R.drawable.ic_like_filled)
|
||||||
|
setOnClickListener {
|
||||||
|
showDictAlert(key, data)
|
||||||
|
}
|
||||||
|
vl.setOnClickListener {
|
||||||
|
getSharedPreferences("dict", MODE_PRIVATE)?.edit()?.apply {
|
||||||
|
if(like) {
|
||||||
|
remove(key)
|
||||||
|
it.setBackgroundResource(R.drawable.ic_like)
|
||||||
|
} else {
|
||||||
|
putString(key, data)
|
||||||
|
it.setBackgroundResource(R.drawable.ic_like_filled)
|
||||||
|
}
|
||||||
|
hasLiked = true
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount() = listKeys?.size?:0
|
override fun getItemCount() = listKeys?.size?:0
|
||||||
|
|||||||
@@ -10,21 +10,44 @@ class SimpleDict(private val client: Client, private val pwd: String) { //must
|
|||||||
//val size get() = dict.size
|
//val size get() = dict.size
|
||||||
private val raw: ByteArray
|
private val raw: ByteArray
|
||||||
get() {
|
get() {
|
||||||
initDict()
|
var times = 3
|
||||||
client.sendMessage("cat")
|
var re: ByteArray
|
||||||
sleep(2333)
|
var firstRecv: ByteArray
|
||||||
val re = client.receiveRawMessage()
|
do {
|
||||||
closeDict()
|
re = byteArrayOf()
|
||||||
|
initDict()
|
||||||
|
sendMessageWithDelay("cat", 2333)
|
||||||
|
try {
|
||||||
|
firstRecv = client.receiveRawMessage()
|
||||||
|
val firstStr = firstRecv.decodeToString()
|
||||||
|
var length = ""
|
||||||
|
for ((i, c) in firstStr.withIndex()) {
|
||||||
|
if(c.isDigit()) length += c
|
||||||
|
else {
|
||||||
|
if(i + 1 < firstRecv.size) re = firstRecv.copyOfRange(i, firstRecv.size)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
re += client.receiveRawMessage(length.toInt() - re.size)
|
||||||
|
break
|
||||||
|
} catch (e: Exception){
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
closeDict()
|
||||||
|
} while (times-- > 0)
|
||||||
return re
|
return re
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
private fun sendMessageWithDelay(msg: CharSequence, delay: Long = 233) = Thread{
|
||||||
Thread{ fetchDict() }.start()
|
client.sendMessage(msg)
|
||||||
}
|
sleep(delay)
|
||||||
|
}.start()
|
||||||
|
|
||||||
private fun initDict() {
|
private fun initDict() {
|
||||||
client.initConnect()
|
client.initConnect()
|
||||||
client.sendMessage(pwd)
|
client.sendMessage(pwd)
|
||||||
|
client.receiveRawMessage()
|
||||||
|
sleep(233)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun closeDict() {
|
private fun closeDict() {
|
||||||
@@ -45,59 +68,36 @@ class SimpleDict(private val client: Client, private val pwd: String) { //must
|
|||||||
//fun filterKeys(predicate: (String) -> Boolean) = dict.filterKeys(predicate)
|
//fun filterKeys(predicate: (String) -> Boolean) = dict.filterKeys(predicate)
|
||||||
fun filterValues(predicate: (String?) -> Boolean) = dict.filterValues(predicate)
|
fun filterValues(predicate: (String?) -> Boolean) = dict.filterValues(predicate)
|
||||||
|
|
||||||
fun fetchDict() {
|
fun fetchDict(doOnLoadSuccess: ()->Unit = {
|
||||||
|
Log.d("MySD", "Fetch dict success")
|
||||||
|
}) {
|
||||||
val dictBlock = ByteArray(128)
|
val dictBlock = ByteArray(128)
|
||||||
|
dict = hashMapOf()
|
||||||
raw.inputStream().let {
|
raw.inputStream().let {
|
||||||
var c = '1'
|
while (it.read(dictBlock, 0, 128) == 128) analyzeDictBlk(dictBlock)
|
||||||
while (!it.read().toChar().isDigit()) Log.d("MySD", "Skip banner.")
|
doOnLoadSuccess()
|
||||||
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>{
|
operator fun minusAssign(key: String) {
|
||||||
val re = mutableSetOf<String>()
|
|
||||||
initDict()
|
initDict()
|
||||||
client.sendMessage("lst")
|
sendMessageWithDelay("del")
|
||||||
sleep(233)
|
client.receiveMessage()
|
||||||
|
sendMessageWithDelay(key)
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
client.sendMessage(pattern)
|
|
||||||
client.receiveMessage()?.substringBeforeLast('\n')?.split('\n')?.forEach {
|
|
||||||
re.add(it)
|
|
||||||
}
|
|
||||||
closeDict()
|
closeDict()
|
||||||
return re
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDirectly(key: String): String? {
|
|
||||||
initDict()
|
|
||||||
client.sendMessage("get")
|
|
||||||
sleep(233)
|
|
||||||
client.receiveMessage()
|
|
||||||
client.sendMessage(key)
|
|
||||||
val re = client.receiveMessage()
|
|
||||||
closeDict()
|
|
||||||
return re
|
|
||||||
}*/
|
|
||||||
|
|
||||||
operator fun get(key: String) = dict[key]
|
operator fun get(key: String) = dict[key]
|
||||||
|
|
||||||
operator fun set(key: String, value: String): String? {
|
operator fun set(key: String, value: String): String? {
|
||||||
val p = dict[key]
|
val p = dict[key]
|
||||||
initDict()
|
initDict()
|
||||||
client.sendMessage("set")
|
sendMessageWithDelay("set")
|
||||||
sleep(233)
|
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
client.sendMessage(key)
|
sendMessageWithDelay(key)
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
client.sendMessage(value)
|
sendMessageWithDelay(value)
|
||||||
client.receiveMessage()
|
client.receiveMessage()
|
||||||
closeDict()
|
closeDict()
|
||||||
dict[key] = value
|
dict[key] = value
|
||||||
|
|||||||
10
app/src/main/res/drawable-anydpi/ic_like.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_like.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="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportHeight="1024"
|
||||||
|
android:viewportWidth="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/holo_red_light"
|
||||||
|
android:pathData="M668 117C833 117 939 250 939 428c0 138-125 291-372 462a97 97 0 0 1-110 0C210 718 85 566 85 428 85 250 191 117 356 117c60 0 100 21 156 68C568 138 608 117 668 117z m0 63c-41 0-70 15-117 55-2 2-14 12-18 15a32 32 0 0 1-42 0c-4-3-16-14-18-15-47-40-76-55-117-55C230 180 149 281 149 427 149 538 263 675 494 835a32 32 0 0 0 37 0C761 675 875 538 875 427c0-145-81-246-207-246z"/>
|
||||||
|
</vector>
|
||||||
10
app/src/main/res/drawable-anydpi/ic_like_filled.xml
Normal file
10
app/src/main/res/drawable-anydpi/ic_like_filled.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="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportHeight="1024"
|
||||||
|
android:viewportWidth="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/holo_red_light"
|
||||||
|
android:pathData="M668 117C833 117 939 250 939 428c0 138-125 291-372 462a97 97 0 0 1-110 0C210 718 85 566 85 428 85 250 191 117 356 117c60 0 100 21 156 68C568 138 608 117 668 117z"/>
|
||||||
|
</vector>
|
||||||
@@ -1,32 +1,33 @@
|
|||||||
<?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:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
|
||||||
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?attr/colorSurface">
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
app:contentScrim="?attr/colorSurface"
|
android:fillViewport="true"
|
||||||
|
app:layout_scrollFlags="scroll">
|
||||||
|
|
||||||
app:layout_scrollFlags="scroll"
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
app:toolbarId="@+id/toolbar">
|
|
||||||
|
|
||||||
<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="match_parent"
|
||||||
app:layout_behavior="com.lapism.search.widget.SearchBehavior" />
|
app:contentScrim="?attr/colorSurface"
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
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>
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
@@ -46,6 +47,4 @@
|
|||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
@@ -1,31 +1,50 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
android:foreground="?android:attr/selectableItemBackground">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
<View
|
||||||
android:id="@+id/ta"
|
android:id="@+id/vl"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="32dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="32dp"
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:fontFamily="@font/gotham"
|
android:background="@drawable/ic_like"
|
||||||
android:text="TextView"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:textColor="?attr/colorOnSurface"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:textSize="22sp" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"/>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/tb"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginStart="16dp"
|
android:orientation="vertical">
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
<TextView
|
||||||
android:layout_marginBottom="8dp"
|
android:id="@+id/ta"
|
||||||
android:text="TextView" />
|
android:layout_width="match_parent"
|
||||||
</LinearLayout>
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:fontFamily="@font/gotham"
|
||||||
|
android:textColor="?attr/colorOnSurface"
|
||||||
|
android:textSize="22sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tb"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
<!-- Primary brand color. -->
|
<!-- Primary brand color. -->
|
||||||
<item name="colorPrimary">@color/purple_200</item>
|
<item name="colorPrimary">@color/purple_200</item>
|
||||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||||
<item name="colorOnPrimary">@color/black</item>
|
<item name="colorOnPrimary">@android:color/black</item>
|
||||||
<!-- Secondary brand color. -->
|
<!-- Secondary brand color. -->
|
||||||
<item name="colorSecondary">@color/teal_200</item>
|
<item name="colorSecondary">@color/teal_200</item>
|
||||||
<item name="colorSecondaryVariant">@color/teal_200</item>
|
<item name="colorSecondaryVariant">@color/teal_200</item>
|
||||||
<item name="colorOnSecondary">@color/black</item>
|
<item name="colorOnSecondary">@android:color/black</item>
|
||||||
<!-- Status bar color. -->
|
<!-- Status bar color. -->
|
||||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||||
<!-- Customize your theme here. -->
|
<!-- Customize your theme here. -->
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="purple_200">#FFBB86FC</color>
|
<color name="purple_200">#FFBB86FC</color>
|
||||||
<color name="purple_500">#FF6200EE</color>
|
|
||||||
<color name="purple_700">#FF3700B3</color>
|
<color name="purple_700">#FF3700B3</color>
|
||||||
<color name="teal_200">#FF03DAC5</color>
|
<color name="teal_200">#FF03DAC5</color>
|
||||||
<color name="teal_700">#FF018786</color>
|
|
||||||
<color name="black">#FF000000</color>
|
|
||||||
<color name="white">#FFFFFFFF</color>
|
|
||||||
<color name="colorPrimary">#BA8D08</color>
|
<color name="colorPrimary">#BA8D08</color>
|
||||||
<color name="colorPrimaryVariant">#FF9800</color>
|
<color name="colorPrimaryVariant">#FF9800</color>
|
||||||
<color name="colorSecondary">#FF845E</color>
|
<color name="colorSecondary">#FF845E</color>
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<dimen name="fab_margin">16dp</dimen>
|
|
||||||
</resources>
|
|
||||||
@@ -1,12 +1,3 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">SimpleDict</string>
|
<string name="app_name">SimpleDict</string>
|
||||||
<string name="action_settings">Settings</string>
|
|
||||||
<!-- Strings used for fragments for navigation -->
|
|
||||||
<string name="first_fragment_label">First Fragment</string>
|
|
||||||
<string name="second_fragment_label">Second Fragment</string>
|
|
||||||
<string name="next">Next</string>
|
|
||||||
<string name="previous">Previous</string>
|
|
||||||
|
|
||||||
<string name="hello_first_fragment">Hello first fragment</string>
|
|
||||||
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
Binary file not shown.
@@ -10,8 +10,8 @@
|
|||||||
{
|
{
|
||||||
"type": "SINGLE",
|
"type": "SINGLE",
|
||||||
"filters": [],
|
"filters": [],
|
||||||
"versionCode": 4,
|
"versionCode": 5,
|
||||||
"versionName": "1.2",
|
"versionName": "1.3",
|
||||||
"outputFile": "app-winrelease.apk"
|
"outputFile": "app-winrelease.apk"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user