基本浏览器模块完成
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#Created by .winboll/winboll_app_build.gradle
|
||||
#Thu Nov 27 10:54:58 HKT 2025
|
||||
#Thu Nov 27 03:28:47 GMT 2025
|
||||
stageCount=2
|
||||
libraryProject=
|
||||
baseVersion=15.11
|
||||
publishVersion=15.11.1
|
||||
buildCount=0
|
||||
buildCount=8
|
||||
baseBetaVersion=15.11.2
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/MyAppTheme"
|
||||
android:resizeableActivity="true"
|
||||
android:name=".App">
|
||||
android:name=".App"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
||||
@@ -17,13 +17,14 @@ import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.winboll.activities.AboutActivity;
|
||||
import cc.winboll.studio.winboll.fragments.MainFragment;
|
||||
import java.util.ArrayList;
|
||||
import cc.winboll.studio.winboll.fragments.BrowserFragment;
|
||||
|
||||
public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActivity {
|
||||
|
||||
|
||||
public static final String TAG = "MainActivity";
|
||||
|
||||
MainFragment mMainFragment;
|
||||
BrowserFragment mBrowserFragment;
|
||||
|
||||
@Override
|
||||
public Activity getActivity() {
|
||||
@@ -38,11 +39,11 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (mMainFragment == null) {
|
||||
mMainFragment = new MainFragment();
|
||||
addFragment(mMainFragment);
|
||||
if (mBrowserFragment == null) {
|
||||
mBrowserFragment = new BrowserFragment();
|
||||
addFragment(mBrowserFragment);
|
||||
}
|
||||
showFragment(mMainFragment);
|
||||
showFragment(mBrowserFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,11 +87,11 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi
|
||||
super.onItemClick(parent, view, position, id);
|
||||
switch (position) {
|
||||
case 0 : {
|
||||
if (mMainFragment == null) {
|
||||
mMainFragment = new MainFragment();
|
||||
addFragment(mMainFragment);
|
||||
if (mBrowserFragment == null) {
|
||||
mBrowserFragment = new BrowserFragment();
|
||||
addFragment(mBrowserFragment);
|
||||
}
|
||||
showFragment(mMainFragment);
|
||||
showFragment(mBrowserFragment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,228 @@
|
||||
package cc.winboll.studio.winboll.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import cc.winboll.studio.winboll.R;
|
||||
import cc.winboll.studio.winboll.views.WinBoLLView;
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/27 11:09
|
||||
* @Describe 浏览器Fragment(Java 7 语法完整版)
|
||||
* 适配Java 7特性,移除Lambda/方法引用,兼容低版本Android系统
|
||||
*/
|
||||
public class BrowserFragment extends Fragment implements View.OnClickListener, WinBoLLView.OnPageStatusListener {
|
||||
|
||||
// 控件声明(Java 7 成员变量显式声明)
|
||||
private EditText mEtUrl;
|
||||
private Button mBtnLoad;
|
||||
private Button mBtnRefresh;
|
||||
private Button mBtnStop;
|
||||
private Button mBtnForward;
|
||||
private Button mBtnBack;
|
||||
private ProgressBar mProgressBar;
|
||||
private WinBoLLView mWinBoLLView;
|
||||
|
||||
// 单例创建方法(Java 7 静态工厂模式)
|
||||
public static BrowserFragment newInstance() {
|
||||
return new BrowserFragment();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
// 加载布局(Java 7 显式强转,无菱形语法)
|
||||
View view = inflater.inflate(R.layout.fragment_browser, container, false);
|
||||
// 初始化控件
|
||||
initViews(view);
|
||||
// 绑定事件
|
||||
initEvents();
|
||||
// 初始化WinBoLLView
|
||||
initWinBoLLView();
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件(Java 7 显式绑定,无Stream简化)
|
||||
*/
|
||||
private void initViews(View view) {
|
||||
mEtUrl = (EditText) view.findViewById(R.id.et_url);
|
||||
mBtnLoad = (Button) view.findViewById(R.id.btn_load);
|
||||
mBtnRefresh = (Button) view.findViewById(R.id.btn_refresh);
|
||||
mBtnStop = (Button) view.findViewById(R.id.btn_stop);
|
||||
mBtnForward = (Button) view.findViewById(R.id.btn_forward);
|
||||
mBtnBack = (Button) view.findViewById(R.id.btn_back);
|
||||
mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
|
||||
mWinBoLLView = (WinBoLLView) view.findViewById(R.id.winboll_webview);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定点击事件(Java 7 匿名内部类,无Lambda)
|
||||
*/
|
||||
private void initEvents() {
|
||||
// 功能按钮点击事件
|
||||
mBtnLoad.setOnClickListener(this);
|
||||
mBtnRefresh.setOnClickListener(this);
|
||||
mBtnStop.setOnClickListener(this);
|
||||
mBtnForward.setOnClickListener(this);
|
||||
mBtnBack.setOnClickListener(this);
|
||||
|
||||
// 输入框软键盘“前往”按钮事件(Java 7 匿名内部类实现)
|
||||
mEtUrl.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId, android.view.KeyEvent event) {
|
||||
// 处理软键盘“前往”点击
|
||||
loadUrlFromInput();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化WinBoLLView(Java 7 显式调用,无方法引用)
|
||||
*/
|
||||
private void initWinBoLLView() {
|
||||
// 绑定进度条
|
||||
mWinBoLLView.setProgressBar(mProgressBar);
|
||||
// 设置页面状态监听(this 实现 OnPageStatusListener)
|
||||
mWinBoLLView.setOnPageStatusListener(this);
|
||||
// 预加载默认页面(兼容Java 7 字符串拼接)
|
||||
//String defaultUrl = "https://www.baidu.com";
|
||||
String defaultUrl = "https://www.winboll.cc";
|
||||
mWinBoLLView.loadUrlSafe(defaultUrl);
|
||||
mEtUrl.setText(defaultUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击事件处理(Java 7 switch-case 语句,无增强switch)
|
||||
*/
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.btn_load) {
|
||||
// 加载输入框中的URL
|
||||
loadUrlFromInput();
|
||||
} else if (id == R.id.btn_refresh) {
|
||||
// 刷新当前页面
|
||||
mWinBoLLView.refreshPage();
|
||||
} else if (id == R.id.btn_stop) {
|
||||
// 停止页面加载
|
||||
mWinBoLLView.stopPageLoad();
|
||||
} else if (id == R.id.btn_forward) {
|
||||
// 前进(无历史则提示)
|
||||
if (!mWinBoLLView.goForwardSafe()) {
|
||||
showToast("无前进历史");
|
||||
}
|
||||
} else if (id == R.id.btn_back) {
|
||||
// 后退(无历史则提示)
|
||||
if (!mWinBoLLView.goBackSafe()) {
|
||||
showToast("无后退历史");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从输入框获取URL并加载(Java 7 显式空值校验)
|
||||
*/
|
||||
private void loadUrlFromInput() {
|
||||
// 空值校验(Java 7 显式判断,无Objects.requireNonNull)
|
||||
if (mEtUrl == null) {
|
||||
showToast("控件初始化失败");
|
||||
return;
|
||||
}
|
||||
String url = mEtUrl.getText().toString().trim();
|
||||
// 调用WinBoLLView安全加载方法
|
||||
mWinBoLLView.loadUrlSafe(url);
|
||||
// 隐藏软键盘
|
||||
hideSoftKeyboard();
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏软键盘(Java 7 显式获取系统服务,无Lambda简化)
|
||||
*/
|
||||
private void hideSoftKeyboard() {
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
// 获取InputMethodManager(Java 7 显式强转)
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(android.content.Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null && getActivity().getCurrentFocus() != null) {
|
||||
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示Toast提示(Java 7 简化封装,避免重复代码)
|
||||
*/
|
||||
private void showToast(String msg) {
|
||||
if (getActivity() == null || msg == null) {
|
||||
return;
|
||||
}
|
||||
// Java 7 显式创建Toast,无Toast.makeText简化链式调用
|
||||
Toast toast = Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
// ------------------- WinBoLLView.OnPageStatusListener 实现(Java 7 显式重写) -------------------
|
||||
@Override
|
||||
public void onPageStarted(String url) {
|
||||
// 页面开始加载:更新输入框URL(Java 7 显式非空判断)
|
||||
if (mEtUrl != null && url != null) {
|
||||
mEtUrl.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(String url) {
|
||||
// 页面加载完成:更新输入框URL
|
||||
if (mEtUrl != null && url != null) {
|
||||
mEtUrl.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageError(String errorMsg) {
|
||||
// 页面加载错误:显示错误提示
|
||||
showToast("加载失败:" + errorMsg);
|
||||
}
|
||||
|
||||
// ------------------- 生命周期管理(防止内存泄漏,Java 7 显式重写) -------------------
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
// 销毁WinBoLLView(释放资源,避免内存泄漏)
|
||||
if (mWinBoLLView != null) {
|
||||
mWinBoLLView.destroyWebView();
|
||||
mWinBoLLView = null;
|
||||
}
|
||||
// 置空控件(帮助GC回收)
|
||||
mEtUrl = null;
|
||||
mBtnLoad = null;
|
||||
mBtnRefresh = null;
|
||||
mBtnStop = null;
|
||||
mBtnForward = null;
|
||||
mBtnBack = null;
|
||||
mProgressBar = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
// 彻底释放资源
|
||||
if (mWinBoLLView != null) {
|
||||
mWinBoLLView.destroyWebView();
|
||||
mWinBoLLView = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
package cc.winboll.studio.winboll.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebResourceError;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
/**
|
||||
* @Author ZhanGSKen&豆包大模型<zhangsken@qq.com>
|
||||
* @Date 2025/11/27 11:05
|
||||
* @Describe 自定义WebView控件(WinBoLLView)
|
||||
* 集成进度监听、页面加载控制、安全配置等核心能力
|
||||
*/
|
||||
public class WinBoLLView extends WebView {
|
||||
public static final String TAG = "WinBoLLView";
|
||||
|
||||
private ProgressBar mProgressBar; // 页面加载进度条(可选,增强用户体验)
|
||||
private OnPageStatusListener mStatusListener; // 页面状态监听回调
|
||||
private boolean mIsLoading = false; // 自定义加载状态标记(替代系统isLoading())
|
||||
|
||||
// 构造方法(兼容代码创建和XML布局引用)
|
||||
public WinBoLLView(Context context) {
|
||||
super(context);
|
||||
initWebViewSettings();
|
||||
initWebViewClient();
|
||||
}
|
||||
|
||||
public WinBoLLView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initWebViewSettings();
|
||||
initWebViewClient();
|
||||
}
|
||||
|
||||
public WinBoLLView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initWebViewSettings();
|
||||
initWebViewClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化WebView基础配置(安全+性能+兼容性)
|
||||
*/
|
||||
private void initWebViewSettings() {
|
||||
WebSettings settings = getSettings();
|
||||
|
||||
// 基础功能配置
|
||||
settings.setJavaScriptEnabled(true); // 启用JS(根据需求决定是否开启)
|
||||
settings.setSupportZoom(true); // 支持缩放
|
||||
settings.setBuiltInZoomControls(true); // 显示缩放控件
|
||||
settings.setDisplayZoomControls(false); // 隐藏系统缩放控件(优化UI)
|
||||
settings.setLoadWithOverviewMode(true); // 自适应屏幕
|
||||
settings.setUseWideViewPort(true); // 支持宽视角
|
||||
|
||||
// 缓存配置(提升加载速度)
|
||||
settings.setCacheMode(WebSettings.LOAD_DEFAULT);
|
||||
settings.setDomStorageEnabled(true); // 启用DOM存储
|
||||
settings.setDatabaseEnabled(true); // 启用数据库存储
|
||||
|
||||
// 安全配置(防止XSS和恶意跳转)
|
||||
settings.setJavaScriptCanOpenWindowsAutomatically(false); // 禁止JS自动打开窗口
|
||||
setBackgroundColor(0x00000000); // 透明背景(避免白屏闪烁)
|
||||
|
||||
// 适配HTTPS和HTTP混合内容(Android 5.0+)
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
||||
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化WebViewClient和ChromeClient(控制页面加载和进度)
|
||||
*/
|
||||
private void initWebViewClient() {
|
||||
// 控制页面跳转(不打开系统浏览器)
|
||||
setWebViewClient(new WebViewClient() {
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
// 拦截URL加载,使用当前WebView打开
|
||||
view.loadUrl(request.getUrl().toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
|
||||
super.onPageStarted(view, url, favicon);
|
||||
// 页面开始加载:更新自定义加载状态标记
|
||||
mIsLoading = true;
|
||||
// 更新进度条+回调状态
|
||||
if (mProgressBar != null) mProgressBar.setVisibility(VISIBLE);
|
||||
if (mStatusListener != null) mStatusListener.onPageStarted(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
// 页面加载完成:更新自定义加载状态标记
|
||||
mIsLoading = false;
|
||||
// 隐藏进度条+回调状态
|
||||
if (mProgressBar != null) mProgressBar.setVisibility(GONE);
|
||||
if (mStatusListener != null) mStatusListener.onPageFinished(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
|
||||
super.onReceivedError(view, request, error);
|
||||
// 页面加载错误:更新自定义加载状态标记
|
||||
mIsLoading = false;
|
||||
// 回调错误信息
|
||||
if (mStatusListener != null) {
|
||||
String errorMsg = error.getDescription().toString();
|
||||
mStatusListener.onPageError(errorMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 监听页面加载进度
|
||||
setWebChromeClient(new WebChromeClient() {
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
super.onProgressChanged(view, newProgress);
|
||||
// 更新进度条进度
|
||||
if (mProgressBar != null) mProgressBar.setProgress(newProgress);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ------------------- 对外暴露的控制方法(供Fragment调用) -------------------
|
||||
/**
|
||||
* 加载URL(增加空值校验+优先HTTPS协议)
|
||||
*/
|
||||
public void loadUrlSafe(String url) {
|
||||
if (url == null || url.trim().isEmpty()) {
|
||||
if (mStatusListener != null) mStatusListener.onPageError("URL不能为空");
|
||||
return;
|
||||
}
|
||||
// 协议补全:优先HTTPS,兼容HTTP(解决ERR_CLEARTEXT_NOT_PERMITTED)
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://")) {
|
||||
url = "https://" + url; // 改为优先HTTPS,而非HTTP
|
||||
}
|
||||
super.loadUrl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新当前页面(使用自定义mIsLoading判断加载状态)
|
||||
*/
|
||||
public void refreshPage() {
|
||||
if (mIsLoading) { // 替换原isLoading(),使用自定义标记
|
||||
stopLoading(); // 若正在加载,先停止再刷新
|
||||
}
|
||||
reload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止页面加载(使用自定义mIsLoading判断加载状态)
|
||||
*/
|
||||
public void stopPageLoad() {
|
||||
if (mIsLoading) { // 替换原isLoading(),使用自定义标记
|
||||
stopLoading();
|
||||
mIsLoading = false; // 停止后更新状态标记
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 前进(判断是否有前进历史)
|
||||
*/
|
||||
public boolean goForwardSafe() {
|
||||
if (canGoForward()) {
|
||||
goForward();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 后退(判断是否有后退历史)
|
||||
*/
|
||||
public boolean goBackSafe() {
|
||||
if (canGoBack()) {
|
||||
goBack();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------- 辅助功能:进度条和状态监听 -------------------
|
||||
/**
|
||||
* 设置进度条(绑定Fragment中的进度条控件)
|
||||
*/
|
||||
public void setProgressBar(ProgressBar progressBar) {
|
||||
this.mProgressBar = progressBar;
|
||||
if (mProgressBar != null) {
|
||||
mProgressBar.setMax(100);
|
||||
mProgressBar.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页面状态监听(供Fragment接收加载状态)
|
||||
*/
|
||||
public void setOnPageStatusListener(OnPageStatusListener listener) {
|
||||
this.mStatusListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面状态监听接口
|
||||
*/
|
||||
public interface OnPageStatusListener {
|
||||
void onPageStarted(String url); // 页面开始加载
|
||||
void onPageFinished(String url); // 页面加载完成
|
||||
void onPageError(String errorMsg); // 页面加载错误
|
||||
}
|
||||
|
||||
// ------------------- 资源释放(防止内存泄漏) -------------------
|
||||
/**
|
||||
* 销毁WebView(必须在Fragment销毁时调用)
|
||||
*/
|
||||
public void destroyWebView() {
|
||||
// 停止加载并清空历史
|
||||
stopLoading();
|
||||
mIsLoading = false; // 销毁时重置加载状态
|
||||
clearHistory();
|
||||
// 移除所有WebViewClient(避免内存泄漏)
|
||||
setWebViewClient(null);
|
||||
setWebChromeClient(null);
|
||||
// 销毁WebView
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
7
winboll/src/main/res/drawable/bg_browser_top.xml
Normal file
7
winboll/src/main/res/drawable/bg_browser_top.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white"/>
|
||||
<corners android:radius="8dp"/>
|
||||
<stroke android:color="@android:color/darker_gray" android:width="1dp"/>
|
||||
</shape>
|
||||
7
winboll/src/main/res/drawable/bg_edittext.xml
Normal file
7
winboll/src/main/res/drawable/bg_edittext.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white"/>
|
||||
<corners android:radius="24dp"/>
|
||||
<stroke android:color="@android:color/darker_gray" android:width="1dp"/>
|
||||
</shape>
|
||||
8
winboll/src/main/res/drawable/progress_bar_style.xml
Normal file
8
winboll/src/main/res/drawable/progress_bar_style.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background" android:drawable="@android:color/darker_gray"/>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip android:drawable="@android:color/holo_blue_light"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
||||
96
winboll/src/main/res/layout/fragment_browser.xml
Normal file
96
winboll/src/main/res/layout/fragment_browser.xml
Normal file
@@ -0,0 +1,96 @@
|
||||
<?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:orientation="vertical">
|
||||
|
||||
<!-- 顶部地址栏区域(水平布局:输入框+功能按钮) -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="@drawable/bg_browser_top"
|
||||
android:padding="4dp">
|
||||
|
||||
<!-- 地址输入框 -->
|
||||
<EditText
|
||||
android:id="@+id/et_url"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="请输入URL或搜索内容"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:background="@drawable/bg_edittext"
|
||||
android:singleLine="true"
|
||||
android:imeOptions="actionGo"
|
||||
android:inputType="textUri" /> <!-- 提示输入URL格式 -->
|
||||
|
||||
<!-- 功能按钮区域(水平排列:加载、刷新、停止、前进、后退) -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingHorizontal="4dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_load"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="加载"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_refresh"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="刷新"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_stop"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="停止"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_forward"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="前进"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_back"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:text="后退"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="2dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 页面加载进度条(位于地址栏下方,WebView上方) -->
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:progressDrawable="@drawable/progress_bar_style"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<!-- 自定义WebView(WinBoLLView) -->
|
||||
<cc.winboll.studio.winboll.views.WinBoLLView
|
||||
android:id="@+id/winboll_webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<!-- 允许访问 winboll.cc 及其子域名(原配置) -->
|
||||
<!-- 允许特定域名的HTTP明文请求(如winboll.com) -->
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">winboll.cc</domain>
|
||||
</domain-config>
|
||||
|
||||
<!-- **新增:允许访问 IP 地址 10.8.0.250** -->
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="false">10.8.0.250</domain> <!-- 不包含子域名 -->
|
||||
<domain includeSubdomains="true">winboll.cc</domain> <!-- 你的目标域名 -->
|
||||
<domain includeSubdomains="true">www.winboll.cc</domain> <!-- 其他需要兼容的域名 -->
|
||||
</domain-config>
|
||||
<!-- 默认允许HTTPS(全局生效) -->
|
||||
<base-config cleartextTrafficPermitted="false">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user