Compare commits

...

13 Commits

14 changed files with 214 additions and 45 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat Apr 25 04:11:46 HKT 2026 #Mon Apr 27 20:18:59 HKT 2026
stageCount=20 stageCount=21
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.15 baseVersion=15.15
publishVersion=15.15.19 publishVersion=15.15.20
buildCount=0 buildCount=0
baseBetaVersion=15.15.20 baseBetaVersion=15.15.21

View File

@@ -16,6 +16,17 @@
android:label="@string/app_name" android:label="@string/app_name"
android:exported="true" android:exported="true"
android:resizeableActivity="true" android:resizeableActivity="true"
android:launchMode="singleTop"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
</activity>
<activity
android:name=".MainActivityAlias"
android:label="@string/app_name"
android:exported="true"
android:resizeableActivity="true"
android:launchMode="singleTop"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"> android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
<intent-filter> <intent-filter>
@@ -30,6 +41,17 @@
</activity> </activity>
<activity
android:name=".Main2Activity"
android:label="@string/app_name"
android:exported="true"
android:resizeableActivity="true"
android:launchMode="singleTop"
android:taskAffinity="cc.winboll.studio.appbase.Main2Activity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation">
</activity>
<activity android:name=".GlobalApplication$CrashActivity"/> <activity android:name=".GlobalApplication$CrashActivity"/>
<meta-data <meta-data

View File

@@ -23,17 +23,8 @@ public class AboutActivity extends Activity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about); setContentView(R.layout.activity_about);
// 设置工具栏
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
setActionBar(toolbar); setActionBar(toolbar);
getActionBar().setSubtitle(TAG);
getActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish(); // 点击导航栏返回按钮,触发 finish()
}
});
AboutView aboutView = findViewById(R.id.aboutview); AboutView aboutView = findViewById(R.id.aboutview);
aboutView.setAPPInfo(genDefaultAppInfo()); aboutView.setAPPInfo(genDefaultAppInfo());

View File

@@ -0,0 +1,20 @@
package cc.winboll.studio.appbase;
import android.os.Bundle;
import android.widget.Toolbar;
import cc.winboll.studio.appbase.R;
public class Main2Activity extends MainActivity {
public static final String TAG = "Main2Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = findViewById(R.id.toolbar);
if (toolbar != null) {
setActionBar(toolbar);
}
}
}

View File

