init global config view and app list view

This commit is contained in:
jiqiu2021
2025-06-25 17:41:00 +08:00
parent 4fe44ae346
commit 499a26feec
15 changed files with 830 additions and 9 deletions

View File

@@ -34,6 +34,15 @@ dependencies {
implementation 'com.google.android.material:material:1.10.0' implementation 'com.google.android.material:material:1.10.0'
implementation 'androidx.activity:activity:1.8.0' implementation 'androidx.activity:activity:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
// Fragment and Navigation dependencies
implementation 'androidx.fragment:fragment:1.6.2'
implementation 'androidx.navigation:navigation-fragment:2.7.5'
implementation 'androidx.navigation:navigation-ui:2.7.5'
// RecyclerView for app list
implementation 'androidx.recyclerview:recyclerview:1.3.2'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 查询已安装应用的权限 -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"

View File

@@ -0,0 +1,73 @@
package com.jiqiu.configapp;
import android.graphics.drawable.Drawable;
/**
* 应用程序信息数据模型
*/
public class AppInfo {
private String appName; // 应用名称
private String packageName; // 包名
private Drawable appIcon; // 应用图标
private boolean isSystemApp; // 是否为系统应用
private boolean isEnabled; // 是否启用注入
public AppInfo(String appName, String packageName, Drawable appIcon, boolean isSystemApp) {
this.appName = appName;
this.packageName = packageName;
this.appIcon = appIcon;
this.isSystemApp = isSystemApp;
this.isEnabled = false; // 默认不启用注入
}
// Getter 和 Setter 方法
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public Drawable getAppIcon() {
return appIcon;
}
public void setAppIcon(Drawable appIcon) {
this.appIcon = appIcon;
}
public boolean isSystemApp() {
return isSystemApp;
}
public void setSystemApp(boolean systemApp) {
isSystemApp = systemApp;
}
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean enabled) {
isEnabled = enabled;
}
@Override
public String toString() {
return "AppInfo{" +
"appName='" + appName + '\'' +
", packageName='" + packageName + '\'' +
", isSystemApp=" + isSystemApp +
", isEnabled=" + isEnabled +
'}';
}
}

View File

@@ -0,0 +1,125 @@
package com.jiqiu.configapp;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.switchmaterial.SwitchMaterial;
import java.util.ArrayList;
import java.util.List;
/**
* 应用列表适配器
*/
public class AppListAdapter extends RecyclerView.Adapter<AppListAdapter.AppViewHolder> {
private List<AppInfo> appList;
private List<AppInfo> filteredAppList;
private OnAppToggleListener onAppToggleListener;
public interface OnAppToggleListener {
void onAppToggle(AppInfo appInfo, boolean isEnabled);
}
public AppListAdapter() {
this.appList = new ArrayList<>();
this.filteredAppList = new ArrayList<>();
}
public void setAppList(List<AppInfo> appList) {
this.appList = appList;
this.filteredAppList = new ArrayList<>(appList);
notifyDataSetChanged();
}
public void setOnAppToggleListener(OnAppToggleListener listener) {
this.onAppToggleListener = listener;
}
public void filterApps(String query, boolean hideSystemApps) {
filteredAppList.clear();
for (AppInfo app : appList) {
// 过滤系统应用
if (hideSystemApps && app.isSystemApp()) {
continue;
}
// 搜索过滤
if (query == null || query.isEmpty() ||
app.getAppName().toLowerCase().contains(query.toLowerCase()) ||
app.getPackageName().toLowerCase().contains(query.toLowerCase())) {
filteredAppList.add(app);
}
}
notifyDataSetChanged();
}
@NonNull
@Override
public AppViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_app, parent, false);
return new AppViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull AppViewHolder holder, int position) {
AppInfo appInfo = filteredAppList.get(position);
holder.bind(appInfo);
}
@Override
public int getItemCount() {
return filteredAppList.size();
}
class AppViewHolder extends RecyclerView.ViewHolder {
private ImageView appIcon;
private TextView appName;
private TextView packageName;
private TextView systemAppLabel;
private SwitchMaterial switchEnable;
public AppViewHolder(@NonNull View itemView) {
super(itemView);
appIcon = itemView.findViewById(R.id.app_icon);
appName = itemView.findViewById(R.id.app_name);
packageName = itemView.findViewById(R.id.package_name);
systemAppLabel = itemView.findViewById(R.id.system_app_label);
switchEnable = itemView.findViewById(R.id.switch_enable);
}
public void bind(AppInfo appInfo) {
appIcon.setImageDrawable(appInfo.getAppIcon());
appName.setText(appInfo.getAppName());
packageName.setText(appInfo.getPackageName());
// 显示系统应用标签
if (appInfo.isSystemApp()) {
systemAppLabel.setVisibility(View.VISIBLE);
} else {
systemAppLabel.setVisibility(View.GONE);
}
// 设置开关状态
switchEnable.setOnCheckedChangeListener(null); // 清除之前的监听器
switchEnable.setChecked(appInfo.isEnabled());
// 设置开关监听器
switchEnable.setOnCheckedChangeListener((buttonView, isChecked) -> {
appInfo.setEnabled(isChecked);
if (onAppToggleListener != null) {
onAppToggleListener.onAppToggle(appInfo, isChecked);
}
});
}
}
}

