代码优化
@@ -1,4 +1,5 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="top.iletter.mooknote">
|
||||||
<application
|
<application
|
||||||
android:label="MookNote"
|
android:label="MookNote"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
@@ -19,13 +20,17 @@
|
|||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
/>
|
/>
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<!-- 图标1: 默认图标 -->
|
<!-- 图标1: 默认图标 -->
|
||||||
<activity-alias
|
<activity-alias
|
||||||
android:name=".MainActivityIcon1"
|
android:name=".MainActivityIcon1"
|
||||||
android:targetActivity=".MainActivity"
|
android:targetActivity=".MainActivity"
|
||||||
android:enabled="true"
|
android:enabled="false"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:roundIcon="@mipmap/ic_launcher"
|
android:roundIcon="@mipmap/ic_launcher"
|
||||||
|
|||||||
@@ -34,22 +34,32 @@ class MainActivity : FlutterActivity() {
|
|||||||
|
|
||||||
private fun switchLauncherIcon(iconName: String) {
|
private fun switchLauncherIcon(iconName: String) {
|
||||||
val pm = packageManager
|
val pm = packageManager
|
||||||
|
val mainActivity = ComponentName(this, "${packageName}.MainActivity")
|
||||||
val icon1 = ComponentName(this, "${packageName}.MainActivityIcon1")
|
val icon1 = ComponentName(this, "${packageName}.MainActivityIcon1")
|
||||||
val icon2 = ComponentName(this, "${packageName}.MainActivityIcon2")
|
val icon2 = ComponentName(this, "${packageName}.MainActivityIcon2")
|
||||||
val icon3 = ComponentName(this, "${packageName}.MainActivityIcon3")
|
val icon3 = ComponentName(this, "${packageName}.MainActivityIcon3")
|
||||||
|
|
||||||
// 先全部禁用
|
// 先禁用所有别名
|
||||||
pm.setComponentEnabledSetting(icon1, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
pm.setComponentEnabledSetting(icon1, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
||||||
pm.setComponentEnabledSetting(icon2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
pm.setComponentEnabledSetting(icon2, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
||||||
pm.setComponentEnabledSetting(icon3, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
pm.setComponentEnabledSetting(icon3, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
||||||
|
|
||||||
// 启用选中的
|
when (iconName) {
|
||||||
val target = when (iconName) {
|
"app_icon2" -> {
|
||||||
"app_icon2" -> icon2
|
// 切换到图标2:禁用主Activity的LAUNCHER,启用别名
|
||||||
"app_icon_m" -> icon3
|
pm.setComponentEnabledSetting(mainActivity, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
||||||
else -> icon1
|
pm.setComponentEnabledSetting(icon2, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
|
||||||
|
}
|
||||||
|
"app_icon_m" -> {
|
||||||
|
// 切换到图标3:禁用主Activity的LAUNCHER,启用别名
|
||||||
|
pm.setComponentEnabledSetting(mainActivity, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
|
||||||
|
pm.setComponentEnabledSetting(icon3, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// 切换回默认图标:启用主Activity,禁用所有别名(已在上面禁用)
|
||||||
|
pm.setComponentEnabledSetting(mainActivity, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pm.setComponentEnabledSetting(target, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCurrentIcon(): String {
|
private fun getCurrentIcon(): String {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
|
org.gradle.java.home=D:\\Environment\\Java\\java17
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
systemProp.http.proxyHost=127.0.0.1
|
systemProp.http.proxyHost=127.0.0.1
|
||||||
systemProp.http.proxyPort=10808
|
systemProp.http.proxyPort=10808
|
||||||
|
|||||||
@@ -195,6 +195,14 @@ class _EpubDetailPageState extends State<EpubDetailPage> {
|
|||||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 24),
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 24),
|
||||||
child: _buildLinkedBookCard(colors),
|
child: _buildLinkedBookCard(colors),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// ── 其他作品(同作者)──
|
||||||
|
if (author.isNotEmpty) ...[
|
||||||
|
Divider(height: 0.5, thickness: 0.5, color: colors.outline),
|
||||||
|
_buildSectionHeader('其他作品', colors),
|
||||||
|
_buildOtherWorks(author, colors),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -396,6 +404,77 @@ class _EpubDetailPageState extends State<EpubDetailPage> {
|
|||||||
await _refreshBook();
|
await _refreshBook();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildOtherWorks(String author, ColorScheme colors) {
|
||||||
|
final linkedBookId = _book['book_id'] as String? ?? '';
|
||||||
|
return FutureBuilder<List<Book>>(
|
||||||
|
future: _bookDao.getBooksByAuthor(author),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (!snapshot.hasData || snapshot.data!.isEmpty) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
|
||||||
|
child: Text('暂未收藏该作者其他作品',
|
||||||
|
style: TextStyle(fontSize: 13, color: colors.onSurface.withValues(alpha: 0.35))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
final books = snapshot.data!.where((b) => b.id != linkedBookId).toList();
|
||||||
|
if (books.isEmpty) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
|
||||||
|
child: Text('暂未收藏该作者其他作品',
|
||||||
|
style: TextStyle(fontSize: 13, color: colors.onSurface.withValues(alpha: 0.35))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return SizedBox(
|
||||||
|
height: 160,
|
||||||
|
child: ListView.builder(
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
itemCount: books.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final book = books[index];
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => Navigator.push(context,
|
||||||
|
MaterialPageRoute(builder: (_) => BookDetailPage(book: book))),
|
||||||
|
child: Container(
|
||||||
|
width: 90,
|
||||||
|
margin: const EdgeInsets.only(right: 12),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
width: 90, height: 126,
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
child: book.coverPath != null && book.coverPath!.isNotEmpty
|
||||||
|
? Image.file(File(book.coverPath!), fit: BoxFit.cover,
|
||||||
|
errorBuilder: (_, __, ___) => _buildBookCoverPlaceholder(colors))
|
||||||
|
: _buildBookCoverPlaceholder(colors),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Text(book.title, maxLines: 1, overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(fontSize: 11, color: colors.onSurface)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBookCoverPlaceholder(ColorScheme colors) {
|
||||||
|
return Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: colors.surfaceContainerHighest,
|
||||||
|
borderRadius: BorderRadius.circular(6),
|
||||||
|
),
|
||||||
|
child: Icon(Icons.menu_book_outlined, size: 28, color: colors.onSurface.withValues(alpha: 0.2)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildCover(String? coverPath, ColorScheme colors) {
|
Widget _buildCover(String? coverPath, ColorScheme colors) {
|
||||||
if (coverPath != null && coverPath.isNotEmpty && File(coverPath).existsSync()) {
|
if (coverPath != null && coverPath.isNotEmpty && File(coverPath).existsSync()) {
|
||||||
return ClipRRect(
|
return ClipRRect(
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 328 KiB |
|
Before Width: | Height: | Size: 238 KiB |
|
Before Width: | Height: | Size: 200 KiB |
BIN
proj-img/bj1.png
|
Before Width: | Height: | Size: 280 KiB |
BIN
proj-img/bj2.png
|
Before Width: | Height: | Size: 274 KiB |
BIN
proj-img/fx1.png
|
Before Width: | Height: | Size: 289 KiB |
BIN
proj-img/fx2.png
|
Before Width: | Height: | Size: 341 KiB |
BIN
proj-img/xq1.png
|
Before Width: | Height: | Size: 2.0 MiB |
BIN
proj-img/xq2.png
|
Before Width: | Height: | Size: 1.7 MiB |