@@ -103,14 +103,17 @@ public class MainActivity extends Activity {
} }
} }
public void onLogTestNewTask(View view) {
LogActivity.startLogActivity(this, true);
}
/** /**
* 日志测试按钮点击事件(打开日志查看界面) * 日志测试按钮点击事件(打开日志查看界面)
* 启动 LogActivity用于查看应用运行日志 * 启动 LogActivity用于查看应用运行日志
* @param view 触发事件的 View对应布局中的日志测试按钮 * @param view 触发事件的 View对应布局中的日志测试按钮
*/ */
public void onLogTest(View view) { public void onLogTest(View view) {
// 启动日志查看 Activity通过静态方法传入上下文简化跳转逻辑 LogActivity.startLogActivity(this, false);
LogActivity.startLogActivity(this);
} }
/** /**
@@ -158,5 +161,35 @@ public class MainActivity extends Activity {
Intent aboutIntent = new Intent(getApplicationContext(), AboutActivity.class); Intent aboutIntent = new Intent(getApplicationContext(), AboutActivity.class);
startActivity(aboutIntent); startActivity(aboutIntent);
} }
public void onSplitScreenMode(View view) {
LogUtils.d(TAG, "onSplitScreenMode() 分屏测试按钮已点击");
ToastUtils.show("分屏测试:已启动新窗口");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
android.graphics.Rect bounds = new android.graphics.Rect();
getWindow().getDecorView().getDisplay().getRectSize(bounds);
int height = bounds.height();
int width = bounds.width();
bounds.set(0, 0, width, height / 2);
LogUtils.d(TAG, "onSplitScreenMode() 分屏窗口范围: " + bounds);
android.content.Intent intent = new android.content.Intent(this, MainActivityAlias.class);
intent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
LogUtils.d(TAG, "onSplitScreenMode() 准备启动MainActivityAlias");
android.app.ActivityOptions options = android.app.ActivityOptions.makeBasic();
options.setLaunchBounds(bounds);
startActivity(intent, options.toBundle());
LogUtils.d(TAG, "onSplitScreenMode() MainActivityAlias已启动");
}
}
public void onMultiInstance(View view) {
LogUtils.d(TAG, "onMultiInstance() 多开窗口按钮已点击");
ToastUtils.show("多开窗口:已启动新窗口");
android.content.Intent intent = new android.content.Intent(this, Main2Activity.class);
intent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
LogUtils.d(TAG, "onMultiInstance() 准备启动Main2Activity");
startActivity(intent);
LogUtils.d(TAG, "onMultiInstance() Main2Activity已启动");
}
} }

View File

@@ -0,0 +1,17 @@
package cc.winboll.studio.appbase;
import android.os.Bundle;
import android.view.View;
import android.widget.Toolbar;
import cc.winboll.studio.appbase.R;
public class MainActivityAlias extends MainActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setActionBar(toolbar);
}
}

View File

@@ -23,6 +23,18 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:spacing="12dp"> android:spacing="12dp">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="关于应用"
android:textSize="16sp"
android:textColor="@android:color/white"
android:background="#81C7F5"
android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp"
android:onClick="onAboutActivity"
android:layout_margin="10dp"/>
<Button <Button
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -47,6 +59,18 @@
android:onClick="onLogTest" android:onClick="onLogTest"
android:layout_margin="10dp"/> android:layout_margin="10dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="应用日志测试(新窗口)"
android:textSize="16sp"
android:textColor="@android:color/white"
android:background="#81C7F5"
android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp"
android:onClick="onLogTestNewTask"
android:layout_margin="10dp"/>
<Button <Button
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -62,18 +86,29 @@
<Button <Button
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="关于应用" android:text="分屏测试"
android:textSize="16sp" android:textSize="16sp"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:background="#81C7F5" android:background="#81C7F5"
android:paddingVertical="12dp" android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp" android:layout_marginHorizontal="24dp"
android:onClick="onAboutActivity" android:onClick="onSplitScreenMode"
android:layout_margin="10dp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="多开窗口"
android:textSize="16sp"
android:textColor="@android:color/white"
android:background="#81C7F5"
android:paddingVertical="12dp"
android:layout_marginHorizontal="24dp"
android:onClick="onMultiInstance"
android:layout_margin="10dp"/> android:layout_margin="10dp"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</LinearLayout> </LinearLayout>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@android:color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Main2Activity"
android:textSize="24sp"
android:textColor="@color/gray_900"/>
</LinearLayout>

0
gradlew vendored Normal file → Executable file
View File

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat Apr 25 04:11:46 HKT 2026 #Mon Apr 27 20:18:59 HKT 2026
stageCount=20 stageCount=21
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.15 baseVersion=15.15
publishVersion=15.15.19 publishVersion=15.15.20
buildCount=0 buildCount=0
baseBetaVersion=15.15.20 baseBetaVersion=15.15.21

View File

@@ -38,6 +38,7 @@
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:exported="true" android:exported="true"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:taskAffinity="cc.winboll.studio.libappbase.LogActivity"
android:process=":LogActivity"> android:process=":LogActivity">
</activity> </activity>

View File

@@ -1,8 +1,11 @@
package cc.winboll.studio.libappbase; package cc.winboll.studio.libappbase;
import android.app.Activity; import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import cc.winboll.studio.libappbase.LogView; import cc.winboll.studio.libappbase.LogView;
import cc.winboll.studio.libappbase.R; import cc.winboll.studio.libappbase.R;
@@ -46,20 +49,39 @@ public class LogActivity extends Activity {
* @param context 上下文Activity/Fragment用于启动 Activity * @param context 上下文Activity/Fragment用于启动 Activity
*/ */
public static void startLogActivity(Context context) { public static void startLogActivity(Context context) {
// 创建启动当前 Activity 的 Intent startLogActivity(context, true);
}
/**
* 启动日志 Activity 的静态方法重载(外部调用入口)
* @param context 上下文Activity/Fragment用于启动 Activity
* @param newTask 是否在新窗口中启动
*/
public static void startLogActivity(Context context, boolean newTask) {
Intent intent = new Intent(context, LogActivity.class); Intent intent = new Intent(context, LogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// 添加 Intent 标志:支持分屏/多窗口模式API 24+ if (newTask) {
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
// 添加 Intent 标志:创建新任务栈(避免并入调用者任务栈) intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent);
// 添加 Intent 标志:标记为新文档(多任务窗口中独立显示) } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT); intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);
// 添加 Intent 标志:允许创建多个任务实例(支持多次启动独立窗口) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
// 启动 Activity Rect bounds = new Rect();
context.startActivity(intent); if (context instanceof Activity) {
Activity activity = (Activity) context;
activity.getWindow().getDecorView().getDisplay().getRectSize(bounds);
bounds.set(0, bounds.height() / 2, bounds.width(), bounds.height());
}
ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchBounds(bounds);
context.startActivity(intent, options.toBundle());
} else {
context.startActivity(intent);
}
} }
} }