View File

@@ -0,0 +1,166 @@
package com.jiqiu.configapp;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textfield.TextInputEditText;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 应用列表Fragment
*/
public class AppListFragment extends Fragment implements AppListAdapter.OnAppToggleListener {
private RecyclerView recyclerView;
private AppListAdapter adapter;
private TextInputEditText searchEditText;
private ProgressBar progressBar;
private List<AppInfo> allApps;
private boolean hideSystemApps = false;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_app_list, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
setupRecyclerView();
setupSearchView();
loadApps();
}
private void initViews(View view) {
recyclerView = view.findViewById(R.id.recycler_view_apps);
searchEditText = view.findViewById(R.id.search_edit_text);
progressBar = view.findViewById(R.id.progress_bar);
}
private void setupRecyclerView() {
adapter = new AppListAdapter();
adapter.setOnAppToggleListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
}
private void setupSearchView() {
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
filterApps(s.toString());
}
@Override
public void afterTextChanged(Editable s) {}
});
}
private void loadApps() {
progressBar.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
new LoadAppsTask().execute();
}
private void filterApps(String query) {
if (adapter != null) {
adapter.filterApps(query, hideSystemApps);
}
}
public void setHideSystemApps(boolean hideSystemApps) {
this.hideSystemApps = hideSystemApps;
filterApps(searchEditText.getText().toString());
}
@Override
public void onAppToggle(AppInfo appInfo, boolean isEnabled) {
// 这里可以保存应用的启用状态到配置文件或数据库
// 暂时只是打印日志
android.util.Log.d("AppListFragment",
"App " + appInfo.getAppName() + " toggle: " + isEnabled);
}
/**
* 异步加载应用列表
*/
private class LoadAppsTask extends AsyncTask<Void, Void, List<AppInfo>> {
@Override
protected List<AppInfo> doInBackground(Void... voids) {
List<AppInfo> apps = new ArrayList<>();
PackageManager pm = getContext().getPackageManager();
List<ApplicationInfo> installedApps = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo appInfo : installedApps) {
try {
String appName = pm.getApplicationLabel(appInfo).toString();
String packageName = appInfo.packageName;
boolean isSystemApp = (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
AppInfo app = new AppInfo(
appName,
packageName,
pm.getApplicationIcon(appInfo),
isSystemApp
);
apps.add(app);
} catch (Exception e) {
// 忽略无法获取信息的应用
e.printStackTrace();
}
}
// 按应用名称排序
Collections.sort(apps, new Comparator<AppInfo>() {
@Override
public int compare(AppInfo o1, AppInfo o2) {
return o1.getAppName().compareToIgnoreCase(o2.getAppName());
}
});
return apps;
}
@Override
protected void onPostExecute(List<AppInfo> apps) {
allApps = apps;
adapter.setAppList(apps);
progressBar.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
// 应用当前的过滤设置
filterApps(searchEditText.getText().toString());
}
}
}

