version 1.0.3.1 backup

This commit is contained in:
Simon 2024-08-09 13:40:38 +08:00
parent 508b57593f
commit 50225a3cfe
30 changed files with 674 additions and 226 deletions

View File

@ -94,33 +94,19 @@ dependencies {
implementation("com.google.mlkit:text-recognition-japanese:16.0.0")
// To recognize Korean script
implementation("com.google.mlkit:text-recognition-korean:16.0.0")
// 文本识别
implementation("com.google.mlkit:language-id:17.0.5")
// CameraX core library
implementation(libs.androidx.camera.core)
// CameraX Camera2 extensions
implementation(libs.androidx.camera.camera2)
// CameraX Lifecycle library
implementation(libs.androidx.camera.lifecycle)
// CameraX View class
implementation(libs.androidx.camera.view)
// 文本识别
// To recognize Latin script
// implementation(libs.play.services.mlkit.text.recognition)
// // To recognize Chinese script
// implementation(libs.play.services.mlkit.text.recognition.chinese)
// // To recognize Devanagari script
// implementation(libs.play.services.mlkit.text.recognition.devanagari)
// // To recognize Japanese script
// implementation(libs.play.services.mlkit.text.recognition.japanese)
// // To recognize Korean script
// implementation(libs.play.services.mlkit.text.recognition.korean)
// other
implementation(libs.guava)
implementation(libs.retrofit)

View File

@ -1,16 +1,18 @@
package com.assimilate.alltrans.common
import android.app.Activity
import android.util.Log
import android.widget.FrameLayout
import com.assimilate.alltrans.MyApp
import com.google.android.gms.ads.interstitial.InterstitialAd
import com.lol.apex.ok.google.adlibrary.base.listener.AdLoadListener
import com.lol.apex.ok.google.adlibrary.base.listener.AdShowListener
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import com.lol.apex.ok.google.adlibrary.bean.AdType
import com.lol.apex.ok.google.adlibrary.inner.LOLAdsInnerDispatcher
import com.lol.apex.ok.google.adlibrary.inner.base.AdInnerLoadAdapter
import com.lol.apex.ok.google.adlibrary.inner.base.AdInnerShowAdapter
import com.lol.apex.ok.google.adlibrary.inst.InstAdCache
import com.lol.apex.ok.google.adlibrary.inst.LOLAdsInstDispatcher
import com.lol.apex.ok.google.adlibrary.rewarded.LOLAdsRewardedDispatcher
@ -36,6 +38,7 @@ class LolAdWrapper {
return LOLAdsInstDispatcher.canShow(placement, false)
}
fun hasRewardCache(placement: String): Boolean {
return LOLAdsRewardedDispatcher.canShow(placement)
}
@ -167,6 +170,7 @@ class LolAdWrapper {
private fun showAd(act: Activity, placement: String, listener: LolShowListener? = null) {
if (act.isFinishing) return
LOLAdsInstDispatcher.getShower(act, placement, object : AdShowListener {
override fun onAdClicked() {
MyApp.app.isAdShowing.set(true)
}
@ -202,5 +206,6 @@ class LolAdWrapper {
}).showAd()
}
}

View File

@ -0,0 +1,113 @@
package com.assimilate.alltrans.common
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import com.assimilate.alltrans.R
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import java.util.Locale
object MyTextTools {
private lateinit var tts: TextToSpeech
// 添加历史
fun addToHistory(context: Context, rText: String, transResult: String?) {
val dbTranslation = DbTranslation(context)
val translations = Translations(
PreferenceLanguageUtils.getString("language_source"),
rText,
PreferenceLanguageUtils.getString("language_target"),
transResult
)
dbTranslation.addTranslation(translations)
}
// 分享文本
fun shareText(context: Context, text: String) {
val share: String = text.trim()
if (!TextUtils.isEmpty(share)) {
val intent = Intent(Intent.ACTION_SEND)
intent.setType("text/plain")
intent.putExtra(Intent.EXTRA_TEXT, share)
context.startActivity(Intent.createChooser(intent, "Share " + R.string.app_name))
}
}
// 复制到粘贴板
fun copyToClipboard(context: Context, string: String) {
val tip = "Copied to clipboard!"
val tipNull = "text is null!"
val share = string.trim()
if (!TextUtils.isEmpty(share)) {
val clipboardManager =
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("targetValue", share)
clipboardManager.setPrimaryClip(clipData)
Toast.makeText(context, tip, Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(context, tipNull, Toast.LENGTH_SHORT).show()
}
}
// 朗读文本
fun ttsReadText(text: String, targetLanguage: String, context: Context) {
Toast.makeText(context, R.string.tr_tts_reading, Toast.LENGTH_SHORT).show()
tts = TextToSpeech(context) { status ->
if (TextToSpeech.SUCCESS == status) tts.setLanguage(
Locale.getDefault()
)
tts.setSpeechRate(0.7f)
val speech: String = text.trim()
if (!TextUtils.isEmpty(speech)) {
// 获取目标语言的语言代码
val languageCode =
LanguagesConstants.getInstance()
.getLanguageCodeByLanguage(targetLanguage, context)
Log.d("LanguageCode", "Language Code for $targetLanguage: $languageCode")
// 创建语言 Locale 对象
val locale = Locale(languageCode)
// 判断语言是否支持
if (TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(locale)) {
tts.language = locale
tts.speak(speech, TextToSpeech.QUEUE_FLUSH, null, null)
} else {
Toast.makeText(context, R.string.tr_tts_error, Toast.LENGTH_SHORT).show()
}
tts.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
override fun onStart(utteranceId: String?) {
}
override fun onDone(utteranceId: String?) {
tts.shutdown()
}
@Deprecated("Deprecated in Java")
override fun onError(utteranceId: String?) {
tts.shutdown()
}
})
}
}
}
}

View File

@ -35,7 +35,8 @@ class TextGraphic(
color = MARKER_COLOR
style = Paint.Style.FILL
}
private var hiddenTextBlocks: MutableList<Boolean> = MutableList(text.textBlocks.size) { !textShow }
private var hiddenTextBlocks: MutableList<Boolean> =
MutableList(text.textBlocks.size) { !textShow }
private var isVisible: Boolean
init {
@ -51,7 +52,6 @@ class TextGraphic(
postInvalidate()
}
}
// Redraw the overlay, as this graphic has been added.
postInvalidate()
}
@ -156,7 +156,8 @@ class TextGraphic(
var textLayout: StaticLayout
while (textSize > 0) {
textPaintCopy.textSize = textSize
textLayout = StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth)
textLayout =
StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth)
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setLineSpacing(0.0f, 1.0f)
.setIncludePad(false)
@ -168,7 +169,8 @@ class TextGraphic(
textSize -= 1
}
textLayout = StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth)
textLayout =
StaticLayout.Builder.obtain(text, 0, text.length, textPaintCopy, availableWidth)
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setLineSpacing(0.0f, 1.0f)
.setIncludePad(false)