View File

@@ -353,7 +353,7 @@ public class AboutView extends LinearLayout {
*/ */
private void addFunctionView(View view) { private void addFunctionView(View view) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.topMargin = dp2px(PADDING_SMALL); params.topMargin = 0;
llFunctionContainer.addView(view, params); llFunctionContainer.addView(view, params);
} }
@@ -413,7 +413,18 @@ public class AboutView extends LinearLayout {
setPadding(dp2px(PADDING_MID), dp2px(PADDING_SMALL), dp2px(PADDING_MID), dp2px(PADDING_SMALL)); setPadding(dp2px(PADDING_MID), dp2px(PADDING_SMALL), dp2px(PADDING_MID), dp2px(PADDING_SMALL));
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
setClickable(true); setClickable(true);
setBackgroundResource(android.R.drawable.list_selector_background); setBackground(create_item_background());
}
/**
* 创建带1像素边框的背景drawable
*/
private android.graphics.drawable.Drawable create_item_background() {
android.graphics.drawable.GradientDrawable drawable = new android.graphics.drawable.GradientDrawable();
drawable.setStroke(1, mItemContext.getResources().getColor(R.color.gray_200));
drawable.setCornerRadius(4);
drawable.setColor(mItemContext.getResources().getColor(android.R.color.white));
return drawable;
} }
/** /**

View File

@@ -10,15 +10,15 @@
android:orientation="vertical" android:orientation="vertical"
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingTop="32dp" android:paddingTop="16dp"
android:paddingRight="16dp" android:paddingRight="16dp"
android:paddingBottom="32dp"> android:paddingBottom="16dp">
<cc.winboll.studio.libappbase.views.DebugSwitchImageView <cc.winboll.studio.libappbase.views.DebugSwitchImageView
android:id="@+id/iv_app_icon" android:id="@+id/iv_app_icon"
android:layout_width="48dp" android:layout_width="48dp"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="8dp"
android:scaleType="centerCrop"/> android:scaleType="centerCrop"/>
<TextView <TextView
@@ -32,16 +32,16 @@
android:id="@+id/tv_app_desc" android:id="@+id/tv_app_desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="4dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="8dp"
android:textSize="14sp" android:textSize="14sp"
android:textColor="@color/gray_500"/> android:textColor="@color/gray_500"/>
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1px" android:layout_height="1px"
android:layout_marginTop="8dp" android:layout_marginTop="4dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="8dp"
android:background="@color/gray_200"/> android:background="@color/gray_200"/>
<LinearLayout <LinearLayout
@@ -55,7 +55,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:layout_marginTop="16dp" android:layout_marginTop="8dp"
android:spacing="20dp"> android:spacing="20dp">
<ImageButton <ImageButton