View File

@@ -7,8 +7,17 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets; import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity { import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity implements SettingsFragment.OnSettingsChangeListener {
private BottomNavigationView bottomNavigationView;
private AppListFragment appListFragment;
private SettingsFragment settingsFragment;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -20,5 +29,61 @@ public class MainActivity extends AppCompatActivity {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets; return insets;
}); });
initViews();
setupBottomNavigation();
// 默认显示应用列表
if (savedInstanceState == null) {
showAppListFragment();
}
}
private void initViews() {
bottomNavigationView = findViewById(R.id.bottom_navigation);
}
private void setupBottomNavigation() {
bottomNavigationView.setOnItemSelectedListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.navigation_apps) {
showAppListFragment();
return true;
} else if (itemId == R.id.navigation_settings) {
showSettingsFragment();
return true;
}
return false;
});
}
private void showAppListFragment() {
if (appListFragment == null) {
appListFragment = new AppListFragment();
}
showFragment(appListFragment);
}
private void showSettingsFragment() {
if (settingsFragment == null) {
settingsFragment = new SettingsFragment();
settingsFragment.setOnSettingsChangeListener(this);
}
showFragment(settingsFragment);
}
private void showFragment(Fragment fragment) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.nav_host_fragment, fragment);
transaction.commit();
}
@Override
public void onHideSystemAppsChanged(boolean hideSystemApps) {
// 当设置改变时通知应用列表Fragment更新过滤
if (appListFragment != null) {
appListFragment.setHideSystemApps(hideSystemApps);
}
} }
} }

View File

