Add Functionality and Fix Issues in WebViewActivity
- Implemented draggable FloatingActionButton with click functionality. - Resolved touch conflict between touch and click events on FloatingActionButton. - Improved WebView reload logic and ensured UI components are not obstructed. - Updated XML layouts for better constraint alignment and visual consistency. - Enhanced logging for user actions on the refresh button. Ensures a smoother user experience and UI operation.
This commit is contained in:
parent
b82febf82a
commit
236bb140f8
12 changed files with 126 additions and 55 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -15,5 +15,4 @@ local.properties
|
|||
/jdks
|
||||
/android
|
||||
/.tmp
|
||||
/kotlin-profile
|
||||
|
||||
/kotlin-profile
|
||||
|
|
@ -67,6 +67,8 @@ dependencies {
|
|||
implementation(libs.androidx.constraintlayout)
|
||||
implementation("androidx.activity:activity-ktx:1.9.2")
|
||||
implementation(libs.material)
|
||||
implementation("androidx.browser:browser:1.3.0")
|
||||
|
||||
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.WebViewApp"> <!-- 使用 Theme.WebViewApp 作为主题 -->
|
||||
android:theme="@style/Theme.WebViewApp">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
package com.example.lobchat
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
|
|
@ -12,7 +11,6 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var webView: WebView
|
||||
private lateinit var urlInput: EditText
|
||||
private lateinit var loadUrlButton: Button
|
||||
|
||||
|
|
@ -21,15 +19,17 @@ class MainActivity : AppCompatActivity() {
|
|||
const val KEY_SAVED_URL = "saved_url"
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("MissingInflatedId")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
// 初始化视图组件
|
||||
webView = findViewById(R.id.webView)
|
||||
urlInput = findViewById(R.id.urlInput)
|
||||
loadUrlButton = findViewById(R.id.loadUrlButton)
|
||||
|
||||
|
||||
// 从 SharedPreferences 加载上次保存的 URL
|
||||
val sharedPreferences = getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
val savedUrl = sharedPreferences.getString(KEY_SAVED_URL, "")
|
||||
|
|
@ -37,14 +37,6 @@ class MainActivity : AppCompatActivity() {
|
|||
urlInput.setText(savedUrl)
|
||||
}
|
||||
|
||||
// 设置状态栏为透明,使系统自动使用默认的颜色
|
||||
window.statusBarColor = resources.getColor(android.R.color.transparent, theme)
|
||||
|
||||
// 初始化 WebView 设置
|
||||
val webSettings: WebSettings = webView.settings
|
||||
webSettings.javaScriptEnabled = true
|
||||
webSettings.domStorageEnabled = true
|
||||
|
||||
// 点击按钮后加载用户输入的 URL
|
||||
loadUrlButton.setOnClickListener {
|
||||
val url = urlInput.text.toString().trim()
|
||||
|
|
@ -53,11 +45,9 @@ class MainActivity : AppCompatActivity() {
|
|||
if (url.isNotEmpty()) {
|
||||
// 确保 URL 包含 http 或 https
|
||||
val formattedUrl = if (!urlPattern.matches(url)) {
|
||||
// 如果 URL 格式不正确,则提示用户
|
||||
Toast.makeText(this, "请输入正确的网站地址", Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener // 结束函数
|
||||
return@setOnClickListener
|
||||
} else {
|
||||
// 确保 URL 包含 http 或 https
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
"https://$url"
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,40 +1,51 @@
|
|||
package com.example.lobchat
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.webkit.ConsoleMessage
|
||||
import android.webkit.ValueCallback
|
||||
import android.webkit.WebChromeClient
|
||||
import android.webkit.WebResourceRequest
|
||||
import android.webkit.WebSettings
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.webkit.*
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
||||
|
||||
class WebViewActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var webView: WebView
|
||||
private var filePathCallback: ValueCallback<Array<Uri>>? = null
|
||||
private lateinit var fileChooserLauncher: ActivityResultLauncher<Intent>
|
||||
private var isFinalUrlLoaded = false
|
||||
// 用于标记是否通过 LobeChat 验证
|
||||
private var isLobeChatVerified = false
|
||||
private lateinit var refreshButton: FloatingActionButton
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_web_view)
|
||||
|
||||
refreshButton = findViewById(R.id.refreshButton)
|
||||
// 初始化 WebView
|
||||
webView = findViewById(R.id.webView)
|
||||
|
||||
setupWebView()
|
||||
|
||||
// 刷新按钮的点击事件
|
||||
refreshButton.bringToFront()
|
||||
refreshButton.setOnClickListener {
|
||||
Log.i("WebViewActivity", "Refresh button clicked")
|
||||
webView.reload()
|
||||
}
|
||||
|
||||
// 设置拖动事件监听器
|
||||
refreshButton.setOnTouchListener(DraggableTouchListener())
|
||||
|
||||
// 初始化文件选择器启动器
|
||||
fileChooserLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
handleFileChooserResult(result)
|
||||
|
|
@ -49,29 +60,30 @@ class WebViewActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
// 增加处理Android返回键逻辑
|
||||
// 处理返回键
|
||||
override fun onBackPressed() {
|
||||
if (webView.canGoBack()) {
|
||||
// 如果WebView能够返回上一页
|
||||
webView.goBack()
|
||||
} else {
|
||||
// 否则调用super以处理默认的后退行为
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun setupWebView() {
|
||||
val webSettings: WebSettings = webView.settings
|
||||
webSettings.javaScriptEnabled = true
|
||||
webSettings.domStorageEnabled = true
|
||||
webSettings.cacheMode = WebSettings.LOAD_CACHE_ELSE_NETWORK
|
||||
webSettings.cacheMode = WebSettings.LOAD_DEFAULT // Use default caching strategy
|
||||
|
||||
// Other optimizations
|
||||
webSettings.databaseEnabled = true
|
||||
webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
|
||||
|
||||
webSettings.userAgentString = "Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Mobile Safari/537.36"
|
||||
|
||||
webView.webViewClient = object : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
|
||||
// 当 URL 变化时重置 isFinalUrlLoaded 标志
|
||||
isFinalUrlLoaded = false
|
||||
// 返回 false 表示允许 WebView 处理请求
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -88,12 +100,10 @@ class WebViewActivity : AppCompatActivity() {
|
|||
""".trimIndent()
|
||||
) { result ->
|
||||
if (result == "true") {
|
||||
// 验证通过,不再继续验证
|
||||
isLobeChatVerified = true
|
||||
Toast.makeText(this@WebViewActivity, "LobeChat validation passed", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this@WebViewActivity, "The webpage does not contain the required LobeChat text in the header.", Toast.LENGTH_LONG).show()
|
||||
// 如果验证失败,返回 MainActivity
|
||||
val intent = Intent(this@WebViewActivity, MainActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(intent)
|
||||
|
|
@ -145,4 +155,37 @@ class WebViewActivity : AppCompatActivity() {
|
|||
private fun showSnackbar(message: String) {
|
||||
Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private inner class DraggableTouchListener : View.OnTouchListener {
|
||||
|
||||
private var dX = 0f
|
||||
private var dY = 0f
|
||||
private var isClick = false
|
||||
|
||||
override fun onTouch(view: View, event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
dX = view.x - event.rawX
|
||||
dY = view.y - event.rawY
|
||||
isClick = true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
view.animate()
|
||||
.x(event.rawX + dX)
|
||||
.y(event.rawY + dY)
|
||||
.setDuration(0)
|
||||
.start()
|
||||
isClick = false
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (isClick) {
|
||||
// 处理点击事件
|
||||
Log.i("WebViewActivity", "Refresh button clicked")
|
||||
webView.reload()
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
11
app/src/main/res/drawable/ic_refresh.xml
Normal file
11
app/src/main/res/drawable/ic_refresh.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="100dp" android:viewportHeight="24" android:viewportWidth="24" android:width="100dp">
|
||||
|
||||
<path android:fillColor="@color/transparent" android:pathData="M3,12a9,9 0,0 1,9 -9,9.75 9.75,0 0,1 6.74,2.74L21,8" android:strokeColor="@color/purple_dark_10" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||
|
||||
<path android:fillColor="@color/transparent" android:pathData="M21,3v5h-5" android:strokeColor="@color/purple_dark_10" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||
|
||||
<path android:fillColor="@color/transparent" android:pathData="M21,12a9,9 0,0 1,-9 9,9.75 9.75,0 0,1 -6.74,-2.74L3,16" android:strokeColor="@color/purple_dark_10" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||
|
||||
<path android:fillColor="@color/transparent" android:pathData="M8,16H3v5" android:strokeColor="@color/purple_dark_10" android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="2"/>
|
||||
|
||||
</vector>
|
||||
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
|
||||
<!-- 包含两个ImageView的容器 -->
|
||||
<LinearLayout
|
||||
|
|
@ -59,7 +61,7 @@
|
|||
android:hint="@string/enter_your_server_url"
|
||||
android:inputType="textUri"
|
||||
android:textColor="@color/cyan_dark_0"
|
||||
android:textColorHint="@color/gray_dark_8"
|
||||
android:textColorHint="@color/gray_dark_4"
|
||||
android:textSize="14sp" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".WebViewActivity">
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".WebViewActivity">
|
||||
|
||||
<!-- FloatingActionButton -->
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/refreshButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="100dp"
|
||||
android:backgroundTint="@color/purple_dark_9"
|
||||
android:contentDescription="Refresh"
|
||||
app:srcCompat="@drawable/ic_refresh"
|
||||
app:backgroundTint="@color/transparent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<!-- WebView 控件 -->
|
||||
<WebView
|
||||
android:id="@+id/webView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:id="@+id/webView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
|
|||
|
|
@ -675,4 +675,7 @@
|
|||
<color name="slate_light_10">#484a4d</color>
|
||||
<color name="slate_light_11">#1b1c1d</color>
|
||||
<color name="slate_light_12">#111111</color>
|
||||
|
||||
<color name="transparent">#00000000</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<resources>
|
||||
<string name="app_name">lobchat</string>
|
||||
<string name="app_name">LobeChat</string>
|
||||
<string name="enter_your_server_url">Enter your server URL</string>
|
||||
<string name="send">Send</string>
|
||||
<string name="app_logo">App Logo</string>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,2 @@
|
|||
<resources>
|
||||
<!-- 使主题继承自 Theme.AppCompat.DayNight.NoActionBar,以获得系统默认的状态栏 -->
|
||||
<style name="Theme.WebViewApp" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- 使用系统默认的颜色 -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryDark</item> <!-- 让状态栏使用主题色 -->
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -1,5 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.Lobchat" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
<!-- 使主题继承自 Theme.AppCompat.DayNight.NoActionBar,以获得系统默认的状态栏 -->
|
||||
<style name="Theme.WebViewApp" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="android:statusBarColor">
|
||||
@color/purple_dark_9
|
||||
</item>
|
||||
<item name="android:navigationBarColor">
|
||||
@color/design_default_color_background
|
||||
</item>
|
||||
<item name="android:windowTitleBackgroundStyle">
|
||||
@color/design_default_color_background
|
||||
</item>
|
||||
</style>
|
||||
</resources>
|
||||
Loading…
Reference in a new issue