View File

@ -20,11 +20,12 @@ class TextRecognitionProcessor(
private val textShow:Boolean,
private val needTrans: Boolean,
private val fbFrom:String,
private val callback: TextRecognitionCallback? = null // 添加回调
private val callback: TextRecognitionCallback? = null
) : VisionProcessorBase<Text>(context) {
interface TextRecognitionCallback {
fun onTextRecognized(text: String)
fun onTextRecognized(text: Text,graphicOverlay: GraphicOverlay)
fun onTextFailure(e: Exception)
}
private val textRecognizer: TextRecognizer = TextRecognition.getClient(textRecognizerOptions)
@ -43,10 +44,8 @@ class TextRecognitionProcessor(
}
override fun onSuccess(text: Text, graphicOverlay: GraphicOverlay) {
//
PreferenceLanguageUtils.putString("language_source", getMostFrequentLanguage(text))
Log.d(TAG, "On-device Text detection successful")
logExtrasForTesting(text)
graphicOverlay.add(
TextGraphic(
graphicOverlay,
@ -61,10 +60,13 @@ class TextRecognitionProcessor(
)
// 调用回调
callback?.onTextRecognized(text.text)
callback?.onTextRecognized(text,graphicOverlay)
logExtrasForTesting(text)
}
override fun onFailure(e: Exception) {
callback?.onTextFailure(e)
Log.w(TAG, "Text detection failed.$e")
}

View File

@ -42,10 +42,11 @@ class TranslationManager(
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> =
GoogleTranslator()
for ((index, textBlock) in text.textBlocks.withIndex()) {
// 如果源语言和目标语言相同,直接添加原始文本到 translatedTextBlocks
//根据indices获取对应的文本块将翻译后的文本对应
for (index in text.textBlocks.indices) {
// 如果源语言和目标语言相同,直接添加原始文本到 translatedTextBlocks 不请求网络
if (lanSourceCode == lanTargetCode) {
translatedTextBlocks.add(Pair(index, textBlock.text))
translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post {
callback(translatedTextBlocks.sortedBy { it.first }
@ -56,7 +57,7 @@ class TranslationManager(
val param = HashMap<String, String>().apply {
put("sourceLanguage", lanSourceCode)
put("translationLanguage", lanTargetCode)
put("text", textBlock.text)
put("text", text.textBlocks[index].text)
}
translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback {
@ -64,7 +65,7 @@ class TranslationManager(
if (result != null) {
translatedTextBlocks.add(Pair(index, result))
} else {
translatedTextBlocks.add(Pair(index, ""))
translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
}
if (translatedTextBlocks.size == text.textBlocks.size) {
@ -76,7 +77,7 @@ class TranslationManager(
}
override fun onFailure(errorMessage: String?) {
translatedTextBlocks.add(Pair(index, ""))
translatedTextBlocks.add(Pair(index, text.textBlocks[index].text))
if (translatedTextBlocks.size == text.textBlocks.size) {
handler.post {
callback(translatedTextBlocks.sortedBy { it.first }
@ -84,32 +85,43 @@ class TranslationManager(
}
}
when (fbFrom) {
"global" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"float" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"photo" -> {
FirebaseAnalyticsHelper.imagePhotoResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
"image" -> {
FirebaseAnalyticsHelper.imageCameraResultEvent(MyApp.Config.FAIL_REASON,fbFrom + "_" + errorMessage)
}
}
transFailEvent(errorMessage)
}
})
}
}
}
}
private fun transFailEvent(errorMessage: String?) {
when (fbFrom) {
"global" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
"float" -> {
FirebaseAnalyticsHelper.hoverGlobalResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
"photo" -> {
FirebaseAnalyticsHelper.imagePhotoResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
"image" -> {
FirebaseAnalyticsHelper.imageCameraResultEvent(
MyApp.Config.FAIL_REASON,
fbFrom + "_" + errorMessage
)
}
}
}
}

View File

@ -87,10 +87,12 @@ class ControlView(private val context: Context) {
fullScreenView.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
removeControlView()
fullScreenView.performClick()
true
} else {
false
}
}

View File

@ -17,6 +17,7 @@ import android.widget.Toast
import com.assimilate.alltrans.common.TextRecognitionProcessor
import com.assimilate.alltrans.common.VisionImageProcessor
import com.assimilate.alltrans.databinding.LayoutSusCopyBinding
import com.google.mlkit.vision.text.Text
import com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions
import java.io.IOException
@ -135,10 +136,13 @@ class CopyTextView(private val context: Context) :
}
}
override fun onTextRecognized(text: String) {
recognizedText = text
override fun onTextRecognized(text: Text, graphicOverlay: GraphicOverlay) {
recognizedText = text.text
}
override fun onTextFailure(e: Exception) {
Log.d("copy_", e.toString())
}
// 复制到粘贴板

View File

@ -49,6 +49,7 @@ class DistrictView(
setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
removeDistrictView()
performClick()
}
true
}

View File

@ -127,6 +127,7 @@ class FloatingView(
private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
private val maxClickDuration = 500 // 最大点击时间(毫秒)
override fun onTouch(v: View?, event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
@ -139,6 +140,7 @@ class FloatingView(
handler.removeCallbacks(fadeRunnable)
imageView.alpha = 1.0f
imageView.setImageResource(originalImageResId)
return true
}
@ -150,6 +152,7 @@ class FloatingView(
imageView.setImageResource(originalImageResId)
stickToEdge()
imageView.performClick()
if (isClick && duration < maxClickDuration) {
onClickListener?.onClick()
} else {
@ -193,10 +196,10 @@ class FloatingView(
Log.e("FloatingView", "View not attached to window manager", e)
}
}
return true
}
}
return false
}
})

View File

@ -9,7 +9,6 @@ import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
@ -57,23 +56,11 @@ public class GraphicOverlay extends View {
*/
public abstract static class Graphic {
private GraphicOverlay overlay;
private boolean textVisible = true; // 添加可见性
public Graphic(GraphicOverlay overlay) {
this.overlay = overlay;
}
public boolean isVisible() {
return textVisible;
}
public void setVisible(boolean visible) {
this.textVisible = visible;
overlay.postInvalidate();
}
/**
* Draw the graphic on the supplied canvas. Drawing should use the following methods to convert
* to view coordinates for the graphics that are drawn:
@ -89,7 +76,6 @@ public class GraphicOverlay extends View {
*/
public abstract void draw(Canvas canvas);
public abstract boolean contains(float x, float y);
protected void drawRect(

View File

@ -1,6 +1,7 @@
package com.assimilate.alltrans.viewui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.view.View
@ -55,7 +56,6 @@ class HistoryActivity : AppCompatActivity() {
)
}
initClick()
}
@ -72,11 +72,10 @@ class HistoryActivity : AppCompatActivity() {
binding!!.tvFuncTrans.text = getString(R.string.favor_title)
val list = DbTranslation(this).getTranslations(true)
if (list.isEmpty()) {
binding!!.defEmpty.visibility = View.VISIBLE
binding!!.llEmptyFav.visibility = View.VISIBLE
binding!!.remove.visibility = View.GONE
binding!!.defEmpty.text = getString(R.string.favor_emtpoy)
} else {
binding!!.defEmpty.visibility = View.GONE
binding!!.llEmptyFav.visibility = View.GONE
binding!!.remove.visibility = View.GONE
}
if (null != list && list.isNotEmpty()) {
@ -88,11 +87,10 @@ class HistoryActivity : AppCompatActivity() {
val list = DbTranslation(this).getTranslations(false)
if (list.isEmpty()) {
binding!!.remove.visibility = View.GONE
binding!!.defEmpty.visibility = View.VISIBLE
binding!!.defEmpty.text = getString(R.string.his_emtpoy)
binding!!.llEmptyHis.visibility = View.VISIBLE
} else {
binding!!.remove.visibility = View.GONE
binding!!.defEmpty.visibility = View.GONE
binding!!.llEmptyHis.visibility = View.GONE
}
if (null != list && list.isNotEmpty()) {
translations.addAll(list)
@ -192,8 +190,13 @@ class HistoryActivity : AppCompatActivity() {
showInstAdFromCache(MyApp.Config.history_int_auto)
finish()
}
binding?.emtpoyHisNow?.setOnClickListener {
finish()
}
binding?.emtpoyFavNow?.setOnClickListener {
startActivity(Intent(this, MainActivity::class.java))
}
}
private fun backPressedCall() {
val callback = object : OnBackPressedCallback(true) {
@ -213,13 +216,11 @@ class HistoryActivity : AppCompatActivity() {
place,
object : LolAdWrapper.LoLLoadListener {
override fun loadFailed(error: LolLoadError?) {
// Log.d("dsas",error.toString())
}
override fun loaded() {
// 处理加载成功
// Log.d("dsas","backSucc")
}
})
@ -247,7 +248,6 @@ class HistoryActivity : AppCompatActivity() {
})
}
companion object {
const val COMMAND: String = "remove"
const val COMMAND_COLLECTION: String = "remove_collection"

View File

@ -27,13 +27,13 @@ import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.allservice.SusService
import com.assimilate.alltrans.common.AppStore
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.databinding.ActivityMainBinding
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.google.mlkit.nl.languageid.LanguageIdentification
class MainActivity : AppCompatActivity() {
@ -127,19 +127,11 @@ class MainActivity : AppCompatActivity() {
}
}
private fun initView() {
LolAdWrapper.shared.loadAdShowNativeAd(
this,
"your_native_ad_placement",
binding.homeNative,
R.layout.ad_layout_admob_banner,
R.layout.ad_layout_max_banner
)
private fun initView(){
binding.chSourceLanguage.text = PreferenceLanguageUtils.getString("language_source")
binding.chTargetLanguage.text = PreferenceLanguageUtils.getString("language_target")
}
private fun initSet() {
loadNative()
@ -283,6 +275,7 @@ class MainActivity : AppCompatActivity() {
// 更新字符计数显示
val displayCharCount = if (charCount > 1800) 1800 else charCount
binding.tvMainLimitText.text = getString(R.string.main_limit_num, displayCharCount)
reconText(binding.etText.text.toString())
}
})
@ -434,4 +427,25 @@ class MainActivity : AppCompatActivity() {
)
}
private fun reconText(text:String){
val languageIdentifier = LanguageIdentification.getClient()
languageIdentifier.identifyLanguage(text)
.addOnSuccessListener { languageCode ->
if (languageCode == "und") {
Log.i("dsafdsf", "Can't identify language.")
} else {
Log.i("dsafdsf", "Language: $languageCode")
val lan = LanguagesConstants.getInstance().getLanguageByLanguageCode(languageCode,this)
PreferenceLanguageUtils.putString("language_source",lan.language)
binding.chSourceLanguage.text = PreferenceLanguageUtils.getString("language_source")
}
}
.addOnFailureListener {
// Model couldnt be loaded or other internal error.
// ...
}
}
}

View File

@ -94,7 +94,7 @@ class PhotoImageActivity : AppCompatActivity() {
}
firebaseEvent()
Widget.makeSnackbar(this, "Photographing text for translation")
Widget.makeSnackbar(this, getString(R.string.ph_toast))
isLandScape = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
savedInstanceState?.let {

View File

@ -96,7 +96,7 @@ class SettingsActivity
private fun setBottomSheet() {
// 设置 BottomSheetDialog
bottomSheetDialog = BottomSheetDialog(this)
bottomSheetDialog = BottomSheetDialog(this,R.style.CustomBottomSheetDialogTheme)
bottomSheetDialog.setContentView(R.layout.bottomsheet_rate)
bottomSheetDialog.dismissWithAnimation = true

View File

@ -1,12 +1,7 @@
package com.assimilate.alltrans.viewui
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.speech.tts.TextToSpeech
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
@ -18,25 +13,23 @@ import androidx.core.view.WindowInsetsCompat
import com.assimilate.alltrans.MyApp
import com.assimilate.alltrans.R
import com.assimilate.alltrans.common.FirebaseAnalyticsHelper
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.common.Logger
import com.assimilate.alltrans.common.LolAdWrapper
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.common.Widget
import com.assimilate.alltrans.common.MyTextTools
import com.assimilate.alltrans.databinding.ActivityTextResultBinding
import com.assimilate.alltrans.http.GoogleTranslator
import com.assimilate.alltrans.http.Translator
import com.assimilate.alltrans.model.LanguagesConstants
import com.assimilate.alltrans.model.PreferenceLanguageUtils
import com.assimilate.alltrans.mydb.DbTranslation
import com.assimilate.alltrans.mydb.Translations
import com.lol.apex.ok.google.adlibrary.base.listener.LolLoadError
import com.lol.apex.ok.google.adlibrary.base.listener.LolShowError
import java.util.Locale
class TextResultActivity : AppCompatActivity() {
private lateinit var binding: ActivityTextResultBinding
private lateinit var tts: TextToSpeech
private var translating = false
override fun onCreate(savedInstanceState: Bundle?) {
@ -64,12 +57,6 @@ class TextResultActivity : AppCompatActivity() {
binding.tvTrSource.text = receivedString
translate(binding.tvTrSource.text.toString())
tts = TextToSpeech(this) { status ->
if (TextToSpeech.SUCCESS == status) tts.setLanguage(
Locale.getDefault()
)
}
}
private fun backPressedCall() {
@ -96,19 +83,19 @@ class TextResultActivity : AppCompatActivity() {
showInstAdFromCache(MyApp.Config.text_camera_int_auto)
}
binding.ivTrCopy.setOnClickListener {
copyToClipboard()
MyTextTools.copyToClipboard(this, binding.tvTrTarget.text.toString())
FirebaseAnalyticsHelper.textTransCopyEvent()
}
binding.ivSourceClear.setOnClickListener { finish() }
binding.ivSourceTts.setOnClickListener {
readText(
MyTextTools.ttsReadText(
binding.tvTrSource.text.toString(),
PreferenceLanguageUtils.getString("language_source"),
this
)
}
binding.ivTargetTts.setOnClickListener {
readText(
MyTextTools.ttsReadText(
binding.tvTrTarget.text.toString(),
PreferenceLanguageUtils.getString("language_target"),
this
@ -116,7 +103,7 @@ class TextResultActivity : AppCompatActivity() {
FirebaseAnalyticsHelper.textTransPlayEvent()
}
binding.ivTrTargetShare.setOnClickListener {
shareText(binding.tvTrTarget.text.toString())
MyTextTools.shareText(this, binding.tvTrTarget.text.toString())
FirebaseAnalyticsHelper.textTransShareEvent()
}
binding.ivTrCollect.setOnClickListener {
@ -166,7 +153,7 @@ class TextResultActivity : AppCompatActivity() {
put("text", text)
}
binding.tvTrTarget.text = "translating..."
binding.tvTrTarget.text = getString(R.string.tr_trans_ing)
val translator: Translator<GoogleTranslator.GoogleTranslateCallback> = GoogleTranslator()
translator.translate(param, object : GoogleTranslator.GoogleTranslateCallback {
override fun onResponse(result: String?, errorMessage: String?) {
@ -174,7 +161,11 @@ class TextResultActivity : AppCompatActivity() {
runOnUiThread {
if (!TextUtils.isEmpty(result)) {
binding.tvTrTarget.text = result
addHistory(result)
MyTextTools.addToHistory(
this@TextResultActivity,
binding.tvTrSource.text.toString(),
result
)
} else {
// 处理错误信息
if (!TextUtils.isEmpty(errorMessage)) {
@ -183,7 +174,7 @@ class TextResultActivity : AppCompatActivity() {
Log.e("TranslationError", errorMessage)
}
}
binding.tvTrTarget.text = "Translation failed: $errorMessage"
binding.tvTrTarget.text = getString(R.string.tr_trans_fail)
}
}
}
@ -200,9 +191,9 @@ class TextResultActivity : AppCompatActivity() {
if (errorMessage != null) {
Log.e("TranslationFailure", errorMessage)
}
binding.tvTrTarget.text = "Translation failed: $errorMessage"
binding.tvTrTarget.text = getString(R.string.tr_trans_fail)
} else {
binding.tvTrTarget.text = "Translation failed: Unknown error"
binding.tvTrTarget.text = getString(R.string.tr_trans_fail)
}
}
}
@ -210,78 +201,6 @@ class TextResultActivity : AppCompatActivity() {
}
private fun addHistory(transResult: String?) {
val dbTranslation = DbTranslation(this)
val translations = Translations(
PreferenceLanguageUtils.getString("language_source"),
binding.tvTrSource.text.toString(),
PreferenceLanguageUtils.getString("language_target"),
transResult
)
dbTranslation.addTranslation(translations)
}
private fun shareText(text: String) {
val share: String = text.trim()
if (!TextUtils.isEmpty(share)) {
val intent = Intent(Intent.ACTION_SEND)
intent.setType("text/plain")
intent.putExtra(Intent.EXTRA_TEXT, share)
startActivity(Intent.createChooser(intent, "Share " + getString(R.string.app_name)))
}
}
// readText 方法,整合获取语言代码和朗读文本功能
private fun readText(text: String, targetLanguage: String, context: Context) {
val speech: String = text.trim()
if (!TextUtils.isEmpty(speech)) {
// 获取目标语言的语言代码
val languageCode =
LanguagesConstants.getInstance().getLanguageCodeByLanguage(targetLanguage, context)
Log.d("LanguageCode", "Language Code for $targetLanguage: $languageCode")
// 创建语言 Locale 对象
val locale = Locale(languageCode)
// 判断语言是否支持
if (TextToSpeech.LANG_NOT_SUPPORTED != tts.isLanguageAvailable(locale)) {
tts.language = locale
tts.speak(speech, TextToSpeech.QUEUE_FLUSH, null, null)
} else {
Widget.makeToast(this, getString(R.string.tr_tts_error))
}
}
}
// 复制到粘贴板
private fun copyToClipboard() {
val tip = "Copied to clipboard!"
val tipNull = "text is null!"
val share = binding.tvTrTarget.text.toString().trim()
if (!TextUtils.isEmpty(share)) {
val clipboardManager =
getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("targetValue", share)
clipboardManager.setPrimaryClip(clipData)
Widget.makeToast(this, tip)
} else {
Widget.makeToast(this, tipNull)
}
}
override fun onStop() {
super.onStop()
tts.stop()
}
override fun onDestroy() {
super.onDestroy()
tts.shutdown()
}
private fun doBack() {
finish()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

View File

@ -4,7 +4,6 @@
<corners android:radius="24dp" />
<solid android:color="#ffffffff" />
<gradient
android:angle="45"
android:endColor="#ff2da5ff"
android:startColor="#ff14cbf9"
android:type="linear" />

View File

@ -0,0 +1,45 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="327dp"
android:height="199dp"
android:viewportWidth="327"
android:viewportHeight="199">
<path
android:pathData="M12,0L315,0A12,12 0,0 1,327 12L327,187A12,12 0,0 1,315 199L12,199A12,12 0,0 1,0 187L0,12A12,12 0,0 1,12 0z"
android:fillColor="#ffffff"/>
<path
android:pathData="M20,20L307,20A4,4 0,0 1,311 24L311,34A4,4 0,0 1,307 38L20,38A4,4 0,0 1,16 34L16,24A4,4 0,0 1,20 20z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M20,42L307,42A4,4 0,0 1,311 46L311,56A4,4 0,0 1,307 60L20,60A4,4 0,0 1,16 56L16,46A4,4 0,0 1,20 42z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M20,78L32,78A4,4 0,0 1,36 82L36,94A4,4 0,0 1,32 98L20,98A4,4 0,0 1,16 94L16,82A4,4 0,0 1,20 78z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M56,78L68,78A4,4 0,0 1,72 82L72,94A4,4 0,0 1,68 98L56,98A4,4 0,0 1,52 94L52,82A4,4 0,0 1,56 78z"
android:fillColor="#D9D9D9"/>
<path
android:pathData="M92,78L104,78A4,4 0,0 1,108 82L108,94A4,4 0,0 1,104 98L92,98A4,4 0,0 1,88 94L88,82A4,4 0,0 1,92 78z"
android:fillColor="#D9D9D9"/>
<group>
<clip-path
android:pathData="M294,76L306,76A6,6 0,0 1,312 82L312,94A6,6 0,0 1,306 100L294,100A6,6 0,0 1,288 94L288,82A6,6 0,0 1,294 76z"/>
<path
android:pathData="M307.29,90.94L300,97L292.71,90.94C292.23,90.47 291.85,89.91 291.6,89.29C291.34,88.67 291.22,88 291.24,87.33C291.26,86.66 291.41,86 291.7,85.39C291.98,84.78 292.39,84.24 292.9,83.8C293.4,83.36 293.99,83.02 294.63,82.82C295.27,82.62 295.95,82.55 296.61,82.62C297.28,82.69 297.93,82.9 298.51,83.24C299.09,83.57 299.6,84.02 300,84.56C300.4,84.02 300.91,83.58 301.49,83.25C302.07,82.92 302.72,82.71 303.38,82.64C304.05,82.57 304.72,82.64 305.36,82.85C306,83.05 306.59,83.38 307.09,83.82C307.59,84.26 308,84.8 308.28,85.41C308.57,86.01 308.73,86.67 308.74,87.34C308.76,88.01 308.64,88.67 308.39,89.29C308.14,89.92 307.77,90.48 307.29,90.95"
android:strokeLineJoin="round"
android:strokeWidth="1.94445"
android:fillColor="#00000000"
android:strokeColor="#C6C6CB"
android:strokeLineCap="round"/>
</group>
<path
android:pathData="M294,76.25L306,76.25A5.75,5.75 0,0 1,311.75 82L311.75,94A5.75,5.75 0,0 1,306 99.75L294,99.75A5.75,5.75 0,0 1,288.25 94L288.25,82A5.75,5.75 0,0 1,294 76.25z"
android:strokeWidth="0.5"
android:fillColor="#00000000"
android:strokeColor="#E72D2D"/>
<path
android:pathData="M300,100V112.74C300,117.15 296.42,120.74 292,120.74H262C257.58,120.74 254,124.32 254,128.74V137"
android:strokeWidth="0.5"
android:fillColor="#00000000"
android:strokeColor="#E62D2D"/>
</vector>

View File

@ -0,0 +1,115 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="315dp"
android:height="315dp"
android:viewportWidth="315"
android:viewportHeight="315">
<path
android:pathData="M157.5,157.5m-156.85,0a156.85,156.85 0,1 1,313.7 0a156.85,156.85 0,1 1,-313.7 0"
android:strokeAlpha="0.02"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-78.85,0a78.85,78.85 0,1 1,157.7 0a78.85,78.85 0,1 1,-157.7 0"
android:strokeAlpha="0.1"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-58.85,0a58.85,58.85 0,1 1,117.7 0a58.85,58.85 0,1 1,-117.7 0"
android:strokeAlpha="0.12"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-48.85,0a48.85,48.85 0,1 1,97.7 0a48.85,48.85 0,1 1,-97.7 0"
android:strokeAlpha="0.13"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-68.85,0a68.85,68.85 0,1 1,137.7 0a68.85,68.85 0,1 1,-137.7 0"
android:strokeAlpha="0.11"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-88.85,0a88.85,88.85 0,1 1,177.7 0a88.85,88.85 0,1 1,-177.7 0"
android:strokeAlpha="0.09"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-98.85,0a98.85,98.85 0,1 1,197.7 0a98.85,98.85 0,1 1,-197.7 0"
android:strokeAlpha="0.08"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-108.85,0a108.85,108.85 0,1 1,217.7 0a108.85,108.85 0,1 1,-217.7 0"
android:strokeAlpha="0.07"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-118.85,0a118.85,118.85 0,1 1,237.7 0a118.85,118.85 0,1 1,-237.7 0"
android:strokeAlpha="0.06"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-128.85,0a128.85,128.85 0,1 1,257.7 0a128.85,128.85 0,1 1,-257.7 0"
android:strokeAlpha="0.05"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-138.85,0a138.85,138.85 0,1 1,277.7 0a138.85,138.85 0,1 1,-277.7 0"
android:strokeAlpha="0.04"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M157.5,157.5m-148.85,0a148.85,148.85 0,1 1,297.7 0a148.85,148.85 0,1 1,-297.7 0"
android:strokeAlpha="0.03"
android:strokeWidth="1.3"
android:fillColor="#00000000"
android:strokeColor="#ffffff"/>
<path
android:pathData="M158,158m-40,0a40,40 0,1 1,80 0a40,40 0,1 1,-80 0"
android:fillColor="#ffffff"/>
<path
android:pathData="M163.09,154.88H172.46C172.76,154.88 173.07,154.95 173.35,155.06C173.64,155.18 173.9,155.35 174.12,155.57C174.33,155.79 174.51,156.05 174.62,156.33C174.74,156.62 174.8,156.92 174.8,157.23V172.46C174.8,172.76 174.74,173.07 174.62,173.35C174.51,173.64 174.33,173.9 174.12,174.12C173.9,174.33 173.64,174.51 173.35,174.62C173.07,174.74 172.76,174.8 172.46,174.8H157.23C156.92,174.8 156.62,174.74 156.33,174.62C156.05,174.51 155.79,174.33 155.57,174.12C155.35,173.9 155.18,173.64 155.06,173.35C154.95,173.07 154.88,172.76 154.88,172.46V163.09H159.57C160.03,163.09 160.49,163 160.92,162.82C161.34,162.64 161.73,162.38 162.06,162.06C162.38,161.73 162.64,161.34 162.82,160.92C163,160.49 163.09,160.03 163.09,159.57V154.88ZM142,144.34C142,144.04 142.06,143.73 142.18,143.45C142.29,143.16 142.47,142.9 142.68,142.68C142.9,142.47 143.16,142.29 143.45,142.18C143.73,142.06 144.04,142 144.34,142H159.57C159.88,142 160.18,142.06 160.47,142.18C160.75,142.29 161.01,142.47 161.23,142.68C161.45,142.9 161.62,143.16 161.74,143.45C161.85,143.73 161.91,144.04 161.91,144.34V159.57C161.91,159.88 161.85,160.18 161.74,160.47C161.62,160.75 161.45,161.01 161.23,161.23C161.01,161.45 160.75,161.62 160.47,161.74C160.18,161.85 159.88,161.91 159.57,161.91H144.34C144.04,161.91 143.73,161.85 143.45,161.74C143.16,161.62 142.9,161.45 142.68,161.23C142.47,161.01 142.29,160.75 142.18,160.47C142.06,160.18 142,159.88 142,159.57V144.34ZM146.68,154.46H148.4V153.55H150.86V157.88H152.68V153.55H155.2V154.31H157.06V148.57H152.68V147.3C152.67,146.98 152.72,146.65 152.83,146.35C152.85,146.3 152.87,146.25 152.88,146.2C152.88,146.16 152.76,146.13 152.52,146.1H150.81V148.57H146.68V154.46V154.46ZM148.4,149.98H150.86V152.19H148.4V149.98L148.4,149.98ZM155.19,152.19H152.67V149.98H155.19V152.19V152.19ZM162.65,170.06L163.36,168.1H167.03L167.74,170.06H169.76L166.49,160.75H164.12L160.74,170.06H162.65ZM163.86,166.54L165.22,162.56H165.27L166.53,166.54H163.86ZM172.46,151.37H170.12C170.12,150.13 169.62,148.94 168.74,148.06C167.86,147.18 166.67,146.69 165.43,146.69V144.34C166.35,144.34 167.27,144.52 168.12,144.88C168.97,145.23 169.75,145.75 170.4,146.4C171.05,147.05 171.57,147.83 171.92,148.68C172.28,149.54 172.46,150.45 172.46,151.37ZM144.34,165.43H146.68C146.68,166.04 146.81,166.65 147.04,167.22C147.28,167.79 147.62,168.31 148.06,168.74C148.49,169.18 149.01,169.52 149.58,169.76C150.15,169.99 150.76,170.12 151.37,170.12V172.46C149.51,172.46 147.72,171.72 146.4,170.4C145.08,169.08 144.34,167.29 144.34,165.43Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M163.09,154.88H172.46C172.76,154.88 173.07,154.95 173.35,155.06C173.64,155.18 173.9,155.35 174.12,155.57C174.33,155.79 174.51,156.05 174.62,156.33C174.74,156.62 174.8,156.92 174.8,157.23V172.46C174.8,172.76 174.74,173.07 174.62,173.35C174.51,173.64 174.33,173.9 174.12,174.12C173.9,174.33 173.64,174.51 173.35,174.62C173.07,174.74 172.76,174.8 172.46,174.8H157.23C156.92,174.8 156.62,174.74 156.33,174.62C156.05,174.51 155.79,174.33 155.57,174.12C155.35,173.9 155.18,173.64 155.06,173.35C154.95,173.07 154.88,172.76 154.88,172.46V163.09H159.57C160.03,163.09 160.49,163 160.92,162.82C161.34,162.64 161.73,162.38 162.06,162.06C162.38,161.73 162.64,161.34 162.82,160.92C163,160.49 163.09,160.03 163.09,159.57V154.88ZM142,144.34C142,144.04 142.06,143.73 142.18,143.45C142.29,143.16 142.47,142.9 142.68,142.68C142.9,142.47 143.16,142.29 143.45,142.18C143.73,142.06 144.04,142 144.34,142H159.57C159.88,142 160.18,142.06 160.47,142.18C160.75,142.29 161.01,142.47 161.23,142.68C161.45,142.9 161.62,143.16 161.74,143.45C161.85,143.73 161.91,144.04 161.91,144.34V159.57C161.91,159.88 161.85,160.18 161.74,160.47C161.62,160.75 161.45,161.01 161.23,161.23C161.01,161.45 160.75,161.62 160.47,161.74C160.18,161.85 159.88,161.91 159.57,161.91H144.34C144.04,161.91 143.73,161.85 143.45,161.74C143.16,161.62 142.9,161.45 142.68,161.23C142.47,161.01 142.29,160.75 142.18,160.47C142.06,160.18 142,159.88 142,159.57V144.34ZM146.68,154.46H148.4V153.55H150.86V157.88H152.68V153.55H155.2V154.31H157.06V148.57H152.68V147.3C152.67,146.98 152.72,146.65 152.83,146.35C152.85,146.3 152.87,146.25 152.88,146.2C152.88,146.16 152.76,146.13 152.52,146.1H150.81V148.57H146.68V154.46V154.46ZM148.4,149.98H150.86V152.19H148.4V149.98L148.4,149.98ZM155.19,152.19H152.67V149.98H155.19V152.19V152.19ZM162.65,170.06L163.36,168.1H167.03L167.74,170.06H169.76L166.49,160.75H164.12L160.74,170.06H162.65ZM163.86,166.54L165.22,162.56H165.27L166.53,166.54H163.86ZM172.46,151.37H170.12C170.12,150.13 169.62,148.94 168.74,148.06C167.86,147.18 166.67,146.69 165.43,146.69V144.34C166.35,144.34 167.27,144.52 168.12,144.88C168.97,145.23 169.75,145.75 170.4,146.4C171.05,147.05 171.57,147.83 171.92,148.68C172.28,149.54 172.46,150.45 172.46,151.37ZM144.34,165.43H146.68C146.68,166.04 146.81,166.65 147.04,167.22C147.28,167.79 147.62,168.31 148.06,168.74C148.49,169.18 149.01,169.52 149.58,169.76C150.15,169.99 150.76,170.12 151.37,170.12V172.46C149.51,172.46 147.72,171.72 146.4,170.4C145.08,169.08 144.34,167.29 144.34,165.43Z">
<aapt:attr name="android:fillColor">
<gradient
android:startX="158.4"
android:startY="142"
android:endX="158.4"
android:endY="174.8"
android:type="linear">
<item android:offset="0" android:color="#FF14CBF9"/>
<item android:offset="0.98" android:color="#FF2CA7FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M158,158m-34.4,0a34.4,34.4 0,1 1,68.8 0a34.4,34.4 0,1 1,-68.8 0"
android:strokeWidth="1.6"
android:fillColor="#00000000">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="158"
android:startY="103.54"
android:endX="158"
android:endY="221.34"
android:type="linear">
<item android:offset="0" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FF16C8FA"/>
</gradient>
</aapt:attr>
</path>
</vector>

View File

@ -0,0 +1,20 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2.899,12H20.899"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#1F1724"
android:strokeLineCap="round"/>
<path
android:pathData="M8.899,18L2.899,12L8.899,6"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#1F1724"
android:strokeLineCap="round"/>
</vector>

View File

@ -0,0 +1,71 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="60dp"
android:height="60dp"
android:viewportWidth="60"
android:viewportHeight="60">
<path
android:pathData="M30,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="10"
android:startY="10"
android:endX="49"
android:endY="54"
android:type="linear">
<item android:offset="0.009" android:color="#FFDCEAFF"/>
<item android:offset="1" android:color="#FFA6C7F1"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,29.998m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="15.333"
android:startY="15.331"
android:endX="43.933"
android:endY="47.598"
android:type="linear">
<item android:offset="0.009" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M25,22.104C24.653,22.302 24.319,22.52 24,22.756C23.454,23.161 22.951,23.62 22.5,24.125C20.944,25.865 20,28.151 20,30.654C20,36.106 24.477,40.525 30,40.525C35.523,40.525 40,36.106 40,30.654C40,28.151 39.056,25.865 37.5,24.125C37.049,23.62 36.547,23.161 36,22.756C35.681,22.52 35.347,22.302 35,22.104"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="30"
android:startY="22.104"
android:endX="30"
android:endY="40.525"
android:type="linear">
<item android:offset="0" android:color="#FF15CCFA"/>
<item android:offset="1" android:color="#FF2BA9FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,19.998V30.525"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="30.5"
android:startY="19.998"
android:endX="30.5"
android:endY="30.525"
android:type="linear">
<item android:offset="0" android:color="#FF15CCFA"/>
<item android:offset="1" android:color="#FF2BA9FF"/>
</gradient>
</aapt:attr>
</path>
</vector>

View File

@ -0,0 +1,66 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="60dp"
android:height="60dp"
android:viewportWidth="60"
android:viewportHeight="60">
<path
android:pathData="M30,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0">
<aapt:attr name="android:fillColor">
<gradient
android:startX="10"
android:startY="10"
android:endX="49"
android:endY="54"
android:type="linear">
<item android:offset="0.009" android:color="#7FDCEAFF"/>
<item android:offset="1" android:color="#7FA6C7F1"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,29.998m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0"
android:strokeAlpha="0.5"
android:fillAlpha="0.5">
<aapt:attr name="android:fillColor">
<gradient
android:startX="15.333"
android:startY="15.331"
android:endX="43.933"
android:endY="47.598"
android:type="linear">
<item android:offset="0.009" android:color="#FFFFFFFF"/>
<item android:offset="1" android:color="#FFFFFFFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M25,22.104C24.653,22.302 24.319,22.52 24,22.756C23.454,23.161 22.951,23.62 22.5,24.125C20.944,25.865 20,28.151 20,30.654C20,36.106 24.477,40.525 30,40.525C35.523,40.525 40,36.106 40,30.654C40,28.151 39.056,25.865 37.5,24.125C37.049,23.62 36.547,23.161 36,22.756C35.681,22.52 35.347,22.302 35,22.104"
android:strokeAlpha="0.2"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:fillAlpha="0.2"
android:strokeLineCap="round">
<aapt:attr name="android:strokeColor">
<gradient
android:startX="30"
android:startY="22.104"
android:endX="30"
android:endY="40.525"
android:type="linear">
<item android:offset="0" android:color="#FF15CCFA"/>
<item android:offset="1" android:color="#FF2BA9FF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M30,19.998V30.525"
android:strokeAlpha="0.2"
android:strokeLineJoin="round"
android:strokeWidth="2.6"
android:fillColor="#00000000"
android:strokeColor="#15CCFA"
android:fillAlpha="0.2"
android:strokeLineCap="round"/>
</vector>

View File

@ -66,16 +66,87 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/def_empty"
<LinearLayout
android:id="@+id/ll_empty_his"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/main_text_ff1f1724"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/his_emtpoy"
android:textColor="@color/his_empty_text"
android:textSize="16sp" />
<TextView
android:id="@+id/emtpoy_his_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="32dp"
android:background="@drawable/button_r24_blue_bg"
android:paddingStart="56dp"
android:paddingTop="12dp"
android:paddingEnd="56dp"
android:paddingBottom="12dp"
android:text="@string/translate_now"
android:textColor="@color/white"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="@id/histories"
app:layout_constraintEnd_toEndOf="@id/histories"
app:layout_constraintStart_toStartOf="@id/histories"
app:layout_constraintTop_toTopOf="@id/histories" />
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_empty_fav"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="110dp"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/favor_emtpoy"
android:textColor="@color/his_empty_text"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="@drawable/emp"
android:gravity="bottom|center"
android:text="@string/fav_emp_description"
android:textColor="@color/text_gray"
android:textSize="12sp" />
<TextView
android:id="@+id/emtpoy_fav_now"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="32dp"
android:background="@drawable/button_r24_blue_bg"
android:paddingStart="56dp"
android:paddingTop="12dp"
android:paddingEnd="56dp"
android:paddingBottom="12dp"
android:text="@string/translate_now"
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_r20_white_bg_tlr"
android:orientation="vertical">
<ImageView

View File

@ -84,11 +84,11 @@
<!-- 分隔线 -->
<View
android:id="@+id/sus_view1"
android:layout_width="110dp"
android:layout_width="140dp"
android:layout_height="5dp"
android:layout_gravity="center"
android:layout_marginTop="16dp"
android:layout_marginBottom="15dp"
android:layout_marginBottom="5dp"
android:background="@drawable/ic_dashed_line_4b4b4b4" />
<!-- 第三行 -->
<LinearLayout
@ -97,7 +97,7 @@
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="20dp"
android:layout_marginBottom="30dp"
android:orientation="horizontal">

View File

@ -23,6 +23,7 @@
<color name="bg_ff605c62">#FF605C62</color>
<!-- his_page-->
<color name="text_ffa5a5a5">#FFA5A5A5</color>
<color name="his_empty_text">#FFB3B3B3</color>
<!-- still-page-->
<color name="bg_53514c">#FF53514C</color>

View File

@ -1,7 +1,7 @@
<resources>
<string name="app_name">Translark</string>
<string name="my_admob_app_id">ca-app-pub-9280511366580942~8779388277</string>
<!--system-->
<string name="pref_key_info_hide" translatable="false">ih</string>
<string name="pref_key_group_recognized_text_in_blocks" translatable="false">grtib</string>
<string name="pref_key_show_language_tag" translatable="false">slt</string>
@ -9,12 +9,14 @@
<string name="pref_key_pose_detector_prefer_gpu" translatable="false">pdpg</string>
<string name="pref_key_camera_live_viewport" translatable="false">clv</string>
<string name="select_image" translatable="false">Select image</string>
<!--main_page-->
<string name="menu_item_settings" translatable="false">Settings</string>
<string name="text_main_title">translate</string>
<string name="text_source_language">Chinese</string>
<string name="text_target_language">English</string>
<string name="main_text_enter">Enter text</string>
<string name="main_text_enter">Enter text\nSupport for intelligent recognition of language types</string>
<string name="main_paste_text">Paste</string>
<string name="main_paste_empty">Clipboard contains empty or invalid data.</string>
<string name="main_voice_to_text">Your device may not support speech-to-text.</string>
@ -27,6 +29,8 @@
<string name="main_dictionary">Dictionary</string>
<string name="main_limit_num">%1$d/1800</string>
<!-- photo-->
<string name="ph_toast">Photographing text for translation</string>
<!-- change_page-->
<string name="ch_title">Languages</string>
@ -35,7 +39,11 @@
<string name="tr_common">Common</string>
<string name="tr_other">other</string>
<string name="tr_tts_error">Speech in this language is temporarily not supported.</string>
<string name="tr_tts_reading">Preparing to read…</string>
<string name="tr_title">Translator</string>
<string name="tr_trans_fail">Translation failed: Please check the network.</string>
<string name="tr_trans_ing"> translating…</string>
<!-- sus_view-->
<string name="global_translation">Global Translation</string>
@ -49,9 +57,11 @@
<!-- his_page-->
<string name="his_delete">Delete</string>
<string name="his_title">History</string>
<string name="his_emtpoy">No translation records</string>
<string name="his_emtpoy">Empty no history...</string>
<string name="favor_title">Favorite</string>
<string name="favor_emtpoy">No collection record</string>
<string name="favor_emtpoy">Empty no favorite...</string>
<string name="translate_now">Translate Now</string>
<!--settings_page-->
<string name="settings">Settings</string>
<string name="languages">App Languages</string>
@ -82,7 +92,7 @@
<string name="quick_set_kj_long">长按悬浮球</string>
<string name="quick_set_kj_long_to">打开应用</string>
<string name="quick_set_kj_double">双击悬浮球</string>
<string name="fav_emp_description">Click the \"Favorite\" button at the end\nafter translation.\nEasily bookmark sentences.</string>
</resources>