@@ -0,0 +1,98 @@
package com.jiqiu.configapp;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/**
* 设置Fragment
*/
public class SettingsFragment extends Fragment {
private static final String PREFS_NAME = "MyInjectorSettings";
private static final String KEY_HIDE_SYSTEM_APPS = "hide_system_apps";
private RadioGroup radioGroupFilter;
private RadioButton radioShowAll;
private RadioButton radioHideSystem;
private SharedPreferences sharedPreferences;
private OnSettingsChangeListener settingsChangeListener;
public interface OnSettingsChangeListener {
void onHideSystemAppsChanged(boolean hideSystemApps);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_settings, container, false);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
initSharedPreferences();
loadSettings();
setupListeners();
}
private void initViews(View view) {
radioGroupFilter = view.findViewById(R.id.radio_group_filter);
radioShowAll = view.findViewById(R.id.radio_show_all);
radioHideSystem = view.findViewById(R.id.radio_hide_system);
}
private void initSharedPreferences() {
sharedPreferences = getContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
}
private void loadSettings() {
boolean hideSystemApps = sharedPreferences.getBoolean(KEY_HIDE_SYSTEM_APPS, false);
if (hideSystemApps) {
radioHideSystem.setChecked(true);
} else {
radioShowAll.setChecked(true);
}
}
private void setupListeners() {
radioGroupFilter.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
boolean hideSystemApps = (checkedId == R.id.radio_hide_system);
// 保存设置
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(KEY_HIDE_SYSTEM_APPS, hideSystemApps);
editor.apply();
// 通知设置变化
if (settingsChangeListener != null) {
settingsChangeListener.onHideSystemAppsChanged(hideSystemApps);
}
}
});
}
public void setOnSettingsChangeListener(OnSettingsChangeListener listener) {
this.settingsChangeListener = listener;
}
public boolean isHideSystemApps() {
return sharedPreferences.getBoolean(KEY_HIDE_SYSTEM_APPS, false);
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF9800" />
<corners android:radius="12dp" />
</shape>

View File

@@ -7,13 +7,26 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView <!-- Fragment容器 -->
android:layout_width="wrap_content" <androidx.fragment.app.FragmentContainerView
android:layout_height="wrap_content" android:id="@+id/nav_host_fragment"
android:text="Hello World!" android:layout_width="0dp"
app:layout_constraintBottom_toBottomOf="parent" android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
<!-- 底部导航栏 -->
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="@menu/bottom_nav_menu" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:padding="16dp"
tools:context=".AppListFragment">
<!-- 搜索框 -->
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:hint="@string/search_apps">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/search_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<!-- 应用列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_apps"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="vertical" />
<!-- 加载进度条 -->
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</LinearLayout>

View File

@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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=".SettingsFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- 全局设置标题 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/global_settings"
android:textSize="18sp"
android:textStyle="bold"
android:layout_marginBottom="16dp" />
<!-- 过滤系统应用设置 -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/filter_system_apps"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/filter_system_apps_desc"
android:textSize="14sp"
android:textColor="@android:color/darker_gray"
android:layout_marginBottom="12dp" />
<RadioGroup
android:id="@+id/radio_group_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/radio_show_all"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/show_all_apps"
android:checked="true" />
<RadioButton
android:id="@+id/radio_hide_system"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hide_system_apps" />
</RadioGroup>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
<!-- 其他设置可以在这里添加 -->
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/about"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginBottom="8dp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_description"
android:textSize="14sp"
android:textColor="@android:color/darker_gray" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
app:cardCornerRadius="8dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="12dp"
android:gravity="center_vertical">
<!-- 应用图标 -->
<ImageView
android:id="@+id/app_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="12dp"
android:scaleType="centerCrop" />
<!-- 应用信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:maxLines="1"
android:ellipsize="end" />
<TextView
android:id="@+id/package_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="@android:color/darker_gray"
android:maxLines="1"
android:ellipsize="end"
android:layout_marginTop="2dp" />
<!-- 系统应用标签 -->
<TextView
android:id="@+id/system_app_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/system_app"
android:textSize="10sp"
android:textColor="@android:color/white"
android:background="@drawable/system_app_badge"
android:padding="4dp"
android:layout_marginTop="4dp"
android:visibility="gone" />
</LinearLayout>
<!-- 启用开关 -->
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_enable"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_apps"
android:icon="@android:drawable/ic_menu_view"
android:title="@string/title_apps" />
<item
android:id="@+id/navigation_settings"
android:icon="@android:drawable/ic_menu_preferences"
android:title="@string/title_settings" />
</menu>

View File

@@ -1,3 +1,23 @@
<resources> <resources>
<string name="app_name">configapp</string> <string name="app_name">MyInjector Config</string>
<!-- 底部导航 -->
<string name="title_apps">应用列表</string>
<string name="title_settings">全局设置</string>
<!-- 应用列表 -->
<string name="search_apps">搜索应用</string>
<string name="system_app">系统应用</string>
<string name="loading_apps">正在加载应用列表...</string>
<!-- 设置页面 -->
<string name="global_settings">全局设置</string>
<string name="filter_system_apps">过滤系统应用</string>
<string name="filter_system_apps_desc">选择是否在应用列表中显示系统应用</string>
<string name="show_all_apps">显示所有应用</string>
<string name="hide_system_apps">隐藏系统应用</string>
<!-- 关于 -->
<string name="about">关于</string>
<string name="app_description">MyInjector 配置应用,用于管理注入设置</string>
</resources> </resources>

View File

@@ -17,3 +17,9 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX # Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true android.enableJetifier=true
# Fix TLS handshake issues
systemProp.https.protocols=TLSv1.2,TLSv1.3
systemProp.http.proxyHost=
systemProp.http.proxyPort=
systemProp.https.proxyHost=
systemProp.https.proxyPort=