UI优化添加搜索历史记录功能

This commit is contained in:
muqing 2024-02-05 11:53:58 +08:00
parent d1a1adae99
commit 290156a322
16 changed files with 800 additions and 276 deletions

View File

@ -142,4 +142,6 @@ dependencies {
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'com.google.android.flexbox:flexbox:3.0.0'
}

View File

@ -2,15 +2,17 @@ package com.coldmint.rust.pro
import android.graphics.Color
import android.os.Bundle
import android.text.Editable
import android.text.Spannable
import android.text.SpannableString
import android.text.TextWatcher
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.SearchView
import android.view.inputmethod.EditorInfo
import androidx.core.view.isVisible
import com.coldmint.rust.core.database.code.CodeDataBase
import com.coldmint.rust.core.database.code.CodeInfo
@ -28,6 +30,29 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
title = getString(R.string.code_table)
setReturnButton()
loadData()
viewBinding.edittext.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(a: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(a: CharSequence?, p1: Int, p2: Int, p3: Int) {
if (a.isNullOrEmpty()) {
loadData()
return
}
loadData(a.toString())
}
override fun afterTextChanged(a: Editable?) {
}
})
viewBinding.edittext.setOnEditorActionListener { v, p1, _ ->
if (p1 == EditorInfo.IME_ACTION_SEARCH) {
if (v?.text.isNullOrEmpty()) {
loadData()
}else
loadData(v?.text.toString())
}
false
}
}
}
@ -43,7 +68,7 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
*/
fun ifNeedFinish() {
private fun ifNeedFinish() {
if (filterMode) {
loadData()
} else {
@ -97,7 +122,7 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
codeDataBase.getCodeDao()
.findCodeByCodeOrTranslateFromSection(key, section.code)
}
if (list == null || list.isEmpty()) {
if (list.isNullOrEmpty()) {
group.remove(section)
} else {
item.add(list)
@ -110,8 +135,12 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
adapter.setTypeNameMap(typeNameMap)
adapter.setSectionMap(sectionMap)
runOnUiThread {
adapter.labelFunction = { index, view, string ->
loadData(section = string)
adapter.labelFunction = { _, _, string ->
// section = string
if (string.isEmpty()) {
loadData()
}
loadData(string)
}
viewBinding.displayView.isVisible = false
viewBinding.progressBar.isVisible = false
@ -128,8 +157,8 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
* 没有找到节
* @param key String?
*/
fun notFindKey(key: String?) {
if (key != null && key.isNotBlank()) {
private fun notFindKey(key: String?) {
if (!key.isNullOrBlank()) {
val tip = String.format(getString(R.string.not_find_code_name), key)
val action = getString(R.string.not_find_units_action)
val start = tip.indexOf(action)
@ -138,7 +167,7 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
spannableString.setSpan(
object : ClickableSpan() {
override fun onClick(p0: View) {
sea.setQuery("", false)
editisVisible(false)
loadData()
}
}, start, start + action.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
@ -153,26 +182,8 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
viewBinding.expandableListView.isVisible = false
viewBinding.progressBar.isVisible = false
}
lateinit var sea: SearchView
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// val inflater = menuInflater
menuInflater.inflate(R.menu.menu_code_table, menu)
val findItem = menu.findItem(R.id.filter_units)
sea = findItem.actionView as SearchView
sea.queryHint = "请输入关键字"
sea.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
// 在这里执行搜索操作
loadData(query)
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
// 在这里更新搜索结果列表
loadData(newText)
return false
}
})
return true
}
@ -180,7 +191,15 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.filter_units -> {
// editisVisible(true)
if (viewBinding.edittext.isVisible) {
if (viewBinding.edittext.text.isNullOrEmpty()) {
loadData()
} else {
loadData(viewBinding.edittext.text.toString())
}
} else {
editisVisible(true)
}
/*
InputDialog(this).setTitle(R.string.filter).setMessage(R.string.filter_tip)
.setInputCanBeEmpty(false).setMaxNumber(20)
@ -197,6 +216,10 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
}
android.R.id.home -> {
if (viewBinding.edittext.isVisible) {
editisVisible(false)
return true
}
ifNeedFinish()
return true
}
@ -204,10 +227,20 @@ class CodeTableActivity : BaseActivity<ActivityCodeTableBinding>() {
return super.onOptionsItemSelected(item)
}
private fun editisVisible(b: Boolean) {
viewBinding.edittext.isVisible = b
if (!b) {
viewBinding.edittext.setText("")
com.coldmint.rust.pro.muqing.gj.ycjp(viewBinding.edittext)
} else {
com.coldmint.rust.pro.muqing.gj.tcjp(viewBinding.edittext)
}
}
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
if (sea != null && !sea.isIconified) {
sea.isIconified = true
if (viewBinding.edittext.isVisible) {
editisVisible(false)
return
}
ifNeedFinish()

View File

@ -1,72 +0,0 @@
package com.coldmint.rust.pro
import com.coldmint.rust.pro.viewmodel.FileManagerViewModel
import java.io.File
import java.util.Collections
class FileSort(a: MutableList<File?>,sortType: FileManagerViewModel.SortType) {
//内置的类型排序筛选器数据 可以不用 但是类型排序必须要进行筛选才能正常排序
init {
when (sortType) {
FileManagerViewModel.SortType.BY_NAME -> sort_name(a)
FileManagerViewModel.SortType.BY_LAST_MODIFIED -> sort_time(a)
FileManagerViewModel.SortType.BY_SIZE -> sort_size(a)
FileManagerViewModel.SortType.BY_TYPE -> sort_type(a)
}
sort_front(a)
// println(manner)
//一个内置的排序筛选器 也可以在外部调用 com.coldmint.rust.pro.FileSort.sort_front(List<File> a) 等静态的方法
}
companion object {
//0表示 名称排序 1表示 时间排序 2表示 大小排序 3表示类型排序
private fun sort_front(a: MutableList<File?>) {
Collections.sort(a, kotlin.Comparator { o1, o2 ->
if (o1!!.isDirectory && o2!!.isFile) return@Comparator -1
if (o1.isFile && o2!!.isDirectory) return@Comparator 1
else return@Comparator 0
})
}
//文件夹在前面的排序算法 每次sort_name等排序方法前后或者都会调研次方法
fun sort_name(a: MutableList<File?>) {
Collections.sort(a, Comparator { o1, o2 ->
if (o1!!.isDirectory && o2!!.isFile)
return@Comparator -1
if (o1.isFile && o2!!.isDirectory)
return@Comparator 1
else o1.name.compareTo(o2!!.name)
return@Comparator 0
})
}
fun sort_time(a: MutableList<File?>) {
a.sortWith { f1, f2 ->
val diff = f1!!.lastModified() - f2!!.lastModified()
if (diff > 0) 1 else if (diff == 0L) 0 else -1
//如果 if 中修改为 返回-1 同时此处修改为返回 1 排序就会是递减
}
}
fun sort_size(a: MutableList<File?>) {
a.sortWith { o1, o2 ->
val diff = o1!!.length() - o2!!.length()
if (diff > 0) 1
else if (diff == 0L) 0
else -1
}
}
fun sort_type(a: MutableList<File?>) {
//文件类型排序 按照后缀优先级
a.sortWith { o1, o2 ->
val extension1 = o1?.extension?.lowercase()
val extension2 = o2?.extension?.lowercase()
// 定义文件类型的优先级顺序
val typePriority = listOf("txt", "jpg", "png")
val typeIndex1 = typePriority.indexOf(extension1)
val typeIndex2 = typePriority.indexOf(extension2)
typeIndex1.compareTo(typeIndex2)
}
}
}
}

View File

@ -9,6 +9,7 @@ import android.os.Bundle
import cat.ereza.customactivityoncrash.config.CaocConfig
import com.coldmint.rust.core.debug.LogCat
import com.coldmint.rust.core.debug.LogCatObserver
import com.coldmint.rust.pro.muqing.wj
import com.coldmint.rust.pro.tool.AppSettings
import com.google.android.material.color.DynamicColors
import com.google.android.material.color.DynamicColorsOptions
@ -33,6 +34,9 @@ class RustApplication : Application() {
override fun onCreate() {
super.onCreate()
wj(this)
instanceObject = this
AppSettings.initAppSettings(this)
//动态颜色

View File

@ -1,12 +1,17 @@
package com.coldmint.rust.pro
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.ViewGroup
import android.widget.Button
import androidx.appcompat.widget.SearchView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.coldmint.rust.core.dataBean.HotSearchData
import com.coldmint.rust.core.dataBean.SearchSuggestionsData
import com.coldmint.rust.core.interfaces.ApiCallBack
@ -15,12 +20,19 @@ import com.coldmint.rust.pro.adapters.HotSearchAdapter
import com.coldmint.rust.pro.adapters.SearchSuggestionsAdapter
import com.coldmint.rust.pro.base.BaseActivity
import com.coldmint.rust.pro.databinding.ActivitySearchBinding
import com.coldmint.rust.pro.databinding.ItemStringBinding
import com.coldmint.rust.pro.ui.StableLinearLayoutManager
import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
/**
* 搜索界面
*/
class SearchActivity : BaseActivity<ActivitySearchBinding>() {
lateinit var list: MutableList<String>
@SuppressLint("CommitPrefEdits", "NotifyDataSetChanged")
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
title = getString(R.string.search)
setReturnButton()
@ -28,6 +40,76 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>() {
viewBinding.hotSearchView.layoutManager = StableLinearLayoutManager(this)
loadSearchView()
loadHotSearch()
list = getSharedPreferences("lishi", Context.MODE_PRIVATE)
.getStringSet("data", mutableSetOf())
?.toMutableList() ?: mutableListOf()
viewBinding.hotSearchView2.layoutManager = FlexboxLayoutManager(this)
viewBinding.hotSearchView2.adapter = adapter
viewBinding.deleat.setOnClickListener {
MaterialAlertDialogBuilder(this@SearchActivity)
.setTitle("清空所有历史记录")
.setPositiveButton("确定"){ _, _ ->
list.clear()
getSharedPreferences("lishi",
Context.MODE_PRIVATE).edit().putStringSet(
"data", list.toSet()).apply()
adapter.notifyDataSetChanged()
}
.setNegativeButton("取消"){ _, _ ->
}.show()
}
viewBinding.searchView.onActionViewExpanded()
}
@SuppressLint("NotifyDataSetChanged")
private fun additem(string: String) {
list.remove(string)
list.add(0,string)
adapter.notifyDataSetChanged()
// 限制历史记录数量为10
if (list.size > 10) {
list.removeAt(list.lastIndex)
}
val editor = getSharedPreferences("lishi", Context.MODE_PRIVATE).edit()
editor.putStringSet("data", list.toSet())
editor.apply()
}
fun search(string: String) {
val intent = Intent(this@SearchActivity, SearchResultActivity::class.java)
intent.putExtra("key",string)
startActivity(intent)
additem(string)
}
val adapter: RecyclerView.Adapter<VH> = object :RecyclerView.Adapter<VH>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
return VH(ItemStringBinding.bind(
LayoutInflater.from(viewBinding.root.context)
.inflate(R.layout.item_string, parent, false)))
}
override fun onBindViewHolder(holder: VH, position: Int) {
holder.binding.button.text = list[position]
holder.binding.button.setOnClickListener{
val a: Button = it as Button
search(a.text.toString())
}
}
override fun getItemCount() :Int {
viewBinding.textview1Text1.isVisible = list.isEmpty()
return list.size
}
}
class VH(itemView: ItemStringBinding) : RecyclerView.ViewHolder(itemView.root) {
var binding: ItemStringBinding = itemView
}
@ -35,11 +117,9 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>() {
Search.instance.hotSearch(object : ApiCallBack<HotSearchData> {
override fun onResponse(t: HotSearchData) {
val adapter = HotSearchAdapter(this@SearchActivity, t.data)
adapter.setItemEvent { i, itemHotSearchBinding, viewHolder, data ->
adapter.setItemEvent { _, itemHotSearchBinding, _, data ->
itemHotSearchBinding.root.setOnClickListener {
val intent = Intent(this@SearchActivity, SearchResultActivity::class.java)
intent.putExtra("key", data.keyword)
startActivity(intent)
search(data.keyword)
}
}
viewBinding.hotSearchView.adapter = adapter
@ -54,59 +134,52 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>() {
private fun loadSearchView() {
viewBinding.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener,
android.widget.SearchView.OnQueryTextListener {
android.widget.SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
if (query != null && query.isNotBlank()) {
val intent = Intent(this@SearchActivity, SearchResultActivity::class.java)
intent.putExtra("key", query)
startActivity(intent)
if (!query.isNullOrBlank()) {
search(query)
}
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
if (newText != null && newText.isNotBlank()) {
viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_loading)
if (!newText.isNullOrBlank()) {
// viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_loading)
Search.instance.suggestions(newText,
object : ApiCallBack<SearchSuggestionsData> {
override fun onResponse(t: SearchSuggestionsData) {
val dataList = t.data
if (dataList.isEmpty()) {
viewBinding.recyclerView.isVisible = false
viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_null)
} else {
val adapter =
SearchSuggestionsAdapter(
this@SearchActivity,
newText,
dataList
)
adapter.setItemEvent { i, itemSearchSuggestionsBinding, viewHolder, s ->
itemSearchSuggestionsBinding.root.setOnClickListener {
val intent = Intent(
this@SearchActivity,
SearchResultActivity::class.java
)
intent.putExtra("key", s)
startActivity(intent)
object : ApiCallBack<SearchSuggestionsData> {
override fun onResponse(t: SearchSuggestionsData) {
val dataList = t.data
if (dataList.isEmpty()) {
viewBinding.recyclerView.isVisible = false
// viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_null)
} else {
val adapter =
SearchSuggestionsAdapter(
this@SearchActivity,
newText,
dataList
)
adapter.setItemEvent { _, itemSearchSuggestionsBinding, _, s ->
itemSearchSuggestionsBinding.root.setOnClickListener {
search(s)
}
}
viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.isVisible = true
// val s = String.format(getString(R.string.search_suggestions_number),dataList.size)
// viewBinding.searchSuggestionsView.text = s
}
viewBinding.recyclerView.adapter = adapter
viewBinding.recyclerView.isVisible = true
val s = String.format(getString(R.string.search_suggestions_number),dataList.size)
viewBinding.searchSuggestionsView.text = s
}
}
override fun onFailure(e: Exception) {
override fun onFailure(e: Exception) {
viewBinding.recyclerView.isVisible = false
viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_null)
}
viewBinding.recyclerView.isVisible = false
// viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_null)
}
})
})
} else {
viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_null)
// viewBinding.searchSuggestionsView.setText(R.string.search_suggestions_null)
viewBinding.recyclerView.isVisible = false
}
return true
@ -115,8 +188,32 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>() {
})
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val add = menu.add("搜索")
add.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == 0) {
if (!viewBinding.searchView.query.isNullOrBlank()) {
search(viewBinding.searchView.query.toString())
}
}
return super.onOptionsItemSelected(item)
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivitySearchBinding {
return ActivitySearchBinding.inflate(layoutInflater)
}
override fun onBackPressed() {
if (viewBinding.recyclerView.isVisible) {
viewBinding.recyclerView.isVisible = false
return
}
super.onBackPressed()
}
}

View File

@ -43,8 +43,8 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
position: Int
) {
val icon = data.headIcon
Log.d("CommentAdapter", "图标路径" + icon)
if (icon == null || icon.isBlank()) {
Log.d("CommentAdapter", "图标路径$icon")
if (icon.isNullOrBlank()) {
viewBinding.iconView.setImageResource(R.drawable.head_icon)
} else {
Glide.with(context).load(ServerConfiguration.getRealLink(icon))
@ -68,8 +68,7 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
AppOperator.shareText(context, context.getString(R.string.share_message), data.content)
}
viewBinding.contentView.setOnLongClickListener {
GlobalMethod.copyText(context, "", it.rootView)
GlobalMethod.copyText(context, viewBinding.contentView.text.toString())
false
}
viewBinding.moreImageView.setOnClickListener { view ->
@ -78,8 +77,7 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
menu.menu.add(R.string.delete_title)
menu.menu.add(R.string.report)
menu.setOnMenuItemClickListener {
val title = it.title
when (title) {
when (it.title) {
context.getString(R.string.copy) -> {
GlobalMethod.copyText(context, data.content, view)
}
@ -91,7 +89,7 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
)
).setPositiveButton(R.string.dialog_ok) {
val token = AppSettings.getValue(AppSettings.Setting.Token, "")
if (token.isNullOrBlank()) {
if (token.isBlank()) {
Snackbar.make(
view,
context.getString(R.string.please_login_first),
@ -104,7 +102,8 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
object : ApiCallBack<ApiResponse> {
override fun onResponse(t: ApiResponse) {
if (t.code == ServerConfiguration.Success_Code) {
removeItem(viewHolder.adapterPosition)
// removeItem(viewHolder.adapterPosition) 过时的代码
removeItem(viewHolder.layoutPosition)
Snackbar.make(
view,
t.message,
@ -145,8 +144,8 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
}
menu.show()
}
TextStyleMaker.instance.load(viewBinding.contentView, data.content) { type, data ->
TextStyleMaker.instance.clickEvent(context, type, data)
TextStyleMaker.instance.load(viewBinding.contentView, data.content) { type, a ->
TextStyleMaker.instance.clickEvent(context, type, a)
}
}

View File

@ -0,0 +1,122 @@
package com.coldmint.rust.pro.muqing;
import android.annotation.SuppressLint;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Collections;
/** @noinspection unused*/
public class gj {
public static String log_TAB = "铁锈助手";
public static void ts(Context a, Object b) {
Toast.makeText(a, b.toString(), Toast.LENGTH_SHORT).show();
}
public static class ts implements Runnable {
String string;
Context context;
public ts(Context context,String string) {
this.string = string;
this.context = context;
}
@Override
public void run() {
ts(context,string);
}
}
public static void sc(Object a) {
if (a == null) {
a = "null";
}
Log.d(log_TAB, a.toString());
}
public static void fx(Context context, String str) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, str);
context.startActivity(shareIntent);
}
/**
* 复制文字到剪切板
*
*/
public static void fz(Context context, String text) {
ClipboardManager systemService =
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
// 创建能够存入剪贴板的ClipData对象
//Label这是任意文字标签
ClipData mClipData = ClipData.newPlainText("Label", text);
//将ClipData数据复制到剪贴板
systemService.setPrimaryClip(mClipData);
gj.ts(context, "复制成功");
}
public static boolean isWiFiConnected() {
try {
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
if (networkInterface.isUp() && !networkInterface.isLoopback()) {
if (networkInterface.getDisplayName().contains("wlan")) {
return true; // Wi-Fi网络
} else if (networkInterface.getDisplayName().contains("rmnet")) {
return false; // 流量网络
}
}
}
} catch (SocketException e) {
sc(e);
}
return false; // 默认为流量网络
}
public static void tcjp(EditText editText) {
editText.requestFocus();//获取焦点
InputMethodManager imm = (InputMethodManager)
editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
// gj.sc(imm.isActive());
//没有显示键盘弹出
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
public static void ycjp(EditText editText) {
InputMethodManager imm = (InputMethodManager)
editText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive()) //有显示键盘隐藏
imm.hideSoftInputFromWindow(editText.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
public static int getztl(Context context) {
// 获得状态栏高度
@SuppressLint({"InternalInsetResource", "DiscouragedApi"}) int resourceId =
context.getResources().
getIdentifier("status_bar_height", "dimen", "android");
return context.getResources().getDimensionPixelSize(resourceId);
}
public static int getbackgroundColor(AppCompatActivity appCompatActivity) {
TypedArray array = appCompatActivity.getTheme().obtainStyledAttributes(new int[] {
android.R.attr.colorBackground
// android.R.attr.textColorPrimary,
});
int backgroundColor = array.getColor(0, 0xFF00FF);
// int textColor = array.getColor(1, 0xFF00FF);
array.recycle();
return backgroundColor;
}
}

View File

@ -0,0 +1,142 @@
package com.coldmint.rust.pro.muqing;
import android.content.Context;
import android.os.Build;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Objects;
/** @noinspection unused, ResultOfMethodCallIgnored, ResultOfMethodCallIgnored */
public class wj {
public static String filesdri;
public wj(Context context) {
wj.filesdri = Objects.requireNonNull(context.getExternalFilesDir("")).
getAbsolutePath() + "/";
// context.getFilesDir().toString() + "/";
}
/*
* 这里定义的是一个文件保存的方法写入到文件中所以是输出流
* */
public static boolean xrwb(String url, String text) {
if (text == null) {
text = "";
}
File file = new File(url);
//如果文件不存在创建文件
try {
File parentFile = file.getParentFile();
if (!Objects.requireNonNull(parentFile).isDirectory()) {
parentFile.mkdirs();
}
if (!file.exists())
file.createNewFile();
//创建FileOutputStream对象写入内容
FileOutputStream fos = new FileOutputStream(file);
//向文件中写入内容
fos.write(text.getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static String dqwb(String url) {
try {
File file = new File(url);
if (!file.exists()) {
return null;
}
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
StringBuilder str = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
str.append(line);
}
br.close();
fis.close();
return str.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static boolean cz(String url) {
return new File(url).exists();
}
public static boolean sc(String url) {
File file = new File(url);
return file.delete();
}
public static boolean sc(File file, boolean bool) {
if (!bool) {
return file.delete();
}
if (file.exists()) {
File[] files = file.listFiles();
if (files != null) {
for (File a : files) {
// 递归调用删除子文件夹及其内容
// 删除文件
sc(a, a.isDirectory());
}
}
return sc(file, false); // 删除当前文件夹
}
return false;
}
public String convertToMd5(String url) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(url.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte value : messageDigest) {
String hex = Integer.toHexString(0xFF & value);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public static void fz(String sourceFilePath, String targetFilePath) {
File sourceFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
try (InputStream in = Files.newInputStream(sourceFile.toPath());
OutputStream out = Files.newOutputStream(targetFile.toPath())) {
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buf)) > 0) {
out.write(buf, 0, bytesRead);
}
// 文件复制完成
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@ -111,14 +111,14 @@ object GlobalMethod {
//请求设置
val requestOptions = if (transformations.isNotEmpty()) {
val multi = MultiTransformation<Bitmap>(
transformations
transformations
)
RequestOptions.bitmapTransform(multi)
} else {
RequestOptions()
}
requestOptions.placeholder(R.drawable.image)
.error(R.drawable.image_not_supported)
.error(R.drawable.image_not_supported)
return requestOptions
}
@ -130,10 +130,10 @@ object GlobalMethod {
val context = view.context;
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
PopupMenu(
context,
view,
Gravity.NO_GRAVITY,
0, R.style.Widget_Material3_PopupMenu
context,
view,
Gravity.NO_GRAVITY,
0, R.style.Widget_Material3_PopupMenu
)
} else {
PopupMenu(context, view)
@ -164,24 +164,24 @@ object GlobalMethod {
* @param func Function1<String, Unit>
*/
fun showColorPickerDialog(
context: Context,
useARGB: Boolean = false, func: ((String) -> Unit)
context: Context,
useARGB: Boolean = false, func: ((String) -> Unit)
) {
ColorPickerDialogBuilder
.with(context).showAlphaSlider(useARGB)
.setTitle(context.getString(R.string.choose_color))
.initialColor(Color.WHITE)
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(12)
.setOnColorSelectedListener {
//toast("onColorSelected: 0x" + Integer.toHexString(selectedColor));
}
.setPositiveButton(R.string.dialog_ok) { dialog, selectedColor, allColors ->
func.invoke(colorToString(selectedColor, useARGB))
}
.setNegativeButton(R.string.dialog_cancel) { dialog, which -> }
.build()
.show()
.with(context).showAlphaSlider(useARGB)
.setTitle(context.getString(R.string.choose_color))
.initialColor(Color.WHITE)
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(12)
.setOnColorSelectedListener {
//toast("onColorSelected: 0x" + Integer.toHexString(selectedColor));
}
.setPositiveButton(R.string.dialog_ok) { dialog, selectedColor, allColors ->
func.invoke(colorToString(selectedColor, useARGB))
}
.setNegativeButton(R.string.dialog_cancel) { dialog, which -> }
.build()
.show()
}
/**
@ -242,11 +242,11 @@ object GlobalMethod {
stringBuilder.append("\n\n------\n\n")
}
val title =
context.getString(R.string.update_record) + "(" + data.size + ")"
context.getString(R.string.update_record) + "(" + data.size + ")"
MaterialAlertDialogBuilder(context).setTitle(title)
.setMessage(stringBuilder.toString()).setCancelable(false)
.setPositiveButton(R.string.dialog_ok) { i, i2 ->
}.show()
.setMessage(stringBuilder.toString()).setCancelable(false)
.setPositiveButton(R.string.dialog_ok) { i, i2 ->
}.show()
} else {
Toast.makeText(context, t.message, Toast.LENGTH_SHORT).show()
}
@ -260,9 +260,9 @@ object GlobalMethod {
override fun onFailure(e: Exception) {
Toast.makeText(
context,
context.getString(R.string.network_error),
Toast.LENGTH_SHORT
context,
context.getString(R.string.network_error),
Toast.LENGTH_SHORT
).show()
}
@ -277,34 +277,34 @@ object GlobalMethod {
fun requestStoragePermissions(activity: FragmentActivity, requestCompleted: (Boolean) -> Unit) {
val list = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
listOf(
Manifest.permission.MANAGE_EXTERNAL_STORAGE
Manifest.permission.MANAGE_EXTERNAL_STORAGE
)
} else {
listOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
}
PermissionX.init(activity).permissions(
list
list
).onForwardToSettings { scope, deniedList ->
scope.showForwardToSettingsDialog(
deniedList,
activity.getString(R.string.dialog_title),
activity.getString(R.string.dialog_confirm)
)
}
.onExplainRequestReason { scope, deniedList ->
scope.showRequestReasonDialog(
deniedList,
activity.getString(R.string.dialog_title),
activity.getString(R.string.dialog_confirm),
activity.getString(R.string.dialog_cancel)
)
}
.request { allGranted, grantedList, deniedList ->
requestCompleted.invoke(allGranted)
}
activity.getString(R.string.dialog_confirm)
)
}
.onExplainRequestReason { scope, deniedList ->
scope.showRequestReasonDialog(
deniedList,
activity.getString(R.string.dialog_title),
activity.getString(R.string.dialog_confirm),
activity.getString(R.string.dialog_cancel)
)
}
.request { allGranted, grantedList, deniedList ->
requestCompleted.invoke(allGranted)
}
}
@ -339,19 +339,36 @@ object GlobalMethod {
clipboardManager.setPrimaryClip(ClipData.newPlainText("", text))
if (showView != null) {
if (AppSettings.getValue(
AppSettings.Setting.ClipboardCue,
Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2
)
AppSettings.Setting.ClipboardCue,
Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2
)
) {
Snackbar.make(
showView,
String.format(context.getText(R.string.copy_complete).toString(), text),
Snackbar.LENGTH_SHORT
showView,
String.format(context.getText(R.string.copy_complete).toString(), text),
Snackbar.LENGTH_SHORT
).show()
}
}
}
/**
* 复制文本
*
* @param context 上下文环境
* @param text 文本
* @param showView 展示的视图设置为null则不展示提示
*/
fun copyText(context: Context, text: String) {
val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
// When setting the clip board text.
clipboardManager.setPrimaryClip(ClipData.newPlainText("", text))
Toast.makeText(
context,
"已复制", Toast.LENGTH_SHORT
).show()
}
//图像着色
fun tintDrawable(drawable: Drawable?, colors: ColorStateList?): Drawable {
val wrappedDrawable = DrawableCompat.wrap(drawable!!)

View File

@ -0,0 +1,135 @@
package com.coldmint.rust.pro.ui;
import android.content.Context;
import android.text.Editable;
import android.text.NoCopySpan;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.coldmint.rust.pro.R;
public class Edit extends LinearLayout {
public Edit(@NonNull Context context) {
super(context);
initView();
}
AttributeSet attrs;
public Edit(Context context, AttributeSet attrs) {
super(context, attrs);
this.attrs=attrs;
initView();
}
public Edit(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.attrs=attrs;
initView();
}
ImageView chahao;
public EditText editText;
private void initView() {
setGravity(Gravity.CENTER_VERTICAL);
// setBackgroundResource(R.drawable.ui_editview);
setPadding(30, 10, 30, 10);
//构建编辑框
editText = new EditText(getContext());
editText.setHint("搜索");
editText.setSingleLine(true);
editText.setBackground(null);
editText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence var1, int var2, int var3, int var4) {
}
@Override
public void onTextChanged(CharSequence var1, int var2, int var3, int var4) {
iskong();
}
@Override
public void afterTextChanged(Editable var1) {
}
});
ImageView imageView = new ImageView(getContext());
imageView.setImageResource(R.drawable.ic_search_black_24dp);
addView(imageView, (int) TypedValue.applyDimension(TypedValue.
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics())
, (int) TypedValue.applyDimension(TypedValue.
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics()));
LayoutParams layoutParams = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.weight = 1;
layoutParams.gravity = Gravity.CENTER;
addView(editText, layoutParams);
chahao = new ImageView(getContext());
chahao.setImageResource(R.drawable.ic_outline_clear_24);
chahao.setOnClickListener(view -> {
editText.setText("");
view.setVisibility(GONE);
});
addView(chahao, (int) TypedValue.applyDimension(TypedValue.
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics())
, (int) TypedValue.applyDimension(TypedValue.
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics()));
iskong();
}
public void addTextChangedListener(TextWatcher textWatcher) {
editText.addTextChangedListener(textWatcher);
}
public void iskong() {
if (editText.getText().toString().isEmpty()) {
chahao.setVisibility(GONE);
} else {
chahao.setVisibility(VISIBLE);
}
}
@Override
public void setLayoutParams(ViewGroup.LayoutParams params) {
// params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
super.setLayoutParams(params);
// setGravity(Gravity.CENTER_VERTICAL);
}
public void setOnEditorActionListener(TextView.OnEditorActionListener a) {
editText.setOnEditorActionListener(a);
}
public void setText(String s) {
editText.setText(s);
}
public Editable getText() {
return editText.getText();
}
public interface TextWatcher extends NoCopySpan, android.text.TextWatcher {
void beforeTextChanged(CharSequence var1, int var2, int var3, int var4);
void onTextChanged(CharSequence var1, int var2, int var3, int var4);
void afterTextChanged(Editable var1);
}
}

View File

@ -1,7 +1,6 @@
<?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:card_view="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -15,7 +14,18 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
android:layout_height="?attr/actionBarSize">
<EditText
android:id="@+id/edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:hint="@string/search"
android:visibility="gone"
android:imeOptions="actionSearch"
android:autofillHints="text"
android:inputType="text" />
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout

View File

@ -16,88 +16,103 @@
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_height="?attr/actionBarSize">
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Outlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginHorizontal="16dp">
android:layout_height="wrap_content">
<LinearLayout
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:animateLayoutChanges="true"
android:orientation="vertical">
<SearchView
android:id="@+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryBackground="@null"
android:queryHint="@string/search" />
<TextView
android:id="@+id/searchSuggestionsView"
style="@style/TextAppearance.Material3.BodySmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/search_suggestions_null" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone" />
</LinearLayout>
android:iconifiedByDefault="false"
android:queryBackground="@null"
android:queryHint="@string/search" />
</com.google.android.material.card.MaterialCardView>
</com.google.android.material.appbar.MaterialToolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="6dp"
android:layout_marginTop="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginHorizontal="16dp"
android:orientation="vertical">
card_view:ignore="UseCompoundDrawables">
<TextView
android:id="@+id/textview1"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/hotSearch" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hotSearchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp" />
android:layout_weight="1"
android:text="历史记录"
card_view:ignore="HardcodedText" />
<ImageView
android:id="@+id/deleat"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginEnd="6dp"
android:src="@drawable/auto_delete"
card_view:ignore="ContentDescription" />
</LinearLayout>
<TextView
android:id="@+id/textview1_text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="没有任何记录"
android:textSize="20sp"
card_view:ignore="HardcodedText" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hotSearchView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"
android:nestedScrollingEnabled="false" />
<TextView
android:id="@+id/textView2"
style="@style/TextAppearance.Material3.HeadlineMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/hotSearch" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hotSearchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"
android:nestedScrollingEnabled="false" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="16dp"
android:background="?android:colorBackground"
android:paddingTop="16dp"
android:visibility="gone"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -32,7 +32,8 @@
android:orientation="vertical">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:scrollbars="none">
<com.google.android.material.chip.ChipGroup
android:layout_width="0dp"
android:layout_height="wrap_content"

View File

@ -90,6 +90,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:focusableInTouchMode="false"
android:nestedScrollingEnabled="false"
android:visibility="gone" />
</LinearLayout>
@ -119,6 +121,8 @@
android:id="@+id/latestReleaseView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"
android:nestedScrollingEnabled="false"
android:layout_marginTop="8dp" />
</LinearLayout>
@ -148,6 +152,8 @@
android:id="@+id/soleRecommendedRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"
android:nestedScrollingEnabled="false"
android:layout_marginTop="8dp" />
</LinearLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="@+id/button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:strokeWidth="1dp"
android:textColor="@color/dark_background"
android:text="@string/action" />
</RelativeLayout>

View File

@ -5,6 +5,5 @@
android:id="@+id/filter_units"
android:title="@string/filter"
android:icon="@drawable/ic_search_black_24dp"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"/>
android:showAsAction="ifRoom"/>
</menu>