init global config view and app list view
This commit is contained in:
@@ -34,6 +34,15 @@ dependencies {
|
||||
implementation 'com.google.android.material:material:1.10.0'
|
||||
implementation 'androidx.activity:activity:1.8.0'
|
||||
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'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- 查询已安装应用的权限 -->
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
||||
73
configapp/src/main/java/com/jiqiu/configapp/AppInfo.java
Normal file
73
configapp/src/main/java/com/jiqiu/configapp/AppInfo.java
Normal 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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
125
configapp/src/main/java/com/jiqiu/configapp/AppListAdapter.java
Normal file
125
configapp/src/main/java/com/jiqiu/configapp/AppListAdapter.java
Normal 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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
166
configapp/src/main/java/com/jiqiu/configapp/AppListFragment.java
Normal file
166
configapp/src/main/java/com/jiqiu/configapp/AppListFragment.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,17 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.graphics.Insets;
|
||||
import androidx.core.view.ViewCompat;
|
||||
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
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -20,5 +29,61 @@ public class MainActivity extends AppCompatActivity {
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
6
configapp/src/main/res/drawable/system_app_badge.xml
Normal file
6
configapp/src/main/res/drawable/system_app_badge.xml
Normal 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>
|
||||
@@ -7,13 +7,26 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
<!-- Fragment容器 -->
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
|
||||
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>
|
||||
42
configapp/src/main/res/layout/fragment_app_list.xml
Normal file
42
configapp/src/main/res/layout/fragment_app_list.xml
Normal 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>
|
||||
108
configapp/src/main/res/layout/fragment_settings.xml
Normal file
108
configapp/src/main/res/layout/fragment_settings.xml
Normal 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>
|
||||
75
configapp/src/main/res/layout/item_app.xml
Normal file
75
configapp/src/main/res/layout/item_app.xml
Normal 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>
|
||||
12
configapp/src/main/res/menu/bottom_nav_menu.xml
Normal file
12
configapp/src/main/res/menu/bottom_nav_menu.xml
Normal 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>
|
||||
@@ -1,3 +1,23 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user