Skip to content

Commit 174d615

Browse files
graycreateclaude
andcommitted
feat: Implement fullscreen WebView for vshare with theme auto-adaptation
- Add VshareWebActivity for fullscreen display of vshare page - Implement automatic light/dark theme adaptation based on app's current mode - Replace browser opening with native WebView experience - Add progress bar for loading indication - Enable JavaScript and DOM storage for proper page functionality - Handle back navigation within WebView 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 4596aa7 commit 174d615

File tree

4 files changed

+190
-1
lines changed

4 files changed

+190
-1
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@
146146
android:exported="true"
147147
android:label="添加附言" />
148148
<activity android:name=".general.PageHost" />
149+
<activity
150+
android:name=".module.vshare.VshareWebActivity"
151+
android:exported="false"
152+
android:theme="@style/GalleryTheme"
153+
android:configChanges="orientation|keyboardHidden|screenSize" />
149154
</application>
150155

151156
</manifest>

app/src/main/java/me/ghui/v2er/module/home/MainActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ protected void init() {
254254
Navigator.from(getContext()).to(CreateTopicActivity.class).start();
255255
break;
256256
case R.id.vshare_nav_item:
257-
Utils.openInBrowser("https://v2er.app/vshare", getContext());
257+
me.ghui.v2er.module.vshare.VshareWebActivity.open(getContext());
258258
mVshareVersionChecker.markAsViewed();
259259
updateVshareBadge();
260260
break;
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package me.ghui.v2er.module.vshare;
2+
3+
import android.annotation.SuppressLint;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.graphics.Bitmap;
7+
import android.os.Bundle;
8+
import android.view.View;
9+
import android.view.Window;
10+
import android.view.WindowManager;
11+
import android.webkit.WebChromeClient;
12+
import android.webkit.WebResourceRequest;
13+
import android.webkit.WebSettings;
14+
import android.webkit.WebView;
15+
import android.webkit.WebViewClient;
16+
import android.widget.ProgressBar;
17+
18+
import androidx.appcompat.app.AppCompatActivity;
19+
20+
import butterknife.BindView;
21+
import butterknife.ButterKnife;
22+
import me.ghui.v2er.R;
23+
import me.ghui.v2er.util.DarkModelUtils;
24+
25+
/**
26+
* Fullscreen WebView Activity for displaying vshare page
27+
* with automatic theme adaptation
28+
*/
29+
public class VshareWebActivity extends AppCompatActivity {
30+
31+
private static final String KEY_URL = "url";
32+
private static final String VSHARE_BASE_URL = "https://v2er.app/vshare";
33+
34+
@BindView(R.id.webview)
35+
WebView mWebView;
36+
37+
@BindView(R.id.progress_bar)
38+
ProgressBar mProgressBar;
39+
40+
public static void open(Context context) {
41+
Intent intent = new Intent(context, VshareWebActivity.class);
42+
// Append theme parameter based on current app theme
43+
String url = VSHARE_BASE_URL;
44+
if (DarkModelUtils.isDarkMode()) {
45+
url += "?theme=dark";
46+
} else {
47+
url += "?theme=light";
48+
}
49+
intent.putExtra(KEY_URL, url);
50+
context.startActivity(intent);
51+
}
52+
53+
@Override
54+
protected void onCreate(Bundle savedInstanceState) {
55+
super.onCreate(savedInstanceState);
56+
57+
// Request fullscreen mode
58+
requestWindowFeature(Window.FEATURE_NO_TITLE);
59+
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
60+
WindowManager.LayoutParams.FLAG_FULLSCREEN);
61+
62+
// Hide action bar if present
63+
if (getSupportActionBar() != null) {
64+
getSupportActionBar().hide();
65+
}
66+
67+
setContentView(R.layout.activity_vshare_web);
68+
ButterKnife.bind(this);
69+
70+
setupWebView();
71+
72+
// Load the URL
73+
String url = getIntent().getStringExtra(KEY_URL);
74+
if (url != null) {
75+
mWebView.loadUrl(url);
76+
}
77+
}
78+
79+
@SuppressLint("SetJavaScriptEnabled")
80+
private void setupWebView() {
81+
WebSettings settings = mWebView.getSettings();
82+
83+
// Enable JavaScript
84+
settings.setJavaScriptEnabled(true);
85+
86+
// Enable DOM storage
87+
settings.setDomStorageEnabled(true);
88+
89+
// Enable responsive layout
90+
settings.setUseWideViewPort(true);
91+
settings.setLoadWithOverviewMode(true);
92+
93+
// Enable zoom
94+
settings.setSupportZoom(true);
95+
settings.setBuiltInZoomControls(true);
96+
settings.setDisplayZoomControls(false);
97+
98+
// Set cache mode
99+
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
100+
101+
// Set WebViewClient to handle navigation
102+
mWebView.setWebViewClient(new WebViewClient() {
103+
@Override
104+
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
105+
// Keep navigation within the WebView
106+
view.loadUrl(request.getUrl().toString());
107+
return true;
108+
}
109+
110+
@Override
111+
public void onPageStarted(WebView view, String url, Bitmap favicon) {
112+
super.onPageStarted(view, url, favicon);
113+
mProgressBar.setVisibility(View.VISIBLE);
114+
}
115+
116+
@Override
117+
public void onPageFinished(WebView view, String url) {
118+
super.onPageFinished(view, url);
119+
mProgressBar.setVisibility(View.GONE);
120+
121+
// Inject CSS to ensure proper theme is applied
122+
String theme = DarkModelUtils.isDarkMode() ? "dark" : "light";
123+
String js = "javascript:(function() { " +
124+
"document.documentElement.setAttribute('data-theme', '" + theme + "'); " +
125+
"})()";
126+
mWebView.loadUrl(js);
127+
}
128+
});
129+
130+
// Set WebChromeClient for progress updates
131+
mWebView.setWebChromeClient(new WebChromeClient() {
132+
@Override
133+
public void onProgressChanged(WebView view, int newProgress) {
134+
mProgressBar.setProgress(newProgress);
135+
if (newProgress == 100) {
136+
mProgressBar.setVisibility(View.GONE);
137+
}
138+
}
139+
});
140+
}
141+
142+
@Override
143+
public void onBackPressed() {
144+
// Handle back navigation in WebView
145+
if (mWebView.canGoBack()) {
146+
mWebView.goBack();
147+
} else {
148+
super.onBackPressed();
149+
}
150+
}
151+
152+
@Override
153+
protected void onDestroy() {
154+
if (mWebView != null) {
155+
mWebView.clearHistory();
156+
mWebView.clearCache(true);
157+
mWebView.loadUrl("about:blank");
158+
mWebView.pauseTimers();
159+
mWebView.destroy();
160+
}
161+
super.onDestroy();
162+
}
163+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="match_parent"
5+
android:background="?android:attr/windowBackground">
6+
7+
<WebView
8+
android:id="@+id/webview"
9+
android:layout_width="match_parent"
10+
android:layout_height="match_parent" />
11+
12+
<ProgressBar
13+
android:id="@+id/progress_bar"
14+
style="?android:attr/progressBarStyleHorizontal"
15+
android:layout_width="match_parent"
16+
android:layout_height="3dp"
17+
android:layout_gravity="top"
18+
android:progressTint="@color/colorAccent"
19+
android:visibility="gone" />
20+
21+
</FrameLayout>

0 commit comments

Comments
 (0)