diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c78eddc..326bf68 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,7 +6,7 @@ plugins { id("com.google.gms.google-services") id("com.google.firebase.crashlytics") } -val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date()) +val timestamp: String = SimpleDateFormat("MM_dd_HH_mm").format(Date()) android { namespace = "com.key.vibekeyboard" compileSdk = 34 @@ -19,8 +19,8 @@ android { applicationId = "com.key.vibekeyboard" minSdk = 23 targetSdk = 34 - versionCode = 2 - versionName = "1.0.1" + versionCode = 3 + versionName = "1.0.2" setProperty( "archivesBaseName", "Mobile Keyboard" + versionName + "(${versionCode})_$timestamp" @@ -63,7 +63,7 @@ dependencies { // Import the BoM for the Firebase platform - implementation(platform("com.google.firebase:firebase-bom:33.6.0")) + implementation(platform("com.google.firebase:firebase-bom:33.7.0")) // Add the dependencies for the Crashlytics and Analytics libraries // When using the BoM, you don't specify versions in Firebase library dependencies diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9f2524d..af0ad94 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,18 +20,18 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile --keepclassmembers class com.key.vibekeyboard.AppApplication { - public static final java.lang.String DB_Name; - public static final int DB_Version; +-keepclassmembers class com.key.vibekeyboard.MyApplication { + public static final java.lang.String DB_NAME; + public static final int DB_VERSION; } -keepclassmembers class * { @androidx.room.Query ; } --keep class com.key.vibekeyboard.Room.MyDatabase { *; } --keep class com.key.vibekeyboard.Room.WallpaperInfo { *; } --keep class com.key.vibekeyboard.Room.WallpaperInfoDao { *; } --keep class com.key.vibekeyboard.Room.Category { *; } +-keep class com.key.vibekeyboard.data.database.AppDatabase { *; } +-keep class com.key.vibekeyboard.data.database.entity.WallpaperInfo { *; } +-keep class com.key.vibekeyboard.data.database.dao.WallpaperInfoDao { *; } +-keep class com.key.vibekeyboard.data.bean.Category { *; } -keep class com.omicronapplications.** { *; } -keep class net.sf.sevenzipjbinding.** { *; } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9f463e3..0ff8d05 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ - @@ -45,9 +42,10 @@ diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/MainActivity.java b/app/src/main/java/com/key/vibekeyboard/Activity/MainActivity.java deleted file mode 100644 index 3b05b7b..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Activity/MainActivity.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.key.vibekeyboard.Activity; - -import android.os.Bundle; -import android.view.LayoutInflater; - -import androidx.appcompat.app.AppCompatActivity; - -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; -import com.key.vibekeyboard.Adapter.MainViewpager2Adapter; -import com.key.vibekeyboard.AppApplication; -import com.key.vibekeyboard.Dialog.PermissionRequestDialog; -import com.key.vibekeyboard.Dialog.RecommendedDialog; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.Utils.Mytool; -import com.key.vibekeyboard.databinding.ActivityMainBinding; -import com.key.vibekeyboard.databinding.MainTabCustomBinding; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Random; - -public class MainActivity extends AppCompatActivity { - - private ActivityMainBinding binding; - private List list = new ArrayList<>(); - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // 使用 ViewBinding 绑定布局 - binding = ActivityMainBinding.inflate(getLayoutInflater()); - setContentView(binding.getRoot()); - - // 创建并设置 ViewPager 适配器 - MainViewpager2Adapter adapter = new MainViewpager2Adapter(this); - binding.mainViewpager.setAdapter(adapter); - - // 解析 Json 文件并随机选取一个分类 - List categories = AppApplication.getCategories(); - Random random = new Random(); - int randomIndex = random.nextInt(categories.size()); // 随机选取分类索引 - list = categories.get(randomIndex).getList(); // 获取随机选中的分类中的壁纸列表 - - // 判断是否完成步骤1和步骤2,显示相应的对话框 - if (Mytool.isStep1() && Mytool.isStep2()) { - showRecommendedDialog(); // 如果两个步骤都完成,显示推荐对话框 - } else { - showPermissionDialog(); // 否则显示权限请求对话框 - } - -// binding.mainViewpager.setUserInputEnabled(false);//禁止页面左右滑动 - - // 初始化 TabLayout(标签栏) - tabLayout(); - } - - // 显示权限请求对话框 - public void showPermissionDialog() { - PermissionRequestDialog dialog = new PermissionRequestDialog(); - dialog.show(getSupportFragmentManager(), "PermissionRequestDialog"); - } - - // 显示推荐壁纸对话框 - public void showRecommendedDialog() { - RecommendedDialog dialog = new RecommendedDialog(); - if (list != null) { - dialog.setList(list); // 设置壁纸列表 - } - dialog.show(getSupportFragmentManager(), "RecommendedDialog"); - } - - // 初始化 TabLayout,设置标签和关联的 ViewPager - public void tabLayout() { - // 使用 TabLayoutMediator 连接 TabLayout 和 ViewPager2 - new TabLayoutMediator(binding.mainTablayout, binding.mainViewpager, (tab, position) -> { - // 创建自定义 Tab 视图 - MainTabCustomBinding tabBinding = MainTabCustomBinding.inflate(LayoutInflater.from(this)); - tab.setCustomView(tabBinding.getRoot()); - - // 设置默认的图标,未选中状态的图标 - if (position == 0) { - tabBinding.iconCustom.setImageResource(R.drawable.home_select); // 第一个 Tab 图标 - } else if (position == 1) { - tabBinding.iconCustom.setImageResource(R.drawable.collection); // 第二个 Tab 图标 - } else { - tabBinding.iconCustom.setImageResource(R.drawable.setting); // 第三个 Tab 图标 - } - }).attach(); // 绑定 TabLayout 和 ViewPager - - // 设置 Tab 选中时和未选中时的图标变化 - binding.mainTablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { - @Override - public void onTabSelected(TabLayout.Tab tab) { - // 选中时更改图标 - MainTabCustomBinding tabBinding = MainTabCustomBinding.bind(Objects.requireNonNull(tab.getCustomView())); - int position = tab.getPosition(); - if (position == 0) { - tabBinding.iconCustom.setImageResource(R.drawable.home_select); // 选中状态的图标 - } else if (position == 1) { - tabBinding.iconCustom.setImageResource(R.drawable.collection_select); // 第二个 Tab 选中图标 - } else { - tabBinding.iconCustom.setImageResource(R.drawable.setting_select); // 第三个 Tab 选中图标 - } - } - - @Override - public void onTabUnselected(TabLayout.Tab tab) { - // 未选中时恢复默认图标 - MainTabCustomBinding tabBinding = MainTabCustomBinding.bind(Objects.requireNonNull(tab.getCustomView())); - int position = tab.getPosition(); - if (position == 0) { - tabBinding.iconCustom.setImageResource(R.drawable.home); // 未选中状态的图标 - } else if (position == 1) { - tabBinding.iconCustom.setImageResource(R.drawable.collection); // 第二个 Tab 未选中图标 - } else { - tabBinding.iconCustom.setImageResource(R.drawable.setting); // 第三个 Tab 未选中图标 - } - } - - @Override - public void onTabReselected(TabLayout.Tab tab) { - // 可以留空,或者添加重复选择时的逻辑 - } - }); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - binding = null; // 释放 ViewBinding 的引用 - } - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/WriteActivity.java b/app/src/main/java/com/key/vibekeyboard/Activity/WriteActivity.java deleted file mode 100644 index 5c82d62..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Activity/WriteActivity.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.key.vibekeyboard.Activity; - -import android.os.Bundle; - -import androidx.appcompat.app.AppCompatActivity; - -import com.key.vibekeyboard.databinding.ActivityWriteBinding; - -public class WriteActivity extends AppCompatActivity { - - private ActivityWriteBinding binding; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - binding = ActivityWriteBinding.inflate(getLayoutInflater()); - setContentView(binding.getRoot()); - - binding.back.setOnClickListener(v -> finish()); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/key/vibekeyboard/Adapter/DownlaodRecyclerViewAdapter.java b/app/src/main/java/com/key/vibekeyboard/Adapter/DownlaodRecyclerViewAdapter.java deleted file mode 100644 index 7c3eb0c..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Adapter/DownlaodRecyclerViewAdapter.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.key.vibekeyboard.Adapter; - -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.resource.bitmap.CenterCrop; -import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Activity.DownloadActivity; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.WallpaperInfo; - -import java.util.ArrayList; -import java.util.List; - -public class DownlaodRecyclerViewAdapter extends RecyclerView.Adapter { - - private DownloadActivity downloadActivity; - private WallpaperInfo wallpaperInfo; - private List list; - - public DownlaodRecyclerViewAdapter(DownloadActivity downloadActivity, WallpaperInfo wallpaperInfo, List list) { - this.downloadActivity = downloadActivity; - this.wallpaperInfo = wallpaperInfo; - this.list = list; - } - - @NonNull - @Override - public DownlaodRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_recycler_item, parent, false); - return new DownlaodRecyclerViewHolder(view); - } - - @Override - public void onBindViewHolder(@NonNull DownlaodRecyclerViewHolder holder, int position) { - - WallpaperInfo wallpaperInfo1 = list.get(position); - - List limitedList = list.subList(0, Math.min(20, list.size())); - - holder.imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(downloadActivity, DownloadActivity.class); - intent.putExtra("wallpaperInfo", wallpaperInfo1); // wallpaperInfo 已经实现了 Parcelable - intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); // list 中的 WallpaperInfo 对象实现了 Parcelable - downloadActivity.startActivity(intent); - } - }); - - // 应用圆角变换 - RequestOptions options = new RequestOptions() - .placeholder(R.mipmap.splash) - .error(R.mipmap.splash) - .transform(new CenterCrop()) - .transform(new RoundedCorners(16)); // 设置圆角度数 - - Glide.with(downloadActivity) - .load(list.get(position).getPreview()) - .apply(options) - .into(holder.imageView); - - } - - @Override - public int getItemCount() { - return list.size(); - } - - public static class DownlaodRecyclerViewHolder extends RecyclerView.ViewHolder { - - private ImageView imageView; - - public DownlaodRecyclerViewHolder(@NonNull View itemView) { - super(itemView); - imageView = itemView.findViewById(R.id.home_recycler_image); - } - } - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Adapter/FavoriteRecyclerViewAdapter.java b/app/src/main/java/com/key/vibekeyboard/Adapter/FavoriteRecyclerViewAdapter.java deleted file mode 100644 index 2fc80b0..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Adapter/FavoriteRecyclerViewAdapter.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.key.vibekeyboard.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.resource.bitmap.CenterCrop; -import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Activity.DownloadActivity; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.WallpaperInfo; - -import java.util.ArrayList; -import java.util.List; - -public class FavoriteRecyclerViewAdapter extends RecyclerView.Adapter { - - - private Context context; - private List list; - - public FavoriteRecyclerViewAdapter(Context context, List list) { - - this.context = context; - this.list = new ArrayList<>(list); - - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_recycler_item, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - - WallpaperInfo wallpaperInfo = list.get(position); - - List limitedList = list.subList(0, Math.min(20, list.size())); - - if (wallpaperInfo != null) { - holder.imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(context, DownloadActivity.class); - intent.putExtra("wallpaperInfo", wallpaperInfo); // wallpaperInfo 已经实现了 Parcelable - intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); // list 中的 WallpaperInfo 对象实现了 Parcelable - context.startActivity(intent); - } - }); - } - - // 应用圆角变换 - RequestOptions options = new RequestOptions() - .placeholder(R.mipmap.splash) - .error(R.mipmap.splash) - .transform(new CenterCrop()) - .transform(new RoundedCorners(16)); // 设置圆角度数 - if (wallpaperInfo != null) { - Glide.with(context) - .load(wallpaperInfo.getPreview()) - .apply(options) - .into(holder.imageView); - - } - } - - @Override - public int getItemCount() { - return (list != null) ? list.size() : 0; - } - - - public static class ViewHolder extends RecyclerView.ViewHolder { - - private ImageView imageView; - - public ViewHolder(@NonNull View itemView) { - super(itemView); - - imageView = itemView.findViewById(R.id.home_recycler_image); - } - } - - // 使用 DiffUtil 更新列表 - public void updateList(List newList) { - DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() { - @Override - public int getOldListSize() { - return list.size(); - } - - @Override - public int getNewListSize() { - return newList.size(); - } - - @Override - public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { - // 通过唯一标识符比较两个项目是否相同 - return list.get(oldItemPosition).getId() == newList.get(newItemPosition).getId(); - } - - @Override - public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { - // 比较内容是否相同 - return list.get(oldItemPosition).equals(newList.get(newItemPosition)); - } - }); - - list.clear(); - list.addAll(newList); - diffResult.dispatchUpdatesTo(this); // 通知 RecyclerView 进行局部更新 - } - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Adapter/HomeRecyclerViewAdapter.java b/app/src/main/java/com/key/vibekeyboard/Adapter/HomeRecyclerViewAdapter.java deleted file mode 100644 index 8e00f48..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Adapter/HomeRecyclerViewAdapter.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.key.vibekeyboard.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.resource.bitmap.CenterCrop; -import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Activity.DownloadActivity; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.WallpaperInfo; - -import java.util.ArrayList; -import java.util.List; - -public class HomeRecyclerViewAdapter extends RecyclerView.Adapter { - - private List categories; - private Context context; - - public HomeRecyclerViewAdapter(Context context,List categories) { - this.context = context; - this.categories = categories; - } - - @NonNull - @Override - public HomeRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_recycler_item, parent, false); - return new HomeRecyclerViewHolder(view); - } - - @Override - public void onBindViewHolder(@NonNull HomeRecyclerViewHolder holder, int position) { - - Category category = categories.get(position); - List list = category.getList(); - WallpaperInfo categoryWallpaperInfo = category.getList().get(position); - WallpaperInfo wallpaperInfo = category.getList().get(0); - - List limitedList = list.subList(0, Math.min(20, list.size())); - - holder.imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(context, DownloadActivity.class); - intent.putExtra("wallpaperInfo", wallpaperInfo); // wallpaperInfo 已经实现了 Parcelable - intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); // list 中的 WallpaperInfo 对象实现了 Parcelable - context.startActivity(intent); - } - }); - - - // 应用圆角变换 - RequestOptions options = new RequestOptions() - .placeholder(R.mipmap.splash) - .error(R.mipmap.splash) - .transform(new CenterCrop()) - .transform(new RoundedCorners(16)); // 设置圆角度数 - - Glide.with(context) - .load(wallpaperInfo.getPreview()) - .apply(options) - .into(holder.imageView); - } - - @Override - public int getItemCount() { - return categories.size(); - } - - public static class HomeRecyclerViewHolder extends RecyclerView.ViewHolder { - private ImageView imageView; - - public HomeRecyclerViewHolder(View view) { - super(view); - imageView = view.findViewById(R.id.home_recycler_image); - } - } - - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Adapter/SearchRecyclerViewAdapter.java b/app/src/main/java/com/key/vibekeyboard/Adapter/SearchRecyclerViewAdapter.java deleted file mode 100644 index 663dd70..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Adapter/SearchRecyclerViewAdapter.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.key.vibekeyboard.Adapter; - -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.resource.bitmap.CenterCrop; -import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Activity.DownloadActivity; -import com.key.vibekeyboard.Activity.SearchActivity; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.WallpaperInfo; - -import java.util.ArrayList; -import java.util.List; - -public class SearchRecyclerViewAdapter extends RecyclerView.Adapter { - - private List wallpaperList; - private SearchActivity context; - - public SearchRecyclerViewAdapter(List wallpaperList, SearchActivity context) { - this.wallpaperList = wallpaperList; - this.context = context; - } - - @NonNull - @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_recycler_item, parent, false); - return new ViewHolder(view); - } - - @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { - WallpaperInfo wallpaperInfo = wallpaperList.get(position); - - List limitedList = wallpaperList.subList(0, Math.min(20, wallpaperList.size())); - - holder.imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(context, DownloadActivity.class); - intent.putExtra("wallpaperInfo", wallpaperInfo); // wallpaperInfo 已经实现了 Parcelable - intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); // list 中的 WallpaperInfo 对象实现了 Parcelable - context.startActivity(intent); - } - }); -// 应用圆角变换 - RequestOptions options = new RequestOptions() - .placeholder(R.mipmap.splash) - .error(R.mipmap.splash) - .transform(new CenterCrop()) - .transform(new RoundedCorners(16)); // 设置圆角度数 - - Glide.with(context) - .load(wallpaperInfo.getPreview()) - .apply(options) - .into(holder.imageView); - // 根据需要加载其他字段,如图片等 - } - - @Override - public int getItemCount() { - return wallpaperList.size(); - } - - public static class ViewHolder extends RecyclerView.ViewHolder { - - private ImageView imageView; - - public ViewHolder(@NonNull View itemView) { - super(itemView); - imageView = itemView.findViewById(R.id.home_recycler_image); - } - } -} - diff --git a/app/src/main/java/com/key/vibekeyboard/Keyboard/CustomViewConfig.java b/app/src/main/java/com/key/vibekeyboard/Keyboard/CustomViewConfig.java deleted file mode 100644 index fb05adc..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Keyboard/CustomViewConfig.java +++ /dev/null @@ -1,190 +0,0 @@ -package com.key.vibekeyboard.Keyboard; - -import static android.content.Context.MODE_PRIVATE; - -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.BitmapFactory; -import android.graphics.Color; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.util.Log; -import android.util.Xml; - -import androidx.core.content.ContextCompat; - -import com.key.vibekeyboard.AppApplication; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Utils.Mytool; -import com.key.vibekeyboard.Utils.StaticValue; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.Objects; - -public class CustomViewConfig { - private String Bg_action_normal = "btn_keyboard_key_functional_normal.9.png"; - private String jpg_BG = "keyboard_background.jpg"; - private String color_normal_key = "key_text_color_normal"; - private String color_action_key = "key_text_color_functional"; - private String Bg_pressed = "btn_keyboard_key_normal_pressed.9.png"; - private String Bg_normal = "btn_keyboard_key_normal_normal.9.png"; - private String path_drawxh = "/drawable-xhdpi-v4/"; - private String path_drawxxh = "/drawable-xxhdpi-v4/"; - private String path_color = "/colors.xml"; - private String icon_del = "sym_keyboard_delete_normal.png"; - private String icon_shift = "sym_keyboard_shift.png"; - private String Bg_action_pressed = "btn_keyboard_key_functional_pressed.9.png"; - private String icon_shift_lock = "sym_keyboard_shift_locked.png"; - - private String Bg_space_normal = "btn_keyboard_spacekey_normal_normal.9.png"; - private String Bg_space_pressed = "btn_keyboard_spacekey_normal_pressed.9.png"; - - private Drawable BgActionDraw; - private Drawable BgSpaceDraw; - private Drawable BgNormalDraw; - - private Drawable iconShift = ContextCompat.getDrawable(AppApplication.instance, android.R.drawable.stat_sys_upload); - private Drawable iconDel = ContextCompat.getDrawable(AppApplication.instance, android.R.drawable.ic_input_delete); - private Drawable BG = ContextCompat.getDrawable(AppApplication.instance, R.color.black); - - private int keyNoramlcolor = AppApplication.instance.getResources().getColor(R.color.white, null); - - private int keyActioncolor = AppApplication.instance.getResources().getColor(R.color.white, null); - - private Drawable iconShiftLock = ContextCompat.getDrawable(AppApplication.instance, android.R.drawable.stat_sys_upload); - - - public Drawable getBG() { - return BG; - } - - public Drawable getBgActionDraw() { - return BgActionDraw; - } - - public Drawable getBgNormalDraw() { - return BgNormalDraw; - } - - public Drawable getBgSpaceDraw() { - return BgSpaceDraw; - } - - public Drawable getIconDel() { - return iconDel; - } - - public Drawable getIconShift() { - return iconShift; - } - - public Drawable getIconShiftLock() { - return iconShiftLock; - } - - public int getKeyNoramlcolor() { - return keyNoramlcolor; - } - - - public int getKeyActioncolor() { - return keyActioncolor; - } - - public void init() { -// iconShift = ContextCompat.getDrawable(CoolKeyboardSkin.app, R.drawable.ico_shift_lit); -// iconDel = ContextCompat.getDrawable(CoolKeyboardSkin.app, R.drawable.icon_del); -// BG = ContextCompat.getDrawable(CoolKeyboardSkin.app, R.color.white); -// keyNoramlcolor = CoolKeyboardSkin.app.getResources().getColor(R.color.white, null); -// iconShiftLock = ContextCompat.getDrawable(CoolKeyboardSkin.app, R.drawable.ico_shift_lit); -// Drawable drawable1 = ContextCompat.getDrawable(CoolKeyboardSkin.app, R.drawable.de_keybg_press); -// Drawable drawable = ContextCompat.getDrawable(CoolKeyboardSkin.app, R.drawable.de_keybg); -// StateListDrawable status = Mytool.getStatus(drawable, drawable1); -// BgActionDraw = status; -// BgNormalDraw = status; -// BgSpaceDraw = status; - } - - private Drawable getKeyBackGround(Context context, String resDirPath, String drawName) { - String filePath = resDirPath + path_drawxh + drawName; - File file = new File(filePath); - if (!file.exists()) { - return null; - } - BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(filePath)); - Log.d("custom", "filePath" + filePath); - return bitmapDrawable; - } - - private Drawable getBackGround(Context context, String resDirPath) { - String filePath = resDirPath + path_drawxxh + jpg_BG; - if (!new File(filePath).exists()) { - return null; - } - BitmapDrawable bitmapDrawable = new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(filePath)); - return bitmapDrawable; - } - - private void updateKeyColor(String resDirPath) { - - String colorXmlPath = resDirPath + path_color; - File file = new File(colorXmlPath); - if (!file.exists()) { - return; - } - try { - XmlPullParser xmlPullParser = Xml.newPullParser(); - - String s = Mytool.fileToString(file); - xmlPullParser.setInput(new StringReader(s)); - int eventT = xmlPullParser.getEventType(); - while (eventT != XmlPullParser.END_DOCUMENT) { - if (eventT == XmlPullParser.START_TAG && (Objects.equals(xmlPullParser.getName(), "color") || Objects.equals(xmlPullParser.getName(), "item"))) { - String value = xmlPullParser.getAttributeValue(null, "name"); - if (value.equals(color_normal_key)) { - keyNoramlcolor = Color.parseColor(xmlPullParser.nextText()); - - } - if (value.equals(color_action_key)) { - keyActioncolor = Color.parseColor(xmlPullParser.nextText()); - - } - } - eventT = xmlPullParser.next(); - } - } catch (XmlPullParserException exception) { - - } catch (IOException e) { - throw new RuntimeException(e); - } - - - } - - public void updateConfig(Context con) { - String resDirPath = getSavedWallpaperPath(AppApplication.getContext()); - if (!resDirPath.isEmpty()) { - updateKeyColor(resDirPath); - BG = getBackGround(con, resDirPath); - BgNormalDraw = getKeyBackGround(con, resDirPath, Bg_normal); - BgActionDraw = getKeyBackGround(con, resDirPath, Bg_action_normal); - BgSpaceDraw = getKeyBackGround(con, resDirPath, Bg_space_normal); - iconDel = getKeyBackGround(con, resDirPath, icon_del); - iconShift = getKeyBackGround(con, resDirPath, icon_shift); - iconShiftLock = getKeyBackGround(con, resDirPath, icon_shift_lock); - } - } - - public String getSavedWallpaperPath(Context context) { - // 读取 SharedPreferences 中保存的路径 - SharedPreferences sharedPreferences = context.getSharedPreferences("keyboard_prefs", MODE_PRIVATE); - return sharedPreferences.getString("wallpaper_path", ""); // 如果没有保存,返回空字符串 - } - - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Keyboard/KeyboardService.java b/app/src/main/java/com/key/vibekeyboard/Keyboard/KeyboardService.java deleted file mode 100644 index 896d1b7..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Keyboard/KeyboardService.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.key.vibekeyboard.Keyboard; - -import android.content.Context; -import android.inputmethodservice.InputMethodService; -import android.inputmethodservice.KeyboardView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; - -import com.key.vibekeyboard.R; - - -public class KeyboardService extends InputMethodService implements KeyboardView.OnKeyboardActionListener { - private int[] ViewXmls = new int[4]; // 保存不同键盘视图的XML资源ID - private MyKeyboard myKeyboard; // 自定义键盘视图的实例 - - private int curImeAction; // 当前输入法的动作类型 - - public KeyboardService() { - // 默认构造函数 - } - - // 创建输入视图的方法,返回键盘视图 - @Override - public View onCreateInputView() { - // 初始化不同键盘视图的XML布局文件 - ViewXmls[0] = R.xml.view_1; - ViewXmls[1] = R.xml.view_2; - ViewXmls[2] = R.xml.view_3; - ViewXmls[3] = R.xml.view_4; - - // 加载主键盘视图布局文件 - View inputView = LayoutInflater.from(this).inflate(R.layout.keyboard_view, null, false); - myKeyboard = inputView.findViewById(R.id.keyboardView); // 绑定键盘视图 - - setBackground(); - - myKeyboard.setKeyboard(new MyKeyboard.KeyBoard(this, ViewXmls[0])); // 设置默认键盘布局 - myKeyboard.setOnKeyboardActionListener(this); // 设置键盘操作监听器 -// myKeyboard.setPreviewEnabled(false); // 可选项,禁用按键预览 - return inputView; - } - - // 当输入法窗口显示时调用 - @Override - public void onWindowShown() { - super.onWindowShown(); - setBackground(); - } - - private void setBackground(){ - curImeAction = getImeAction(getCurrentInputEditorInfo().imeOptions); // 获取当前的输入法动作类型 - myKeyboard.updateConfigView(this, curImeAction); // 更新键盘配置视图 - myKeyboard.invalidate(); // 刷新键盘视图 - } - - // 获取当前输入法的动作类型 - public int getImeAction(int imeOptions) { - int i = imeOptions & EditorInfo.IME_MASK_ACTION; - return i; - } - - // 键盘按键被按下时调用 - @Override - public void onKey(int primaryCode, int[] keyCodes) { - switch (primaryCode) { - case MyKeyboard.KeyBoard.KEYCODE_SHIFT: - // 切换到大写字母布局或恢复到小写字母布局 - if (myKeyboard.getShiftType() == 0) { - changeView(3); - myKeyboard.setShiftType(1); - } else { - changeView(0); - myKeyboard.setShiftType(0); - } - break; - case MyKeyboard.KeyBoard.KEYCODE_MODE_CHANGE: - // 切换到符号键盘或字母键盘 - if (myKeyboard.getViewType() == 0) { - changeView(1); - } else { - changeView(0); - } - break; - case MyKeyboard.KeyBoard.KEYCODE_SHIFT_123: - // 切换到符号键盘 - changeView(1); - break; - case MyKeyboard.KeyBoard.KEYCODE_SHIFT_MORE: - // 切换到更多符号键盘 - changeView(2); - break; - case MyKeyboard.KeyBoard.KEYCODE_DELETE: - // 删除前一个字符 - getCurrentInputConnection().deleteSurroundingText(1, 0); - break; - case MyKeyboard.KeyBoard.KEYCODE_DONE: - // 完成输入并隐藏键盘 - getCurrentInputConnection().performEditorAction(curImeAction); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(myKeyboard.getWindowToken(), 0); - break; - default: - // 处理普通字符输入 - char value; - if (myKeyboard.getShiftType() == 1) { - value = Character.toUpperCase((char) primaryCode); // 大写字母 - } else { - value = (char) primaryCode; // 小写字母 - } - getCurrentInputConnection().commitText(String.valueOf(value), 1); // 提交字符到输入连接 - } - } - - // 更换键盘视图的方法 - private void changeView(int i) { - myKeyboard.setViewType(i); // 设置键盘视图类型 - myKeyboard.setShiftType(i); // 设置键盘大小写类型 - myKeyboard.setKeyboard(new MyKeyboard.KeyBoard(this, ViewXmls[i])); // 设置新的键盘布局 - } - - // 键被按下时调用 - @Override - public void onPress(int primaryCode) { - - } - - // 键被释放时调用 - @Override - public void onRelease(int primaryCode) { - - } - - - @Override - public void onText(CharSequence text) { - // 文本输入时调用(未实现) - } - - @Override - public void swipeLeft() { - // 左滑时调用(未实现) - } - - @Override - public void swipeRight() { - // 右滑时调用(未实现) - } - - @Override - public void swipeDown() { - // 下滑时调用(未实现) - } - - @Override - public void swipeUp() { - // 上滑时调用(未实现) - } -} diff --git a/app/src/main/java/com/key/vibekeyboard/Keyboard/MyKeyboard.java b/app/src/main/java/com/key/vibekeyboard/Keyboard/MyKeyboard.java deleted file mode 100644 index 60985d6..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Keyboard/MyKeyboard.java +++ /dev/null @@ -1,219 +0,0 @@ -package com.key.vibekeyboard.Keyboard; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -import android.inputmethodservice.Keyboard; -import android.inputmethodservice.KeyboardView; -import android.util.AttributeSet; -import android.view.inputmethod.EditorInfo; - - -import com.key.vibekeyboard.Utils.Mytool; - -import java.util.List; - -public class MyKeyboard extends KeyboardView { - // 自定义键盘视图类,继承自 KeyboardView,用于自定义键盘布局及其行为。 - - private Paint mPaint; - // 用于绘制键盘的 Paint 对象。 - - private int viewType = 0; - // 键盘视图的类型,用于区分不同的键盘视图模式。 - - private int shiftType = 0; - // 当前 Shift 键的状态,0 表示未按下,其他值可能表示按下或锁定状态。 - - private CustomViewConfig config; - // 键盘的自定义配置对象,包含键盘背景、键的颜色和图标等。 - - private int curImeAction; - // 当前输入法的动作类型(如搜索、完成等)。 - - public MyKeyboard(Context context, AttributeSet attrs) { - super(context, attrs); - initView(); - // 初始化视图,配置画笔和其他参数。 - } - - public static class KeyBoard extends Keyboard { - // 自定义键盘类,继承自 Keyboard,用于定义键盘的布局和键值。 - - public static final int KEYCODE_SHIFT_MORE = -360; - public static final int KEYCODE_SHIFT_123 = -361; - // 自定义的键值常量,分别用于切换到更多符号和切换到 123 键盘。 - - public KeyBoard(Context context, int layoutTemplateResId) { - super(context, layoutTemplateResId); - // 使用布局模板资源 ID 初始化键盘对象。 - } - } - - public int getShiftType() { - return shiftType; - // 返回当前 Shift 键的状态。 - } - - public void setShiftType(int shiftType) { - this.shiftType = shiftType; - // 设置 Shift 键的状态。 - } - - public void setViewType(int viewType) { - this.viewType = viewType; - // 设置键盘视图的类型。 - } - - public int getViewType() { - return viewType; - // 返回当前键盘视图的类型。 - } - - @Override - public void onDraw(Canvas canvas) { - // 重写 onDraw 方法,自定义绘制键盘的方式。 - - KeyBoard keyboard = (KeyBoard) getKeyboard(); - // 获取当前键盘对象。 - - List keys = keyboard.getKeys(); - // 获取键盘中的所有键。 - - for (int r = 0; r < keys.size(); r++) { - Keyboard.Key key = keys.get(r); - // 遍历每个键对象。 - - int code = key.codes[0]; - // 获取键的第一个键值代码。 - - mPaint.setColor(config.getKeyActioncolor()); - // 设置画笔的颜色为操作键的颜色。 - - if (code == KeyBoard.KEYCODE_MODE_CHANGE) { - // 如果键是模式切换键,绘制其背景和标签(无文字)。 - - onDrawKeyBackground(key, config.getBgActionDraw(), canvas); - onDrawLabel(key, canvas, ""); - - } else if (code == KeyBoard.KEYCODE_SHIFT) { - // 如果键是 Shift 键,绘制其背景和图标。 - - onDrawKeyBackground(key, config.getBgActionDraw(), canvas); - Mytool.onDrawKeyIcon(key, getShiftDraw(), canvas, this); - - } else if (code == KeyBoard.KEYCODE_SHIFT_123) { - // 如果键是切换到 123 键盘的键,绘制其背景和标签(无文字)。 - - onDrawKeyBackground(key, config.getBgActionDraw(), canvas); - onDrawLabel(key, canvas, ""); - - } else if (code == KeyBoard.KEYCODE_SHIFT_MORE) { - // 如果键是切换到更多符号的键,绘制其背景和标签(无文字)。 - - onDrawKeyBackground(key, config.getBgActionDraw(), canvas); - onDrawLabel(key, canvas, ""); - - } else if (code == KeyBoard.KEYCODE_DONE) { - // 如果键是完成键,根据当前输入法的动作类型绘制其背景和标签。 - - onDrawKeyBackground(key, config.getBgActionDraw(), canvas); - if (curImeAction == EditorInfo.IME_ACTION_SEARCH) { - onDrawLabel(key, canvas, "Search"); - } else { - onDrawLabel(key, canvas, ""); - } - - } else if (code == KeyBoard.KEYCODE_DELETE) { - // 如果键是删除键,绘制其背景、图标和标签(无文字)。 - - onDrawKeyBackground(key, config.getBgActionDraw(), canvas); - Mytool.onDrawKeyIcon(key, config.getIconDel(), canvas, this); - onDrawLabel(key, canvas, ""); - - } else { - // 其他普通键,设置画笔颜色为普通键颜色,绘制其背景和标签。 - - mPaint.setColor(config.getKeyNoramlcolor()); - onDrawKeyBackground(key, config.getBgNormalDraw(), canvas); - onDrawLabel(key, canvas, ""); - } - } - } - - private Drawable getShiftDraw() { - // 根据 Shift 键的状态返回相应的图标。 - - if (shiftType == 0) { - return config.getIconShift(); - } else { - return config.getIconShiftLock(); - } - } - - private void initView() { - // 初始化视图,配置画笔和自定义视图配置对象。 - - config = new CustomViewConfig(); - mPaint = new Paint(); - config.init(); - float texsize = Mytool.spToPpx(20f, this.getContext()); - mPaint.setTextSize(texsize); - setPreviewEnabled(false); - // 禁用键预览。 - } - - public void updateConfigView(Context con, int ime) { - // 更新键盘配置视图,根据上下文和输入法动作类型更新配置。 - - curImeAction = ime; - config.updateConfig(con); - setBackground(config.getBG()); - invalidateAllKeys(); - // 更新键盘背景并刷新所有按键。 - } - - private void onDrawKeyBackground(Keyboard.Key myKey, Drawable keyBG, Canvas canvas) { - // 绘制按键的背景。 - - if (keyBG != null) { - int left = myKey.x + getPaddingLeft(); - int top = myKey.y + getPaddingTop(); - int right = left + myKey.width; - int bottom = top + myKey.height; - - keyBG.setBounds(left, top, right, bottom); - keyBG.setState(myKey.getCurrentDrawableState()); - keyBG.draw(canvas); - // 设置背景的边界并绘制背景。 - } - } - - private void onDrawLabel(Keyboard.Key myKey, Canvas canvas, String custLabel) { - // 绘制按键的标签文字。 - - boolean b = myKey.label == null || myKey.label == ""; - if (!b) { - float y1 = myKey.y + myKey.height / 2f - (mPaint.descent() + mPaint.ascent()) / 2f; - float x1 = myKey.x + getPaddingLeft() + (myKey.width / 2f); - x1 -= mPaint.measureText(myKey.label.toString()) / 2f; - // 计算标签的绘制位置,居中显示。 - - if (!custLabel.isEmpty()) { - // 如果提供了自定义标签,使用自定义标签绘制文字。 - - float texsize = Mytool.spToPpx(14f, this.getContext()); - mPaint.setTextSize(texsize); - canvas.drawText(custLabel, x1, y1, mPaint); - } else { - // 否则使用按键的默认标签绘制文字。 - - float texsize = Mytool.spToPpx(18f, this.getContext()); - mPaint.setTextSize(texsize); - canvas.drawText(myKey.label.toString(), x1, y1, mPaint); - } - } - } -} - diff --git a/app/src/main/java/com/key/vibekeyboard/AppApplication.java b/app/src/main/java/com/key/vibekeyboard/MyApplication.java similarity index 64% rename from app/src/main/java/com/key/vibekeyboard/AppApplication.java rename to app/src/main/java/com/key/vibekeyboard/MyApplication.java index 909d6c0..4b1502c 100644 --- a/app/src/main/java/com/key/vibekeyboard/AppApplication.java +++ b/app/src/main/java/com/key/vibekeyboard/MyApplication.java @@ -6,24 +6,25 @@ import android.util.Log; import com.anythink.core.api.ATSDK; import com.anythink.core.api.NetTrafficeCallback; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.MyDatabase; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.Utils.Mytool; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.data.database.AppDatabase; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.utils.JsonUtils; import com.key.vibekeyboard.topon.AdManager; +import com.key.vibekeyboard.utils.TaskExecutorUtils; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -public class AppApplication extends Application { +public class MyApplication extends Application { - public static AppApplication instance; + public static MyApplication instance; public static List categories; - public static final int DB_Version = 1; - public static final String DB_Name = "image_database"; + public static final int DB_VERSION = 1; + public static final String DB_NAME = "keyboard_database"; public static final String TAG = "--------------"; @@ -35,7 +36,7 @@ public class AppApplication extends Application { public void onCreate() { super.onCreate(); instance = this; - categories = Mytool.parseJsonToList("keyboard.json"); + categories = JsonUtils.parseJson("keyboard.json"); // 确保Firebase初始化 // FirebaseApp.initializeApp(this); @@ -49,12 +50,10 @@ public class AppApplication extends Application { initSdk(); - Mytool.runIO(new Runnable() { + TaskExecutorUtils.executeIO(new Runnable() { @Override public void run() { - - MyDatabase.getInstance().wallpaperInfoDao().insertAll(getAlldataList()); - + AppDatabase.getInstance().wallpaperInfoDao().insertAll(getAlldataList()); } }); @@ -67,10 +66,9 @@ public class AppApplication extends Application { @Override public void onResultCallback(boolean isEU) { Log.e(TAG, "onResultCallback:" + isEU); - if (isEU && ATSDK.getGDPRDataLevel(AppApplication.this) == ATSDK.UNKNOWN) { - ATSDK.showGdprAuth(AppApplication.this); + if (isEU && ATSDK.getGDPRDataLevel(MyApplication.this) == ATSDK.UNKNOWN) { + ATSDK.showGdprAuth(MyApplication.this); } - } @Override @@ -87,10 +85,6 @@ public class AppApplication extends Application { } - public static AppApplication getInstance() { - return instance; - } - public static Context getContext() { return instance.getApplicationContext(); } @@ -100,21 +94,21 @@ public class AppApplication extends Application { } public static List getAlldataList() { - List otherdata = new ArrayList<>(); - List mydataList = getCategories(); + List wallpaperInfos = new ArrayList<>(); + List categoryList = getCategories(); Set set = new HashSet<>(); - for (Category mydata : mydataList) { - List otherdataList = mydata.getList(); - for (WallpaperInfo otherdata1 : otherdataList) { - String title = otherdata1.getTitle(); + for (Category category : categoryList) { + List wallpaperInfoList = category.getList(); + for (WallpaperInfo wallpaperInfo : wallpaperInfoList) { + String title = wallpaperInfo.getTitle(); if (!set.contains(title)) { - otherdata.add(otherdata1); + wallpaperInfos.add(wallpaperInfo); set.add(title); } } } - return otherdata; + return wallpaperInfos; } } diff --git a/app/src/main/java/com/key/vibekeyboard/Room/MyDatabase.java b/app/src/main/java/com/key/vibekeyboard/Room/MyDatabase.java deleted file mode 100644 index 4871635..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Room/MyDatabase.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.key.vibekeyboard.Room; - - -import androidx.room.Database; -import androidx.room.Room; -import androidx.room.RoomDatabase; - -import com.key.vibekeyboard.AppApplication; - -@Database(entities = {WallpaperInfo.class}, version = AppApplication.DB_Version, exportSchema = false) -public abstract class MyDatabase extends RoomDatabase { - - public abstract WallpaperInfoDao wallpaperInfoDao(); - - private static MyDatabase INSTANCE; - - public static MyDatabase getInstance() { - if (INSTANCE == null) { - synchronized (MyDatabase.class) { - INSTANCE = Room.databaseBuilder(AppApplication.getContext(), MyDatabase.class, AppApplication.DB_Name).build(); - } - } - return INSTANCE; - } - - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Room/WallpaperInfoDao.java b/app/src/main/java/com/key/vibekeyboard/Room/WallpaperInfoDao.java deleted file mode 100644 index 42f71d9..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Room/WallpaperInfoDao.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.key.vibekeyboard.Room; - - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.Query; -import androidx.room.Update; - -import java.util.List; - -@Dao -public interface WallpaperInfoDao { - - @Query("select * from wallpaper_info order by RANDOM() LIMIT 1") - WallpaperInfo queryRandomItem(); - - @Insert - void insertAll(List likeDataList); - - @Query("select * from wallpaper_info where preview =:pre ") - List checklikelist(String pre); - - @Update - void update(WallpaperInfo wallpaperInfo); - - @Query("SELECT * FROM wallpaper_info WHERE islike = :islike") - List getlikelist(boolean islike); - @Query("SELECT * FROM wallpaper_info WHERE islike = :islike") - LiveData> getLiveLikeList(boolean islike); - - @Query("SELECT * FROM wallpaper_info WHERE isDownloaded = :isdownload") - List getdownloadlist(boolean isdownload); - -} diff --git a/app/src/main/java/com/key/vibekeyboard/Utils/ItemDecoration.java b/app/src/main/java/com/key/vibekeyboard/Utils/ItemDecoration.java deleted file mode 100644 index 7b365f9..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Utils/ItemDecoration.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.key.vibekeyboard.Utils; - -import android.graphics.Rect; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.StaggeredGridLayoutManager; - -import com.key.vibekeyboard.AppApplication; - - -// ItemDecoration 是一个自定义的 RecyclerView.ItemDecoration 类,用于在 RecyclerView 中为每个子项设置间距。 -public class ItemDecoration extends RecyclerView.ItemDecoration { - - // 垂直间距 (vertical spacing)、水平间距 (horizontal spacing) 和额外间距 (extra spacing):这里设置的是第一个的左边距,其它item根据剩余的距离均匀显示。 - private int v, h, ex; - - // 构造函数,传入 dp 值的垂直、水平和额外间距,并将它们转换为像素值。 - public ItemDecoration(int v, int h, int ex) { - // 将 dp 值转换为像素值并四舍五入 - this.v = Math.round(dpToPx(v)); - this.h = Math.round(dpToPx(h)); - this.ex = Math.round(dpToPx(ex)); - } - - // 重写 getItemOffsets 方法,用于为每个子项设置偏移量(间距)。 - @Override - public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { - super.getItemOffsets(outRect, view, parent, state); - - // 定义网格的列数(spanCount)、子项所占的列数(spanSize)以及子项在网格中的索引(spanIndex) - int spanCount = 1; // 列数默认为 1 - int spanSize = 1; // 子项所占列数默认为 1 - int spanIndex = 0; // 子项在网格中的索引默认为 0 - - // 获取子项在 Adapter 中的位置 - int childAdapterPosition = parent.getChildAdapterPosition(view); - // 获取 RecyclerView 的布局管理器 - RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); - - // 如果布局管理器是 StaggeredGridLayoutManager(交错网格布局管理器) - if (layoutManager instanceof StaggeredGridLayoutManager) { - StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; - StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); - spanCount = staggeredGridLayoutManager.getSpanCount(); // 获取列数 - // 如果子项占据整行(isFullSpan),将 spanSize 设置为列数 - if (layoutParams.isFullSpan()) { - spanSize = spanCount; - } - spanIndex = layoutParams.getSpanIndex(); // 获取子项的索引 - - // 如果布局管理器是 GridLayoutManager(网格布局管理器) - } else if (layoutManager instanceof GridLayoutManager) { - GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager; - GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams(); - spanCount = gridLayoutManager.getSpanCount(); // 获取列数 - spanSize = gridLayoutManager.getSpanSizeLookup().getSpanSize(childAdapterPosition); // 获取子项占据的列数 - spanIndex = layoutParams.getSpanIndex(); // 获取子项的索引 - - // 如果布局管理器是 LinearLayoutManager(线性布局管理器) - } else if (layoutManager instanceof LinearLayoutManager) { - // 设置子项的左、右和底部的间距 - outRect.left = v; - outRect.right = v; - outRect.bottom = h; - } - - // 如果子项占据整行(spanSize == spanCount),设置左、右和底部的间距 - if (spanSize == spanCount) { - outRect.left = v + ex; - outRect.right = v + ex; - outRect.bottom = h; - - // 如果子项不占据整行,根据网格布局计算左右间距 - } else { - // 计算每个子项的总间距(包括额外间距) - int itemAllSpacing = (v * (spanCount + 1) + ex * 2) / spanCount; - // 计算子项的左边距 - int left = v * (spanIndex + 1) - itemAllSpacing * spanIndex + ex; - // 计算子项的右边距 - int right = itemAllSpacing - left; - outRect.left = left; - outRect.right = right; - outRect.bottom = h; - } - } - - // 将 dp 值转换为像素值的方法 - public static float dpToPx(float dpValue) { - // 获取当前设备的屏幕密度(dpi) - float density = AppApplication.getContext().getResources().getDisplayMetrics().density; - // 通过公式 density * dp + 0.5f 将 dp 转换为像素,并返回结果 - return density * dpValue + 0.5f; - } -} diff --git a/app/src/main/java/com/key/vibekeyboard/Utils/Mytool.java b/app/src/main/java/com/key/vibekeyboard/Utils/Mytool.java deleted file mode 100644 index 030f407..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Utils/Mytool.java +++ /dev/null @@ -1,319 +0,0 @@ -package com.key.vibekeyboard.Utils; - -import android.content.Context; -import android.content.res.AssetManager; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.inputmethodservice.Keyboard; -import android.os.Build; -import android.provider.Settings; -import android.util.Log; -import android.util.TypedValue; -import android.view.inputmethod.InputMethodInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.Target; -import com.key.vibekeyboard.AppApplication; -import com.key.vibekeyboard.Keyboard.MyKeyboard; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.callback.DownloadCallback; -import com.key.vibekeyboard.callback.UnzipCallback; - -import net.sf.sevenzipjbinding.ArchiveFormat; -import net.sf.sevenzipjbinding.IInArchive; -import net.sf.sevenzipjbinding.SevenZip; -import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; -import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream; -import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class Mytool { - - // 获取输入法管理服务的实例 - private static final InputMethodManager methodManager = (InputMethodManager) AppApplication.instance.getSystemService(Context.INPUT_METHOD_SERVICE); - // 用于执行异步任务的线程池 - private static ExecutorService executorService; - - public static void onDrawKeyIcon(Keyboard.Key currentKey, - Drawable drawKeyIcon, - Canvas myCanvas, - MyKeyboard myKeyboardView) { - currentKey.icon = drawKeyIcon; - currentKey.icon.setBounds(calculateIconBounds(currentKey, drawKeyIcon, myKeyboardView)); - currentKey.icon.draw(myCanvas); - } - - private static Rect calculateIconBounds(Keyboard.Key currentKey, - Drawable drawKeyIcon, - MyKeyboard myKeyboardView) { - float icon_w = drawKeyIcon.getIntrinsicWidth(); - float icon_h = drawKeyIcon.getIntrinsicHeight(); - float icon_wr = icon_w / currentKey.width; - float icon_hr = icon_h / currentKey.height; - - float tep1, tep2; - if (icon_wr > icon_hr) { - tep2 = icon_wr; - tep1 = Math.max(icon_wr, 0.5f); - } else { - tep2 = icon_hr; - tep1 = Math.max(icon_hr, 0.5f); - } - - icon_h = (icon_h / tep2) * tep1; - icon_w = (icon_w / tep2) * tep1; - - int top = (int) (currentKey.y + myKeyboardView.getPaddingTop() + (currentKey.height - icon_h) / 2); - int left = (int) (currentKey.x + myKeyboardView.getPaddingLeft() + (currentKey.width - icon_w) / 2); - int bottom = top + (int) icon_h; - int right = left + (int) icon_w; - - return new Rect(left, top, right, bottom); - } - - // 从资源文件加载JSON数据 - public static JSONArray loadJSONFromAsset(String filename) { - String json; - try { - AssetManager assetManager = AppApplication.getContext().getAssets(); - InputStream inputStream = assetManager.open(filename); - int size = inputStream.available(); - byte[] buffer = new byte[size]; - inputStream.read(buffer); - inputStream.close(); - json = new String(buffer, StandardCharsets.UTF_8); - return new JSONArray(json); // 转换为JSONArray - } catch (IOException | JSONException e) { - e.printStackTrace(); - return null; - } - } - - // 解析JSON数据为列表 - public static List parseJsonToList(String filename) { - List dataList = new ArrayList<>(); - try { - JSONArray jsonObject = loadJSONFromAsset(filename); - for (int a = 0; a < Objects.requireNonNull(jsonObject).length(); a++) { - JSONObject list = jsonObject.getJSONObject(a); - Category myData = new Category(); - List otherdataList = new ArrayList<>(); - myData.setClassName(list.getString("className")); - JSONArray classArray = list.getJSONArray("list"); - for (int i = 0; i < classArray.length(); i++) { - JSONObject item = classArray.getJSONObject(i); - WallpaperInfo otherdata = new WallpaperInfo(); - otherdata.setDownloaded(false); - otherdata.setIslike(false); - otherdata.setClassName(myData.getClassName()); - otherdata.setPreview(item.getString("preview")); - otherdata.setThumb(item.getString("thumb")); - otherdata.setTitle(item.getString("title")); - otherdata.setZipUrl(item.getString("zipUrl")); - otherdataList.add(otherdata); - } - myData.setList(otherdataList); - dataList.add(myData); - } - } catch (JSONException e) { - e.printStackTrace(); - } - return dataList; - } - - // 检查输入法步骤2(确认输入法是否为当前应用) - public static boolean isStep2() { - String string = Settings.Secure.getString(AppApplication.instance.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); - return string.startsWith(AppApplication.instance.getPackageName()); - } - - // 检查输入法步骤1(确认当前输入法是否被启用) - public static boolean isStep1() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return methodManager.getEnabledInputMethodList().stream() - .anyMatch(inputMethodInfo -> inputMethodInfo.getId().startsWith(AppApplication.instance.getPackageName())); - } else { - InputMethodManager inputMethodManager = (InputMethodManager) AppApplication.instance.getSystemService(Context.INPUT_METHOD_SERVICE); - List inputMethodList = inputMethodManager.getEnabledInputMethodList(); - for (InputMethodInfo inputMethodInfo : inputMethodList) { - if (inputMethodInfo.getId().startsWith(AppApplication.instance.getPackageName())) { - return true; - } - } - return false; - } - } - - // 解压文件的操作 - public static void unZip(Context context, String urlpath, File resource, UnzipCallback callback) throws IOException { - if (!resource.exists()) { // 如果资源文件不存在,显示下载失败的提示 - Toast.makeText(context, context.getString(R.string.app_name), Toast.LENGTH_SHORT).show(); - } else { - String itemFilePath = ""; - - // 使用应用的外部文件目录来存储解压后的文件 - File externalDir = context.getExternalFilesDir(null); - if (externalDir == null) { - externalDir = context.getFilesDir(); // 如果外部存储不可用,则回退到内部存储 - } - - String extractPath = new File(externalDir, "ExtractedFiles").getAbsolutePath(); // 定义一个专门的文件夹存储解压文件 - - RandomAccessFile accessFile = new RandomAccessFile(resource, "r"); - RandomAccessFileInStream inStream = new RandomAccessFileInStream(accessFile); - IInArchive iInArchive = SevenZip.openInArchive(ArchiveFormat.SEVEN_ZIP, inStream); - ISimpleInArchiveItem[] archiveItems = iInArchive.getSimpleInterface().getArchiveItems(); - - // 解压每一个文件 - for (int d = 0; d < archiveItems.length; d++) { - ISimpleInArchiveItem simple = archiveItems[d]; - File file = new File(extractPath, simple.getPath()); // 将解压路径设置为外部存储目录 - if (!simple.isFolder()) { // 如果不是文件夹,解压文件 - RandomAccessFileOutStream outStream = new RandomAccessFileOutStream(new RandomAccessFile(file, "rw")); - simple.extractSlow(outStream); - itemFilePath = file.getPath(); // 记录解压后的文件路径 - Log.d("--------", "path: " + itemFilePath); - } else { - boolean mkdirs = file.mkdirs(); // 创建文件夹 - } - } - - inStream.close(); - iInArchive.close(); - - // 截取资源路径 - int res = itemFilePath.indexOf("res"); - String substring = itemFilePath.substring(0, res + 3); // 截取资源路径 - Log.d("--------", "substring: " + substring); - - callback.onUnzipCall(true, substring); // 调用回调函数 - } - } - - // 下载压缩文件操作 - public static void donwnZip(Context context, String url, DownloadCallback callback) { - // 使用Glide库来下载文件 - Glide.with(context) - .asFile() // 指定下载的资源类型为File - .load(url) // 设置下载的URL - .listener(new RequestListener() { - // 添加监听器来处理下载结果 - @Override - public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target target, boolean isFirstResource) { - // 下载失败时的回调 - try { - callback.onDownloadCall(false, null); // 调用回调方法,传递失败状态 - } catch (FileNotFoundException ex) { - throw new RuntimeException(ex); // 如果捕获到FileNotFoundException异常,抛出运行时异常 - } catch (IOException ex) { - throw new RuntimeException(ex); // 如果捕获到IOException异常,抛出运行时异常 - } - return false; // 表示处理了这个事件 - } - - @Override - public boolean onResourceReady(@NonNull File resource, @NonNull Object model, Target target, @NonNull DataSource dataSource, boolean isFirstResource) { - // 下载成功时的回调 - try { - // 使用外部存储目录或内部存储目录 - File externalDir = context.getExternalFilesDir(null); - if (externalDir == null) { - externalDir = context.getFilesDir(); // 如果外部存储不可用,则回退到内部存储 - } - - // 将下载文件保存到外部存储的特定文件夹 - File downloadDir = new File(externalDir, "DownloadedFiles"); - if (!downloadDir.exists()) { - downloadDir.mkdirs(); // 创建目录 - } - - File destinationFile = new File(downloadDir, resource.getName()); - copyFile(resource, destinationFile); // 使用FileUtils来复制文件 - - callback.onDownloadCall(true, destinationFile); // 调用回调方法,传递成功状态和保存后的文件路径 - Log.d("--------", "resource: " + destinationFile); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); // 如果捕获到FileNotFoundException异常,抛出运行时异常 - } catch (IOException e) { - throw new RuntimeException(e); // 如果捕获到IOException异常,抛出运行时异常 - } - return false; // 表示处理了这个事件 - } - }).preload(); // 预加载文件 - } - - public static void copyFile(File sourceFile, File destinationFile) throws IOException { - try (InputStream in = new FileInputStream(sourceFile); - OutputStream out = new FileOutputStream(destinationFile)) { - byte[] buffer = new byte[1024]; - int bytesRead; - while ((bytesRead = in.read(buffer)) != -1) { - out.write(buffer, 0, bytesRead); - } - } - } - - // 将文件内容转换为字符串 - public static String fileToString(File file) throws IOException { - FileInputStream fileInputStream = new FileInputStream(file); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream)); - StringBuilder stringBuilder = new StringBuilder(); - String lin = ""; - // 逐行读取文件内容 - while ((lin = bufferedReader.readLine()) != null) { - stringBuilder.append(lin); - } - bufferedReader.close(); - String con = stringBuilder.toString(); // 转换为字符串 - return con; - } - - // 将SP单位转换为像素单位 - public static float spToPpx(Float values, Context context) { - return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, values, context.getResources().getDisplayMetrics()); - } - - // 运行IO操作的任务 - public static void runIO(Runnable task) { - getExecutorService().execute(task); - } - - // 获取线程池的实例,如果不存在则创建一个单线程池 - private static ExecutorService getExecutorService() { - if (executorService == null) { - executorService = Executors.newSingleThreadExecutor(); - } - return executorService; - } -} diff --git a/app/src/main/java/com/key/vibekeyboard/Utils/SettingUtil.java b/app/src/main/java/com/key/vibekeyboard/Utils/SettingUtil.java deleted file mode 100644 index 588e68b..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Utils/SettingUtil.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.key.vibekeyboard.Utils; - -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.widget.Toast; - -public class SettingUtil { - public static final String PRIVACY_POLICY_URL = "https://himelody.mystrikingly.com/privacy"; - public static final String TERMS_OF_SERVICE_URL = "https://himelody.mystrikingly.com/terms"; - - // 获取当前应用的版本号 - public static String getCurrentVersion(Context context) { - try { - PackageManager packageManager = context.getPackageManager(); - PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); - return packageInfo.versionName; // 返回版本名称 - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return null; // 返回null表示获取版本号失败 - } - } - - // 发送反馈 - public static void sendFeedback(Context context, String email, String subject) { - Intent emailIntent = new Intent(Intent.ACTION_SEND); - emailIntent.setType("message/rfc822"); - emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{email}); - emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject); - try { - context.startActivity(Intent.createChooser(emailIntent, "Send Feedback")); - } catch (ActivityNotFoundException ex) { - Toast.makeText(context, "There is no app that supports sending emails", Toast.LENGTH_LONG).show(); - } - } - - // 分享应用 - public static void shareApp(Context context) { - String appPackageName = context.getPackageName(); - String appName = context.getApplicationInfo().loadLabel(context.getPackageManager()).toString(); - String appPlayStoreLink = "https://play.google.com/store/apps/details?id=" + appPackageName; - - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("text/plain"); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Check out this app: " + appName); - shareIntent.putExtra(Intent.EXTRA_TEXT, "Download " + appName + " from Google Play: " + appPlayStoreLink); - context.startActivity(Intent.createChooser(shareIntent, "Share " + appName + " via")); - } - - // 打开隐私政策 - public static void openPrivacyPolicy(Context context) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(PRIVACY_POLICY_URL)); - context.startActivity(intent); - } - - // 打开服务条款 - public static void openTermsOfService(Context context) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(TERMS_OF_SERVICE_URL)); - context.startActivity(intent); - } - - // 打开Google Play - public static void openGooglePlay(Context context, String packageName) { - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + packageName)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - context.startActivity(intent); - } catch (ActivityNotFoundException e) { - e.printStackTrace(); - } - } -} diff --git a/app/src/main/java/com/key/vibekeyboard/Utils/StaticValue.java b/app/src/main/java/com/key/vibekeyboard/Utils/StaticValue.java deleted file mode 100644 index 96e0666..0000000 --- a/app/src/main/java/com/key/vibekeyboard/Utils/StaticValue.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.key.vibekeyboard.Utils; - -public class StaticValue { - public static String KEY_NAME = "key_name"; - public static String KEY_URL = "key_url"; - public static String KEY_PRE = "key_pre"; - public static String PATH = ""; - public static String KEY_TEXT = ""; - public static String KEY_ISMAINSH = ""; - public static String KEY_ISshow = ""; -} diff --git a/app/src/main/java/com/key/vibekeyboard/ViewModel/FavoriteViewModel.java b/app/src/main/java/com/key/vibekeyboard/ViewModel/FavoriteViewModel.java deleted file mode 100644 index dcc4b66..0000000 --- a/app/src/main/java/com/key/vibekeyboard/ViewModel/FavoriteViewModel.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.key.vibekeyboard.ViewModel; - -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; - -import com.key.vibekeyboard.Room.MyDatabase; -import com.key.vibekeyboard.Room.WallpaperInfo; - -import java.util.List; - -public class FavoriteViewModel extends ViewModel { - private final LiveData> favoriteList; - private final MyDatabase database; - - public FavoriteViewModel() { - // 获取数据库实例 - database = MyDatabase.getInstance(); - // 通过 LiveData 监听数据库中的喜欢列表变化 - favoriteList = database.wallpaperInfoDao().getLiveLikeList(true); - } - - // 提供一个获取喜欢列表 LiveData 的方法 - public LiveData> getFavoriteList() { - return favoriteList; - } -} diff --git a/app/src/main/java/com/key/vibekeyboard/callback/RecommendDialogCallback.java b/app/src/main/java/com/key/vibekeyboard/callback/RecommendDialogCallback.java deleted file mode 100644 index c6da1cb..0000000 --- a/app/src/main/java/com/key/vibekeyboard/callback/RecommendDialogCallback.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.key.vibekeyboard.callback; - -public interface RecommendDialogCallback { - - void onTryNow(); -} diff --git a/app/src/main/java/com/key/vibekeyboard/callback/StepDialogCallback.java b/app/src/main/java/com/key/vibekeyboard/callback/StepDialogCallback.java deleted file mode 100644 index 922af42..0000000 --- a/app/src/main/java/com/key/vibekeyboard/callback/StepDialogCallback.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.key.vibekeyboard.callback; - -public interface StepDialogCallback { - - void onDisMiss(); -} diff --git a/app/src/main/java/com/key/vibekeyboard/Room/Category.java b/app/src/main/java/com/key/vibekeyboard/data/bean/Category.java similarity index 82% rename from app/src/main/java/com/key/vibekeyboard/Room/Category.java rename to app/src/main/java/com/key/vibekeyboard/data/bean/Category.java index 7c1db6a..7e4a5e2 100644 --- a/app/src/main/java/com/key/vibekeyboard/Room/Category.java +++ b/app/src/main/java/com/key/vibekeyboard/data/bean/Category.java @@ -1,4 +1,6 @@ -package com.key.vibekeyboard.Room; +package com.key.vibekeyboard.data.bean; + +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; import java.util.ArrayList; import java.util.List; diff --git a/app/src/main/java/com/key/vibekeyboard/data/database/AppDatabase.java b/app/src/main/java/com/key/vibekeyboard/data/database/AppDatabase.java new file mode 100644 index 0000000..838b28c --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/data/database/AppDatabase.java @@ -0,0 +1,29 @@ +package com.key.vibekeyboard.data.database; + + +import androidx.room.Database; +import androidx.room.Room; +import androidx.room.RoomDatabase; + +import com.key.vibekeyboard.MyApplication; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.data.database.dao.WallpaperInfoDao; + +@Database(entities = {WallpaperInfo.class}, version = MyApplication.DB_VERSION, exportSchema = false) +public abstract class AppDatabase extends RoomDatabase { + + public abstract WallpaperInfoDao wallpaperInfoDao(); + + private static AppDatabase INSTANCE; + + public static AppDatabase getInstance() { + if (INSTANCE == null) { + synchronized (AppDatabase.class) { + INSTANCE = Room.databaseBuilder(MyApplication.getContext(), AppDatabase.class, MyApplication.DB_NAME).build(); + } + } + return INSTANCE; + } + + +} diff --git a/app/src/main/java/com/key/vibekeyboard/data/database/dao/WallpaperInfoDao.java b/app/src/main/java/com/key/vibekeyboard/data/database/dao/WallpaperInfoDao.java new file mode 100644 index 0000000..1c1648c --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/data/database/dao/WallpaperInfoDao.java @@ -0,0 +1,30 @@ +package com.key.vibekeyboard.data.database.dao; + + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.Query; +import androidx.room.Update; + +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; + +import java.util.List; + +@Dao +public interface WallpaperInfoDao { + + @Insert + void insertAll(List likeDataList); + + @Query("select * from wallpaper_info where preview =:pre ") + List checklikelist(String pre); + + @Update + void update(WallpaperInfo wallpaperInfo); + + @Query("SELECT * FROM wallpaper_info WHERE islike = :dislike") + LiveData> getLiveLikeList(boolean dislike); + + +} diff --git a/app/src/main/java/com/key/vibekeyboard/Room/WallpaperInfo.java b/app/src/main/java/com/key/vibekeyboard/data/database/entity/WallpaperInfo.java similarity index 98% rename from app/src/main/java/com/key/vibekeyboard/Room/WallpaperInfo.java rename to app/src/main/java/com/key/vibekeyboard/data/database/entity/WallpaperInfo.java index e74ebee..234e1e5 100644 --- a/app/src/main/java/com/key/vibekeyboard/Room/WallpaperInfo.java +++ b/app/src/main/java/com/key/vibekeyboard/data/database/entity/WallpaperInfo.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Room; +package com.key.vibekeyboard.data.database.entity; import android.os.Parcel; import android.os.Parcelable; diff --git a/app/src/main/java/com/key/vibekeyboard/inputmethod/service/MyInputMethodService.java b/app/src/main/java/com/key/vibekeyboard/inputmethod/service/MyInputMethodService.java new file mode 100644 index 0000000..6a0f61a --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/inputmethod/service/MyInputMethodService.java @@ -0,0 +1,170 @@ +package com.key.vibekeyboard.inputmethod.service; + +import android.inputmethodservice.InputMethodService; +import android.inputmethodservice.Keyboard; +import android.inputmethodservice.KeyboardView; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; + +import com.key.vibekeyboard.R; +import com.key.vibekeyboard.inputmethod.view.CustomKeyboardView; + +public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener { + + private Keyboard keyboardLowercase; + private Keyboard keyboardUppercase; + private Keyboard keyboardSymbols; + private Keyboard keyboardMoreSymbols; + private Keyboard currentKeyboard; + + private CustomKeyboardView customKeyboardView; + + private static final int KEYCODE_MORE_SYMBOLS = -1000; + + @Override + public View onCreateInputView() { + customKeyboardView = (CustomKeyboardView) getLayoutInflater().inflate(R.layout.custom_keyboard_view, null, false); + + initializeKeyboards(); + setUpCustomKeyboardView(); + + return customKeyboardView; + } + + private void initializeKeyboards() { + keyboardLowercase = new Keyboard(this, R.xml.keyboard_lowercase); + keyboardUppercase = new Keyboard(this, R.xml.keyboard_uppercase); + keyboardSymbols = new Keyboard(this, R.xml.keyboard_symbols); + keyboardMoreSymbols = new Keyboard(this, R.xml.keyboard_more_symbols); + + currentKeyboard = keyboardLowercase; + } + + private void setUpCustomKeyboardView() { + customKeyboardView.setKeyboard(currentKeyboard); + customKeyboardView.setOnKeyboardActionListener(this); + } + + @Override + public void onWindowShown() { + super.onWindowShown(); + updateKeyboardBackground(); // 更新背景 + } + + @Override + public void onKey(int primaryCode, int[] keyCodes) { + InputConnection inputConnection = getCurrentInputConnection(); + if (inputConnection == null) return; + + switch (primaryCode) { + case Keyboard.KEYCODE_DELETE: + handleDelete(inputConnection); + break; + + case Keyboard.KEYCODE_SHIFT: + toggleCaseMode(); + break; + + case Keyboard.KEYCODE_MODE_CHANGE: + toggleKeyboardLayout(); + break; + + case Keyboard.KEYCODE_DONE: + performActionBasedOnEditorInfo(inputConnection); + break; + + case KEYCODE_MORE_SYMBOLS: + toggleMoreSymbolsKeyboard(); + break; + + default: + handleCharacterInput(primaryCode, inputConnection); + break; + } + } + + private void handleDelete(InputConnection inputConnection) { + inputConnection.deleteSurroundingText(1, 0); + } + + private void toggleCaseMode() { + if (currentKeyboard == keyboardLowercase) { + switchToNewKeyboard(keyboardUppercase); + customKeyboardView.setShiftState(CustomKeyboardView.ShiftState.CAPS); + } else { + switchToNewKeyboard(keyboardLowercase); + customKeyboardView.setShiftState(CustomKeyboardView.ShiftState.NORMAL); + } + } + + private void toggleKeyboardLayout() { + if (currentKeyboard == keyboardLowercase || currentKeyboard == keyboardUppercase) { + switchToNewKeyboard(keyboardSymbols); + } else if (currentKeyboard == keyboardSymbols || currentKeyboard == keyboardMoreSymbols) { + switchToNewKeyboard(keyboardLowercase); + } + } + + private void switchToNewKeyboard(Keyboard newKeyboard) { + if (currentKeyboard != newKeyboard) { + currentKeyboard = newKeyboard; + customKeyboardView.setKeyboard(currentKeyboard); + updateKeyboardBackground(); + } + } + + private void performActionBasedOnEditorInfo(InputConnection inputConnection) { + EditorInfo editorInfo = getCurrentInputEditorInfo(); + if ((editorInfo.imeOptions & EditorInfo.IME_ACTION_SEARCH) != 0) { + inputConnection.performEditorAction(EditorInfo.IME_ACTION_SEARCH); + } else if ((editorInfo.imeOptions & EditorInfo.IME_ACTION_DONE) != 0) { + inputConnection.performEditorAction(EditorInfo.IME_ACTION_DONE); + } else { + inputConnection.performEditorAction(EditorInfo.IME_ACTION_UNSPECIFIED); + } + } + + private void toggleMoreSymbolsKeyboard() { + switchToNewKeyboard(currentKeyboard == keyboardSymbols ? keyboardMoreSymbols : keyboardSymbols); + } + + private void handleCharacterInput(int primaryCode, InputConnection inputConnection) { + char code = (char) primaryCode; + inputConnection.commitText(String.valueOf(code), 1); + } + + private void updateKeyboardBackground() { + customKeyboardView.updateKeyboardView(this); + customKeyboardView.invalidate(); + } + + @Override + public void onPress(int primaryCode) { + } + + @Override + public void onRelease(int primaryCode) { + } + + @Override + public void onText(CharSequence text) { + } + + @Override + public void swipeLeft() { + } + + @Override + public void swipeRight() { + } + + @Override + public void swipeDown() { + } + + @Override + public void swipeUp() { + } +} + diff --git a/app/src/main/java/com/key/vibekeyboard/inputmethod/theme/KeyboardThemeManager.java b/app/src/main/java/com/key/vibekeyboard/inputmethod/theme/KeyboardThemeManager.java new file mode 100644 index 0000000..c13e039 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/inputmethod/theme/KeyboardThemeManager.java @@ -0,0 +1,172 @@ +package com.key.vibekeyboard.inputmethod.theme; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.util.Xml; + +import androidx.core.content.ContextCompat; + +import com.key.vibekeyboard.R; +import com.key.vibekeyboard.utils.FileUtils; +import com.key.vibekeyboard.utils.PathRepository; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.File; +import java.io.IOException; +import java.io.StringReader; + +public class KeyboardThemeManager { + + private Drawable actionBackgroundDrawable; + private Drawable normalBackgroundDrawable; + private Drawable shiftIconDrawable; + private Drawable shiftLockIconDrawable; + private Drawable deleteIconDrawable; + private Drawable returnIconDrawable; + private Drawable backgroundDrawable; + + private int normalKeyColor; + private int actionKeyColor; + + private static final String COLOR_NORMAL_KEY_TEXT = "key_text_color_normal"; + private static final String COLOR_ACTION_KEY_TEXT = "key_text_color_functional"; + + private static final int DEFAULT_SHIFT_ICON = android.R.drawable.stat_sys_upload; + private static final int DEFAULT_SHIFT_LOCK_ICON = android.R.drawable.stat_sys_upload; + private static final int DEFAULT_DELETE_ICON = android.R.drawable.ic_input_delete; + private static final int DEFAULT_RETURN_ICON = android.R.drawable.screen_background_light_transparent; + private static final int DEFAULT_BACKGROUND_COLOR = R.color.black; + + public KeyboardThemeManager(Context context) { + shiftIconDrawable = ContextCompat.getDrawable(context, DEFAULT_SHIFT_ICON); + shiftLockIconDrawable = ContextCompat.getDrawable(context, DEFAULT_SHIFT_LOCK_ICON); + deleteIconDrawable = ContextCompat.getDrawable(context, DEFAULT_DELETE_ICON); + returnIconDrawable = ContextCompat.getDrawable(context, DEFAULT_RETURN_ICON); + backgroundDrawable = ContextCompat.getDrawable(context, DEFAULT_BACKGROUND_COLOR); + normalKeyColor = ContextCompat.getColor(context, R.color.white); + actionKeyColor = normalKeyColor; + } + + public Drawable getBackgroundDrawable() { + return backgroundDrawable; + } + + public Drawable getActionBackgroundDrawable() { + return actionBackgroundDrawable; + } + + public Drawable getNormalBackgroundDrawable() { + return normalBackgroundDrawable; + } + + public Drawable getDeleteIconDrawable() { + return deleteIconDrawable; + } + + public Drawable getShiftIconDrawable() { + return shiftIconDrawable; + } + + public Drawable getReturnIconDrawable() { + return returnIconDrawable; + } + + public Drawable getShiftLockIconDrawable() { + return shiftLockIconDrawable; + } + + public int getNormalKeyColor() { + return normalKeyColor; + } + + public int getActionKeyColor() { + return actionKeyColor; + } + + public void updateBackground(Context con) { + String resDirPath = getWallpaperPath(con); + if (!resDirPath.isEmpty()) { + updateKeyColors(resDirPath); + backgroundDrawable = getKeyboardBackground(con, resDirPath); + returnIconDrawable = getDrawableForKeyBackground(con, resDirPath, PathRepository.RETURN_ICON); + normalBackgroundDrawable = getDrawableForKeyBackground(con, resDirPath, PathRepository.NORMAL_KEY_BACKGROUND); + actionBackgroundDrawable = getDrawableForKeyBackground(con, resDirPath, PathRepository.ACTION_KEY_BACKGROUND); + deleteIconDrawable = getDrawableForKeyBackground(con, resDirPath, PathRepository.DELETE_ICON); + shiftIconDrawable = getDrawableForKeyBackground(con, resDirPath, PathRepository.SHIFT_ICON); + shiftLockIconDrawable = getDrawableForKeyBackground(con, resDirPath, PathRepository.SHIFT_LOCK_ICON); + } + } + + private Drawable getKeyboardBackground(Context context, String resourceDirectoryPath) { + String filePath = resourceDirectoryPath + "/drawable-xxhdpi-v4/keyboard_background.jpg"; + return loadDrawableFromFile(context, filePath); + } + + private Drawable getDrawableForKeyBackground(Context context, String resourceDirectoryPath, String drawableName) { + String drawablePath = "/drawable-xhdpi-v4/" + drawableName; + return loadDrawableFromFile(context, resourceDirectoryPath + drawablePath); + } + + private void updateKeyColors(String resDirPath) { + String colorXmlPath = resDirPath + "/colors.xml"; + File colorXmlFile = new File(colorXmlPath); + + if (!colorXmlFile.exists()) { + Log.w("updateKeyColors", "File not found: " + colorXmlPath); + return; + } + + try { + XmlPullParser parser = Xml.newPullParser(); + String fileContent = FileUtils.readFileAsString(colorXmlFile); + parser.setInput(new StringReader(fileContent)); + + int eventType = parser.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + String tagName = parser.getName(); + if ("color".equals(tagName) || "item".equals(tagName)) { + String attributeName = parser.getAttributeValue(null, "name"); + String colorValue = parser.nextText(); + if (colorValue != null && !colorValue.trim().isEmpty()) { + if (COLOR_NORMAL_KEY_TEXT.equals(attributeName)) { + normalKeyColor = Color.parseColor(colorValue); + } else if (COLOR_ACTION_KEY_TEXT.equals(attributeName)) { + actionKeyColor = Color.parseColor(colorValue); + } + } else { + Log.w("updateKeyColors", "Invalid color value for: " + attributeName); + } + } + } + eventType = parser.next(); + } + } catch (XmlPullParserException | IOException e) { + Log.e("updateKeyColors", "Error parsing colors XML", e); + } + } + + private Drawable loadDrawableFromFile(Context context, String filePath) { + File file = new File(filePath); + if (file.exists()) { + return new BitmapDrawable(context.getResources(), BitmapFactory.decodeFile(filePath)); + } + return null; + } + + private String getWallpaperPath(Context context) { + SharedPreferences prefs = context.getSharedPreferences("keyboard_info", Context.MODE_PRIVATE); + String path = prefs.getString("wallpaper_path", ""); + if (path.isEmpty()) { + Log.w("KeyboardThemeManager", "Wallpaper path is empty."); + } + return path; + } +} diff --git a/app/src/main/java/com/key/vibekeyboard/inputmethod/view/CustomKeyboardView.java b/app/src/main/java/com/key/vibekeyboard/inputmethod/view/CustomKeyboardView.java new file mode 100644 index 0000000..e3c540f --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/inputmethod/view/CustomKeyboardView.java @@ -0,0 +1,137 @@ +package com.key.vibekeyboard.inputmethod.view; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.inputmethodservice.Keyboard; +import android.inputmethodservice.KeyboardView; +import android.util.AttributeSet; + +import com.key.vibekeyboard.inputmethod.theme.KeyboardThemeManager; +import com.key.vibekeyboard.utils.DrawableUtils; + +import java.util.List; + +public class CustomKeyboardView extends KeyboardView { + + private final Paint mPaint; + private final KeyboardThemeManager keyboardThemeManager; + private ShiftState shiftState = ShiftState.NORMAL; + + private static final float TEXT_SIZE_NORMAL = 18f; + private static final float TEXT_SIZE_LARGE = 20f; + + public CustomKeyboardView(Context context, AttributeSet attrs) { + super(context, attrs); + keyboardThemeManager = new KeyboardThemeManager(context); + mPaint = new Paint(); + mPaint.setTextSize(DrawableUtils.spToPx(TEXT_SIZE_LARGE, context)); + setPreviewEnabled(false); + } + + @Override + public void onDraw(Canvas canvas) { + List keys = getKeyboard().getKeys(); + + for (Keyboard.Key key : keys) { + int keyCode = key.codes[0]; + setPaintColor(keyCode); + + Drawable keyBackground = getKeyBackgroundDrawable(keyCode); + if (keyBackground != null) { + drawKeyBackground(key, keyBackground, canvas); + } + + switch (keyCode) { + case Keyboard.KEYCODE_SHIFT: + DrawableUtils.drawKeyIcon(key, getShiftDrawable(), canvas, this); + break; + + case Keyboard.KEYCODE_DELETE: + DrawableUtils.drawKeyIcon(key, keyboardThemeManager.getDeleteIconDrawable(), canvas, this); + drawKeyLabel(key, canvas); + break; + + case Keyboard.KEYCODE_DONE: + DrawableUtils.drawKeyIcon(key, keyboardThemeManager.getReturnIconDrawable(), canvas, this); + break; + + default: + drawKeyLabel(key, canvas); + break; + } + } + + } + + private void setPaintColor(int keyCode) { + if (isActionKey(keyCode)) { + mPaint.setColor(keyboardThemeManager.getActionKeyColor()); + } else { + mPaint.setColor(keyboardThemeManager.getNormalKeyColor()); + } + } + + private boolean isActionKey(int keyCode) { + return keyCode == Keyboard.KEYCODE_SHIFT || keyCode == Keyboard.KEYCODE_DELETE || + keyCode == Keyboard.KEYCODE_MODE_CHANGE || keyCode == Keyboard.KEYCODE_DONE + || keyCode == -1000 || keyCode == 32; + } + + private Drawable getKeyBackgroundDrawable(int keyCode) { + if (isActionKey(keyCode)) { + return keyboardThemeManager.getActionBackgroundDrawable(); + } else { + return keyboardThemeManager.getNormalBackgroundDrawable(); + } + } + + private Drawable getShiftDrawable() { + if (shiftState == ShiftState.NORMAL) { + return keyboardThemeManager.getShiftIconDrawable(); + } else if (shiftState == ShiftState.CAPS) { + return keyboardThemeManager.getShiftLockIconDrawable(); + } + return null; + } + + private void drawKeyBackground(Keyboard.Key key, Drawable keyBackground, Canvas canvas) { + if (keyBackground != null) { + int left = key.x + getPaddingLeft(); + int top = key.y + getPaddingTop(); + int right = left + key.width; + int bottom = top + key.height; + + keyBackground.setBounds(left, top, right, bottom); + keyBackground.setState(key.getCurrentDrawableState()); + keyBackground.draw(canvas); + } + } + + private void drawKeyLabel(Keyboard.Key key, Canvas canvas) { + if (key.label != null && !key.label.toString().isEmpty()) { + float xPos = key.x + getPaddingLeft() + (key.width / 2f); + float yPos = key.y + key.height / 2f - (mPaint.descent() + mPaint.ascent()) / 2f; + xPos -= mPaint.measureText(key.label.toString()) / 2f; + + mPaint.setTextSize(DrawableUtils.spToPx(TEXT_SIZE_NORMAL, this.getContext())); + canvas.drawText(key.label.toString(), xPos, yPos, mPaint); + } + } + + public void updateKeyboardView(Context context) { + keyboardThemeManager.updateBackground(context); + setBackground(keyboardThemeManager.getBackgroundDrawable()); + invalidateAllKeys(); + } + + public enum ShiftState { + NORMAL, CAPS + } + + public void setShiftState(ShiftState state) { + this.shiftState = state; + } +} + diff --git a/app/src/main/java/com/key/vibekeyboard/topon/AdManager.java b/app/src/main/java/com/key/vibekeyboard/topon/AdManager.java index 3fc2a2f..c9b2865 100644 --- a/app/src/main/java/com/key/vibekeyboard/topon/AdManager.java +++ b/app/src/main/java/com/key/vibekeyboard/topon/AdManager.java @@ -10,7 +10,7 @@ import com.anythink.core.api.ATAdInfo; import com.anythink.core.api.AdError; import com.anythink.interstitial.api.ATInterstitial; import com.anythink.interstitial.api.ATInterstitialListener; -import com.key.vibekeyboard.AppApplication; +import com.key.vibekeyboard.MyApplication; import java.util.ArrayList; import java.util.Collections; @@ -44,14 +44,14 @@ public class AdManager { private static boolean alreadyShow = false; - private static List list = new ArrayList<>(); + private static final List list = new ArrayList<>(); public static void loadAllAd() { if (list.isEmpty()) { - ATInterstitial mInterstitialAd1 = new ATInterstitial(AppApplication.getContext(), place1Id); - ATInterstitial mInterstitialAd2 = new ATInterstitial(AppApplication.getContext(), place2Id); - ATInterstitial mInterstitialAd3 = new ATInterstitial(AppApplication.getContext(), place3Id); + ATInterstitial mInterstitialAd1 = new ATInterstitial(MyApplication.getContext(), place1Id); + ATInterstitial mInterstitialAd2 = new ATInterstitial(MyApplication.getContext(), place2Id); + ATInterstitial mInterstitialAd3 = new ATInterstitial(MyApplication.getContext(), place3Id); list.add(mInterstitialAd1); list.add(mInterstitialAd2); list.add(mInterstitialAd3); @@ -97,11 +97,11 @@ public class AdManager { Collections.shuffle(list); for (ATInterstitial ad : list) { if (ad.isAdReady()) { - Log.d(AppApplication.TAG, "-has Cache------------"); + Log.d(MyApplication.TAG, "-has Cache------------"); return ad; } } - Log.d(AppApplication.TAG, "-No Cache------------"); + Log.d(MyApplication.TAG, "-No Cache------------"); return null; } @@ -111,13 +111,13 @@ public class AdManager { @Override public void onInterstitialAdLoaded() { - Log.d(AppApplication.TAG, "LoadLoaded " + ad.mPlacementId); + Log.d(MyApplication.TAG, "LoadLoaded " + ad.mPlacementId); } @Override public void onInterstitialAdLoadFail(AdError adError) { listener.loadFail(ad.mPlacementId); - Log.d(AppApplication.TAG, "LoadFail:--" + ad.mPlacementId + "--" + adError.getCode() + "---" + adError.getDesc()); + Log.d(MyApplication.TAG, "LoadFail:--" + ad.mPlacementId + "--" + adError.getCode() + "---" + adError.getDesc()); } @Override @@ -127,7 +127,7 @@ public class AdManager { @Override public void onInterstitialAdShow(ATAdInfo atAdInfo) { - Log.d(AppApplication.TAG, "AdShow " + atAdInfo.getShowId()); + Log.d(MyApplication.TAG, "AdShow " + atAdInfo.getShowId()); listener.showSuccess(); ad.load(); } diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/CategoryActivity.java b/app/src/main/java/com/key/vibekeyboard/ui/activity/CategoryActivity.java similarity index 82% rename from app/src/main/java/com/key/vibekeyboard/Activity/CategoryActivity.java rename to app/src/main/java/com/key/vibekeyboard/ui/activity/CategoryActivity.java index 589e42e..02b7316 100644 --- a/app/src/main/java/com/key/vibekeyboard/Activity/CategoryActivity.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/activity/CategoryActivity.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Activity; +package com.key.vibekeyboard.ui.activity; import android.content.Intent; import android.os.Bundle; @@ -6,32 +6,42 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; +import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; -import com.key.vibekeyboard.Adapter.CategoryViewPager2Adapter; +import com.key.vibekeyboard.ui.adapter.CategoryViewPager2Adapter; import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Utils.Mytool; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.utils.JsonUtils; import com.key.vibekeyboard.databinding.ActivityCategoryBinding; import java.util.List; public class CategoryActivity extends AppCompatActivity { - private final List categories = Mytool.parseJsonToList("keyboard.json"); + private final List categories = JsonUtils.parseJson("keyboard.json"); private ActivityCategoryBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - binding = ActivityCategoryBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + EdgeToEdge.enable(this); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + initData(); initEvent(); @@ -43,29 +53,24 @@ public class CategoryActivity extends AppCompatActivity { CategoryViewPager2Adapter adapter = new CategoryViewPager2Adapter(this, categories); binding.categoryViewPager.setAdapter(adapter); - new TabLayoutMediator(binding.categoryTab, binding.categoryViewPager, (tab, position) -> { - // 设置自定义视图 View customView = LayoutInflater.from(this).inflate(R.layout.category_tab_custom, null); tab.setCustomView(customView); - // 设置标题文字 TextView textView = customView.findViewById(R.id.category_tab_custom_title); Category category = categories.get(position); String dir = category.getClassName(); String text = dir.substring(dir.lastIndexOf("_") + 1); - text = text.substring(0, 1).toUpperCase() + text.substring(1); // 首字母大写 + text = text.substring(0, 1).toUpperCase() + text.substring(1); textView.setText(text); }).attach(); -// 添加 TabLayout 选中状态监听器 binding.categoryTab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { - // 当 Tab 选中时,将文字设置为红色 View customView = tab.getCustomView(); if (customView != null) { TextView textView = customView.findViewById(R.id.category_tab_custom_title); @@ -75,7 +80,6 @@ public class CategoryActivity extends AppCompatActivity { @Override public void onTabUnselected(TabLayout.Tab tab) { - // 当 Tab 取消选中时,恢复默认颜色 View customView = tab.getCustomView(); if (customView != null) { TextView textView = customView.findViewById(R.id.category_tab_custom_title); @@ -85,14 +89,12 @@ public class CategoryActivity extends AppCompatActivity { @Override public void onTabReselected(TabLayout.Tab tab) { - // 可选择性处理重复选中的情况 } }); - // 设置第一个 Tab 默认选中并改变颜色 TabLayout.Tab firstTab = binding.categoryTab.getTabAt(0); if (firstTab != null) { - firstTab.select(); // 手动选中第一个 Tab + firstTab.select(); View customView = firstTab.getCustomView(); if (customView != null) { TextView textView = customView.findViewById(R.id.category_tab_custom_title); @@ -118,7 +120,6 @@ public class CategoryActivity extends AppCompatActivity { startActivity(intent); } }); - } @Override diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/DownloadActivity.java b/app/src/main/java/com/key/vibekeyboard/ui/activity/DownloadActivity.java similarity index 70% rename from app/src/main/java/com/key/vibekeyboard/Activity/DownloadActivity.java rename to app/src/main/java/com/key/vibekeyboard/ui/activity/DownloadActivity.java index c09978a..7a75caa 100644 --- a/app/src/main/java/com/key/vibekeyboard/Activity/DownloadActivity.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/activity/DownloadActivity.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Activity; +package com.key.vibekeyboard.ui.activity; import android.content.Intent; import android.content.SharedPreferences; @@ -8,25 +8,30 @@ import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; +import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.GridLayoutManager; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Adapter.DownlaodRecyclerViewAdapter; -import com.key.vibekeyboard.Dialog.PermissionRequestDialog; +import com.key.vibekeyboard.data.database.AppDatabase; +import com.key.vibekeyboard.ui.adapter.WallpaperAdapter; +import com.key.vibekeyboard.ui.dialog.PermissionRequestDialog; import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.MyDatabase; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.Utils.ItemDecoration; -import com.key.vibekeyboard.Utils.Mytool; -import com.key.vibekeyboard.Utils.StaticValue; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.utils.DownloadUtils; +import com.key.vibekeyboard.utils.InputMethodUtils; +import com.key.vibekeyboard.utils.ItemDecoration; import com.key.vibekeyboard.databinding.ActivityDownloadBinding; import com.key.vibekeyboard.topon.AdManager; import com.key.vibekeyboard.topon.onActionListener; -import com.vungle.ads.Ad; +import com.key.vibekeyboard.utils.TaskExecutorUtils; +import com.key.vibekeyboard.utils.unzipUtils; import java.util.ArrayList; import java.util.List; @@ -36,10 +41,9 @@ public class DownloadActivity extends AppCompatActivity { private ActivityDownloadBinding binding; private String preview; private String url; - private String unzipPath; - private WallpaperInfo otherdata; - private Boolean islike = false; - private Boolean tempIsLike = false; // 用来暂存状态 + private WallpaperInfo userdata; + private Boolean dislike = false; + private Boolean tempIsLike = false; @Override @@ -49,6 +53,13 @@ public class DownloadActivity extends AppCompatActivity { binding = ActivityDownloadBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + EdgeToEdge.enable(this); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + AdManager.loadAllAd(); AdManager.showTopOn(this, new onActionListener() { @@ -65,10 +76,10 @@ public class DownloadActivity extends AppCompatActivity { @Override protected void onDestroy() { super.onDestroy(); - if (otherdata != null && tempIsLike != null && tempIsLike != islike) { - otherdata.setIslike(tempIsLike); - Mytool.runIO(() -> { - MyDatabase.getInstance().wallpaperInfoDao().update(otherdata); + if (userdata != null && tempIsLike != null && tempIsLike != dislike) { + userdata.setIslike(tempIsLike); + TaskExecutorUtils.executeIO(() -> { + AppDatabase.getInstance().wallpaperInfoDao().update(userdata); }); } binding = null; @@ -86,37 +97,27 @@ public class DownloadActivity extends AppCompatActivity { } preview = wallpaperInfo.getPreview(); - String name = wallpaperInfo.getTitle(); url = wallpaperInfo.getZipUrl(); Log.d("DownloadActivity", "wallpaperInfo: " + wallpaperInfo); binding.downloadTitle.setText(wallpaperInfo.title); - DownlaodRecyclerViewAdapter adapter = new DownlaodRecyclerViewAdapter(this, wallpaperInfo, list); + WallpaperAdapter adapter = new WallpaperAdapter(this, list); binding.downloadRecycler.setAdapter(adapter); binding.downloadRecycler.setLayoutManager(new GridLayoutManager(this, 2)); binding.downloadRecycler.addItemDecoration(new ItemDecoration(16, 19, 10)); - Mytool.runIO(() -> { - List existingData = MyDatabase.getInstance().wallpaperInfoDao().checklikelist(preview); + TaskExecutorUtils.executeIO(() -> { + List existingData = AppDatabase.getInstance().wallpaperInfoDao().checklikelist(preview); if (!existingData.isEmpty()) { - otherdata = existingData.get(0); - islike = otherdata.getIslike(); - tempIsLike = islike; // Store the initial islike value - - String path = StaticValue.PATH; - - if (path.equals(otherdata.getPath())) { - runOnUiThread(() -> { - // Update UI if needed - }); - } + userdata = existingData.get(0); + dislike = userdata.getIslike(); + tempIsLike = dislike; runOnUiThread(() -> { - // Update the favorite icon based on the islike value - if (islike) { + if (dislike) { binding.downloadFavorite.setImageResource(android.R.drawable.btn_star_big_on); } else { binding.downloadFavorite.setImageResource(android.R.drawable.btn_star_big_off); @@ -126,12 +127,11 @@ public class DownloadActivity extends AppCompatActivity { }); if (wallpaperInfo.getPreview() != null) { - // 应用圆角变换 RequestOptions options = new RequestOptions() .placeholder(R.mipmap.splash) .error(R.mipmap.splash) .transform(new CenterCrop()) - .transform(new RoundedCorners(16)); // 设置圆角度数 + .transform(new RoundedCorners(16)); Glide.with(this) .load(wallpaperInfo.getPreview()) @@ -141,7 +141,6 @@ public class DownloadActivity extends AppCompatActivity { binding.downloadImage.setImageResource(R.mipmap.splash); } - unzipPath = getCacheDir() + "/" + name; } @@ -176,10 +175,8 @@ public class DownloadActivity extends AppCompatActivity { binding.downloadAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(DownloadActivity.this, CategoryActivity.class); startActivity(intent); - } }); @@ -189,34 +186,29 @@ public class DownloadActivity extends AppCompatActivity { ProgressBar progressBar = findViewById(R.id.progressBar); View view = findViewById(R.id.view); - // 显示进度条 progressBar.setVisibility(View.VISIBLE); view.setVisibility(View.VISIBLE); - if (!Mytool.isStep1() || !Mytool.isStep2()) { + if (!InputMethodUtils.isInputMethodEnabled() || !InputMethodUtils.isCurrentInputMethodActive()) { PermissionRequestDialog dialog = new PermissionRequestDialog(); dialog.show(getSupportFragmentManager(), "PermissionRequestDialog"); - // 操作结束后隐藏进度条 progressBar.setVisibility(View.GONE); view.setVisibility(View.GONE); } else { - Mytool.donwnZip(this, url, (successful, resource) -> { + DownloadUtils.downloadFile(this, url, (successful, resource) -> { if (successful) { - Mytool.unZip(this, unzipPath, resource, (successful1, resDirPath) -> { + unzipUtils.unzipFile(this, resource, (successful1, resDirPath) -> { if (successful1) { - // 将路径存储到 SharedPreferences - SharedPreferences sharedPreferences = getSharedPreferences("keyboard_prefs", MODE_PRIVATE); + SharedPreferences sharedPreferences = getSharedPreferences("keyboard_info", MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putString("wallpaper_path", resDirPath); - editor.apply(); // 使用 apply() 异步保存 + editor.apply(); - StaticValue.PATH = resDirPath; + if (userdata != null) { + userdata.setPath(resDirPath); + userdata.setDownloaded(true); - if (otherdata != null) { - otherdata.setPath(resDirPath); - otherdata.setDownloaded(true); - - Mytool.runIO(() -> MyDatabase.getInstance().wallpaperInfoDao().update(otherdata)); + TaskExecutorUtils.executeIO(() -> AppDatabase.getInstance().wallpaperInfoDao().update(userdata)); } } else { runOnUiThread(() -> { @@ -224,7 +216,6 @@ public class DownloadActivity extends AppCompatActivity { }); } - // 解压完成,隐藏进度条 runOnUiThread(() -> { progressBar.setVisibility(View.GONE); view.setVisibility(View.GONE); @@ -233,7 +224,6 @@ public class DownloadActivity extends AppCompatActivity { }); }); } else { - // 下载失败,隐藏进度条 runOnUiThread(() -> { progressBar.setVisibility(View.GONE); view.setVisibility(View.GONE); @@ -246,7 +236,7 @@ public class DownloadActivity extends AppCompatActivity { @Override public void onBackPressed() { super.onBackPressed(); - AdManager.showTopOn(this,new onActionListener() { + AdManager.showTopOn(this, new onActionListener() { @Override public void onAction() { finish(); diff --git a/app/src/main/java/com/key/vibekeyboard/ui/activity/MainActivity.java b/app/src/main/java/com/key/vibekeyboard/ui/activity/MainActivity.java new file mode 100644 index 0000000..0ecba07 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/ui/activity/MainActivity.java @@ -0,0 +1,142 @@ +package com.key.vibekeyboard.ui.activity; + +import android.os.Bundle; +import android.view.LayoutInflater; + +import androidx.activity.EdgeToEdge; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; + +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.key.vibekeyboard.ui.adapter.MainViewpager2Adapter; +import com.key.vibekeyboard.MyApplication; +import com.key.vibekeyboard.ui.dialog.PermissionRequestDialog; +import com.key.vibekeyboard.ui.dialog.RecommendedDialog; +import com.key.vibekeyboard.R; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.databinding.ActivityMainBinding; +import com.key.vibekeyboard.databinding.MainTabCustomBinding; +import com.key.vibekeyboard.utils.InputMethodUtils; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; + +public class MainActivity extends AppCompatActivity { + + private ActivityMainBinding binding; + private List list = new ArrayList<>(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityMainBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + EdgeToEdge.enable(this); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + + initViewPager(); + + loadRandomCategory(); + + checkPermissionsAndShowDialog(); + + binding.mainViewpager.setUserInputEnabled(false); + + initTabLayout(); + } + + private void initViewPager() { + MainViewpager2Adapter adapter = new MainViewpager2Adapter(this); + binding.mainViewpager.setAdapter(adapter); + } + + private void loadRandomCategory() { + List categories = MyApplication.getCategories(); + Random random = new Random(); + int randomIndex = random.nextInt(categories.size()); + list = categories.get(randomIndex).getList(); + } + + private void checkPermissionsAndShowDialog() { + if (InputMethodUtils.isInputMethodEnabled() && InputMethodUtils.isCurrentInputMethodActive()) { + showRecommendedDialog(); + } else { + showPermissionDialog(); + } + } + + public void showPermissionDialog() { + PermissionRequestDialog dialog = new PermissionRequestDialog(); + dialog.show(getSupportFragmentManager(), "PermissionRequestDialog"); + } + + public void showRecommendedDialog() { + RecommendedDialog dialog = new RecommendedDialog(); + if (list != null) { + dialog.setList(list); + } + dialog.show(getSupportFragmentManager(), "RecommendedDialog"); + } + + private void initTabLayout() { + new TabLayoutMediator(binding.mainTablayout, binding.mainViewpager, (tab, position) -> { + MainTabCustomBinding tabBinding = MainTabCustomBinding.inflate(LayoutInflater.from(this)); + tab.setCustomView(tabBinding.getRoot()); + + setTabIcon(tabBinding, position); + }).attach(); + + binding.mainTablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { + @Override + public void onTabSelected(TabLayout.Tab tab) { + MainTabCustomBinding tabBinding = MainTabCustomBinding.bind(Objects.requireNonNull(tab.getCustomView())); + int position = tab.getPosition(); + setTabIcon(tabBinding, position, true); + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) { + MainTabCustomBinding tabBinding = MainTabCustomBinding.bind(Objects.requireNonNull(tab.getCustomView())); + int position = tab.getPosition(); + setTabIcon(tabBinding, position, false); + } + + @Override + public void onTabReselected(TabLayout.Tab tab) { + } + }); + } + + private void setTabIcon(MainTabCustomBinding tabBinding, int position) { + setTabIcon(tabBinding, position, false); + } + + private void setTabIcon(MainTabCustomBinding tabBinding, int position, boolean isSelected) { + if (position == 0) { + tabBinding.iconCustom.setImageResource(isSelected ? R.drawable.home_select : R.drawable.home); + } else if (position == 1) { + tabBinding.iconCustom.setImageResource(isSelected ? R.drawable.collection_select : R.drawable.collection); + } else { + tabBinding.iconCustom.setImageResource(isSelected ? R.drawable.setting_select : R.drawable.setting); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + binding = null; + } +} + diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/SearchActivity.java b/app/src/main/java/com/key/vibekeyboard/ui/activity/SearchActivity.java similarity index 63% rename from app/src/main/java/com/key/vibekeyboard/Activity/SearchActivity.java rename to app/src/main/java/com/key/vibekeyboard/ui/activity/SearchActivity.java index 7bb6879..00e5496 100644 --- a/app/src/main/java/com/key/vibekeyboard/Activity/SearchActivity.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/activity/SearchActivity.java @@ -1,17 +1,22 @@ -package com.key.vibekeyboard.Activity; +package com.key.vibekeyboard.ui.activity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; +import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import androidx.recyclerview.widget.LinearLayoutManager; -import com.key.vibekeyboard.Adapter.SearchRecyclerViewAdapter; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.Utils.ItemDecoration; -import com.key.vibekeyboard.Utils.Mytool; +import com.key.vibekeyboard.R; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.ui.adapter.WallpaperAdapter; +import com.key.vibekeyboard.utils.ItemDecoration; +import com.key.vibekeyboard.utils.JsonUtils; import com.key.vibekeyboard.databinding.ActivitySearchBinding; import com.key.vibekeyboard.topon.AdManager; import com.key.vibekeyboard.topon.onActionListener; @@ -22,9 +27,9 @@ import java.util.List; public class SearchActivity extends AppCompatActivity { private ActivitySearchBinding binding; - private List categories = Mytool.parseJsonToList("keyboard.json"); - private List filteredList = new ArrayList<>(); - private SearchRecyclerViewAdapter adapter; // 适配器类 + private final List categories = JsonUtils.parseJson("keyboard.json"); + private final List filteredList = new ArrayList<>(); + private WallpaperAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { @@ -33,8 +38,20 @@ public class SearchActivity extends AppCompatActivity { binding = ActivitySearchBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + EdgeToEdge.enable(this); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + AdManager.loadAllAd(); + initData(); + initEvent(); + } + + private void initData(){ AdManager.showTopOn(this, new onActionListener() { @Override public void onAction() { @@ -42,18 +59,17 @@ public class SearchActivity extends AppCompatActivity { } }); - // 设置 RecyclerView binding.recyclerView.setLayoutManager(new LinearLayoutManager(this)); - adapter = new SearchRecyclerViewAdapter(filteredList, this); - // 为 RecyclerView 添加自定义的间距装饰。 + adapter = new WallpaperAdapter(this, filteredList); ItemDecoration itemDecoration = new ItemDecoration(12, 10, 9); binding.recyclerView.addItemDecoration(itemDecoration); binding.recyclerView.setAdapter(adapter); + } + private void initEvent(){ binding.back.setOnClickListener(v -> finish()); - // 监听输入框内容变化 binding.searchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { @@ -70,7 +86,6 @@ public class SearchActivity extends AppCompatActivity { }); } - // 过滤逻辑,根据输入内容过滤数据 private void filter(String text) { filteredList.clear(); // 清空之前的结果 @@ -82,13 +97,13 @@ public class SearchActivity extends AppCompatActivity { } } - adapter.notifyDataSetChanged(); // 通知适配器更新数据 + adapter.notifyDataSetChanged(); } @Override protected void onDestroy() { super.onDestroy(); - binding = null; // 释放 ViewBinding 的引用 + binding = null; } } diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/SplashActivity.java b/app/src/main/java/com/key/vibekeyboard/ui/activity/SplashActivity.java similarity index 75% rename from app/src/main/java/com/key/vibekeyboard/Activity/SplashActivity.java rename to app/src/main/java/com/key/vibekeyboard/ui/activity/SplashActivity.java index 7256dc4..d9cada3 100644 --- a/app/src/main/java/com/key/vibekeyboard/Activity/SplashActivity.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/activity/SplashActivity.java @@ -1,11 +1,15 @@ -package com.key.vibekeyboard.Activity; +package com.key.vibekeyboard.ui.activity; import android.content.Intent; import android.os.Bundle; import android.os.CountDownTimer; import android.widget.ProgressBar; +import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.graphics.Insets; +import androidx.core.view.ViewCompat; +import androidx.core.view.WindowInsetsCompat; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; @@ -27,6 +31,13 @@ public class SplashActivity extends AppCompatActivity { binding = ActivitySplashBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + EdgeToEdge.enable(this); + ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { + Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); + v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); + return insets; + }); + AdManager.loadAllAd(); ProgressBar progressBar = binding.progressBar; @@ -40,7 +51,7 @@ public class SplashActivity extends AppCompatActivity { int percentage = (int) (100 - (float) millisUntilFinished / TOTAL_TIME * 100); progressBar.setProgress(percentage); }, - this::startMain // 倒计时结束或广告展示结束时,跳转主界面 + this::startMain ); countDownTimer.start(); diff --git a/app/src/main/java/com/key/vibekeyboard/Activity/PermissionActivity.java b/app/src/main/java/com/key/vibekeyboard/ui/activity/WriteActivity.java similarity index 60% rename from app/src/main/java/com/key/vibekeyboard/Activity/PermissionActivity.java rename to app/src/main/java/com/key/vibekeyboard/ui/activity/WriteActivity.java index fec55da..df6b81a 100644 --- a/app/src/main/java/com/key/vibekeyboard/Activity/PermissionActivity.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/activity/WriteActivity.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Activity; +package com.key.vibekeyboard.ui.activity; import android.os.Bundle; @@ -9,18 +9,31 @@ import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import com.key.vibekeyboard.R; +import com.key.vibekeyboard.databinding.ActivityWriteBinding; -public class PermissionActivity extends AppCompatActivity { +public class WriteActivity extends AppCompatActivity { + + private ActivityWriteBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + binding = ActivityWriteBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + EdgeToEdge.enable(this); - setContentView(R.layout.activity_permission); ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); + + binding.back.setOnClickListener(v -> finish()); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + binding = null; } } \ No newline at end of file diff --git a/app/src/main/java/com/key/vibekeyboard/Adapter/CategoryViewPager2Adapter.java b/app/src/main/java/com/key/vibekeyboard/ui/adapter/CategoryViewPager2Adapter.java similarity index 84% rename from app/src/main/java/com/key/vibekeyboard/Adapter/CategoryViewPager2Adapter.java rename to app/src/main/java/com/key/vibekeyboard/ui/adapter/CategoryViewPager2Adapter.java index 4ddd1c5..243bed5 100644 --- a/app/src/main/java/com/key/vibekeyboard/Adapter/CategoryViewPager2Adapter.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/adapter/CategoryViewPager2Adapter.java @@ -1,12 +1,12 @@ -package com.key.vibekeyboard.Adapter; +package com.key.vibekeyboard.ui.adapter; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.viewpager2.adapter.FragmentStateAdapter; -import com.key.vibekeyboard.Fragment.CategoryFragment; -import com.key.vibekeyboard.Room.Category; +import com.key.vibekeyboard.ui.fragment.CategoryFragment; +import com.key.vibekeyboard.data.bean.Category; import java.util.List; diff --git a/app/src/main/java/com/key/vibekeyboard/Adapter/HomeViewPager2Adapter.java b/app/src/main/java/com/key/vibekeyboard/ui/adapter/HomeSliderAdapter.java similarity index 78% rename from app/src/main/java/com/key/vibekeyboard/Adapter/HomeViewPager2Adapter.java rename to app/src/main/java/com/key/vibekeyboard/ui/adapter/HomeSliderAdapter.java index 7961348..fae3812 100644 --- a/app/src/main/java/com/key/vibekeyboard/Adapter/HomeViewPager2Adapter.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/adapter/HomeSliderAdapter.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Adapter; +package com.key.vibekeyboard.ui.adapter; import android.content.Context; import android.content.Intent; @@ -14,21 +14,21 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Activity.DownloadActivity; +import com.key.vibekeyboard.ui.activity.DownloadActivity; import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.WallpaperInfo; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; import java.util.ArrayList; import java.util.List; import java.util.Random; -public class HomeViewPager2Adapter extends RecyclerView.Adapter { +public class HomeSliderAdapter extends RecyclerView.Adapter { - private List categories; - private Context context; + private final List categories; + private final Context context; - public HomeViewPager2Adapter(Context context, List categories) { + public HomeSliderAdapter(Context context, List categories) { this.context = context; this.categories = categories; } @@ -43,10 +43,9 @@ public class HomeViewPager2Adapter extends RecyclerView.Adapter list = category.getList(); - WallpaperInfo categoryWallpaperInfo = category.getList().get(position); Random random = new Random(); int randomIndex = random.nextInt(20); WallpaperInfo wallpaperInfo = category.getList().get(randomIndex); @@ -63,12 +62,11 @@ public class HomeViewPager2Adapter extends RecyclerView.Adapter { +public class WallpaperAdapter extends RecyclerView.Adapter { - private Context context; - private List list; + private final Context context; + private final List list; - public CategoryRecyclerViewAdapter(Context context, List list) { + public WallpaperAdapter(Context context, List list) { this.context = context; this.list = list; @@ -53,8 +54,8 @@ public class CategoryRecyclerViewAdapter extends RecyclerView.Adapter(limitedList)); // list 中的 WallpaperInfo 对象实现了 Parcelable + intent.putExtra("wallpaperInfo", wallpaperInfo); + intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); context.startActivity(intent); } }); @@ -63,12 +64,11 @@ public class CategoryRecyclerViewAdapter extends RecyclerView.Adapter newList) { + DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffUtil.Callback() { + @Override + public int getOldListSize() { + return list.size(); + } + + @Override + public int getNewListSize() { + return newList.size(); + } + + @Override + public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { + return list.get(oldItemPosition).getId() == newList.get(newItemPosition).getId(); + } + + @Override + public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { + return list.get(oldItemPosition).equals(newList.get(newItemPosition)); + } + }); + + list.clear(); + list.addAll(newList); + diffResult.dispatchUpdatesTo(this); + } + } diff --git a/app/src/main/java/com/key/vibekeyboard/Dialog/PermissionRequestDialog.java b/app/src/main/java/com/key/vibekeyboard/ui/dialog/PermissionRequestDialog.java similarity index 75% rename from app/src/main/java/com/key/vibekeyboard/Dialog/PermissionRequestDialog.java rename to app/src/main/java/com/key/vibekeyboard/ui/dialog/PermissionRequestDialog.java index 1844322..91751c6 100644 --- a/app/src/main/java/com/key/vibekeyboard/Dialog/PermissionRequestDialog.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/dialog/PermissionRequestDialog.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Dialog; +package com.key.vibekeyboard.ui.dialog; import android.app.Dialog; import android.content.Context; @@ -21,20 +21,21 @@ import androidx.fragment.app.DialogFragment; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; -import com.key.vibekeyboard.AppApplication; +import com.key.vibekeyboard.MyApplication; import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Utils.Mytool; import com.key.vibekeyboard.databinding.DialogPermissionBinding; +import com.key.vibekeyboard.utils.InputMethodUtils; public class PermissionRequestDialog extends DialogFragment { private DialogPermissionBinding binding; private InputMethodManager methodManager; - private ContentObserver inputMethodObserver; // 用于监听输入法变化 + private ContentObserver inputMethodObserver; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setCancelable(true); } @Override @@ -44,21 +45,8 @@ public class PermissionRequestDialog extends DialogFragment { return binding.getRoot(); } - @Override - public void onResume() { - super.onResume(); - Dialog dialog = getDialog(); - setCancelable(true); - if (dialog != null && dialog.getWindow() != null) { - Window window = dialog.getWindow(); - window.setLayout((int) (getResources().getDisplayMetrics().widthPixels * 0.9), WindowManager.LayoutParams.WRAP_CONTENT); - } - - update(); - } - public void init() { - methodManager = (InputMethodManager) AppApplication.instance.getSystemService(Context.INPUT_METHOD_SERVICE); + methodManager = (InputMethodManager) MyApplication.instance.getSystemService(Context.INPUT_METHOD_SERVICE); Glide.with(requireContext()) .load(R.mipmap.ic_launcher_foreground) @@ -76,18 +64,20 @@ public class PermissionRequestDialog extends DialogFragment { binding.imageView.setOnClickListener(v -> dismiss()); - // 注册ContentObserver监听输入法变化 inputMethodObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); - if (Mytool.isStep1() && Mytool.isStep2()) { - dismiss(); // 条件满足,关闭对话框 + if (InputMethodUtils.isInputMethodEnabled() && InputMethodUtils.isCurrentInputMethodActive()) { + dismiss(); } } }; + } - // 注册观察输入法变化 + @Override + public void onStart() { + super.onStart(); requireContext().getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.DEFAULT_INPUT_METHOD), false, @@ -95,17 +85,41 @@ public class PermissionRequestDialog extends DialogFragment { ); } - public void update() { - if (Mytool.isStep1()) { - binding.firstIconTextLayout.setSelected(Mytool.isStep1()); - binding.firstIconTextLayout.setClickable(false); + @Override + public void onStop() { + super.onStop(); + if (inputMethodObserver != null) { + requireContext().getContentResolver().unregisterContentObserver(inputMethodObserver); } - if (Mytool.isStep2()) { - binding.secondIconTextLayout.setSelected(Mytool.isStep2()); - binding.secondIconTextLayout.setClickable(false); + } + + @Override + public void onResume() { + super.onResume(); + Dialog dialog = getDialog(); + if (dialog != null && dialog.getWindow() != null) { + Window window = dialog.getWindow(); + window.setLayout((int) (getResources().getDisplayMetrics().widthPixels * 0.9), WindowManager.LayoutParams.WRAP_CONTENT); } - if (Mytool.isStep1() && Mytool.isStep2()) { + update(); + } + + public void update() { + boolean isEnabled = InputMethodUtils.isInputMethodEnabled(); + boolean isActive = InputMethodUtils.isCurrentInputMethodActive(); + + if (isEnabled) { + binding.firstIconTextLayout.setClickable(false); + binding.firstIconTextLayout.setSelected(true); + } else { + binding.firstIconTextLayout.setClickable(true); + binding.firstIconTextLayout.setSelected(false); + } + + binding.secondIconTextLayout.setSelected(isActive); + + if (isEnabled && isActive) { dismiss(); } } @@ -113,9 +127,7 @@ public class PermissionRequestDialog extends DialogFragment { @Override public void onDestroy() { super.onDestroy(); - if (inputMethodObserver != null) { - requireContext().getContentResolver().unregisterContentObserver(inputMethodObserver); - } binding = null; } } + diff --git a/app/src/main/java/com/key/vibekeyboard/Dialog/RecommendedDialog.java b/app/src/main/java/com/key/vibekeyboard/ui/dialog/RecommendedDialog.java similarity index 59% rename from app/src/main/java/com/key/vibekeyboard/Dialog/RecommendedDialog.java rename to app/src/main/java/com/key/vibekeyboard/ui/dialog/RecommendedDialog.java index a7d7d47..03320d2 100644 --- a/app/src/main/java/com/key/vibekeyboard/Dialog/RecommendedDialog.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/dialog/RecommendedDialog.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Dialog; +package com.key.vibekeyboard.ui.dialog; import android.app.Dialog; import android.content.Intent; @@ -17,9 +17,9 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; -import com.key.vibekeyboard.Activity.DownloadActivity; +import com.key.vibekeyboard.ui.activity.DownloadActivity; import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.WallpaperInfo; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; import com.key.vibekeyboard.databinding.DialogRecommendedBinding; import java.util.ArrayList; @@ -28,11 +28,10 @@ import java.util.Random; public class RecommendedDialog extends DialogFragment { - private DialogRecommendedBinding binding; // 绑定布局文件 - private List list = new ArrayList<>(); // 存储壁纸信息的列表 - private WallpaperInfo wallpaperInfo; // 当前选择的壁纸信息 + private DialogRecommendedBinding binding; + private List list = new ArrayList<>(); + private WallpaperInfo wallpaperInfo; - // 设置壁纸列表 public void setList(List list) { this.list = list; } @@ -40,7 +39,6 @@ public class RecommendedDialog extends DialogFragment { @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - // 将布局文件与视图绑定 binding = DialogRecommendedBinding.inflate(inflater, container, false); return binding.getRoot(); } @@ -49,59 +47,48 @@ public class RecommendedDialog extends DialogFragment { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - // 初始化对话框设置 Dialog dialog = getDialog(); - setCancelable(true); // 设置为 true 对话框可点击外面取消 + setCancelable(true); if (dialog != null && dialog.getWindow() != null) { Window window = dialog.getWindow(); window.setLayout((int) (getResources().getDisplayMetrics().widthPixels * 0.9), WindowManager.LayoutParams.WRAP_CONTENT); } - // 随机选择一个壁纸 Random random = new Random(); int randomIndex = random.nextInt(list.size()); - wallpaperInfo = list.get(randomIndex); // 获取随机的壁纸信息 + wallpaperInfo = list.get(randomIndex); List limitedList = list.subList(0, Math.min(20, list.size())); - // 加载图像 loadImage(); - // 点击图片后进入下载界面 binding.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(requireContext(), DownloadActivity.class); - // 将选中的壁纸信息传递给下一个 Activity - intent.putExtra("wallpaperInfo", wallpaperInfo); // wallpaperInfo 已经实现了 Parcelable - // 将壁纸列表传递给下一个 Activity - intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); // list 中的 WallpaperInfo 对象实现了 Parcelable - dismiss(); // 关闭当前对话框 - requireContext().startActivity(intent); // 启动下载界面 + intent.putExtra("wallpaperInfo", wallpaperInfo); + intent.putParcelableArrayListExtra("list", new ArrayList<>(limitedList)); + dismiss(); + requireContext().startActivity(intent); } }); } - // 加载图像的方法 private void loadImage() { - // 判断壁纸的预览图 URL 是否有效 if (wallpaperInfo.getPreview() != null && !wallpaperInfo.getPreview().isEmpty()) { - // 设置图像的加载选项 RequestOptions options = new RequestOptions() .placeholder(R.mipmap.splash) .error(R.mipmap.splash) - .transform(new CenterCrop()) // 中心裁剪,保证图片填满控件 - .transform(new RoundedCorners(16)); // 设置圆角,16px + .transform(new CenterCrop()) + .transform(new RoundedCorners(16)); - // 使用 Glide 加载图像 Glide.with(requireContext()) - .asDrawable() // 指定加载为 Drawable - .load(wallpaperInfo.getPreview()) // 设置要加载的图片 URL - .apply(options) // 应用上面定义的加载选项 - .into(binding.imageView); // 设置到 ImageView 上显示 + .asDrawable() + .load(wallpaperInfo.getPreview()) + .apply(options) + .into(binding.imageView); } else { - // 如果预览图 URL 为空,显示默认图像 - binding.imageView.setImageResource(R.mipmap.splash); // 默认图像 + binding.imageView.setImageResource(R.mipmap.splash); } } diff --git a/app/src/main/java/com/key/vibekeyboard/Fragment/CategoryFragment.java b/app/src/main/java/com/key/vibekeyboard/ui/fragment/CategoryFragment.java similarity index 63% rename from app/src/main/java/com/key/vibekeyboard/Fragment/CategoryFragment.java rename to app/src/main/java/com/key/vibekeyboard/ui/fragment/CategoryFragment.java index 3e491c5..7351620 100644 --- a/app/src/main/java/com/key/vibekeyboard/Fragment/CategoryFragment.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/fragment/CategoryFragment.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Fragment; +package com.key.vibekeyboard.ui.fragment; import android.os.Bundle; import android.view.LayoutInflater; @@ -10,11 +10,11 @@ import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.GridLayoutManager; -import com.key.vibekeyboard.Adapter.CategoryRecyclerViewAdapter; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.Utils.ItemDecoration; -import com.key.vibekeyboard.Utils.Mytool; +import com.key.vibekeyboard.ui.adapter.WallpaperAdapter; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.utils.ItemDecoration; +import com.key.vibekeyboard.utils.JsonUtils; import com.key.vibekeyboard.databinding.FragmentCategoryBinding; import java.util.ArrayList; @@ -25,26 +25,24 @@ public class CategoryFragment extends Fragment { private static final String ARG_CATEGORY = "category"; private FragmentCategoryBinding binding; - private String category; // 用于存储从外部传入的类别名称。 - private final List categories = Mytool.parseJsonToList("keyboard.json"); + private String category; + private final List categories = JsonUtils.parseJson("keyboard.json"); public CategoryFragment() { } - // 工厂方法,用于创建 Fragment 的实例,并通过 Bundle 传递类别参数。 public static CategoryFragment newInstance(String category) { CategoryFragment fragment = new CategoryFragment(); Bundle args = new Bundle(); - args.putString(ARG_CATEGORY, category); // 将类别参数存储到 Bundle 中。 - fragment.setArguments(args); // 将 Bundle 设置为 Fragment 的参数。 + args.putString(ARG_CATEGORY, category); + fragment.setArguments(args); return fragment; } - // 当 Fragment 创建时调用,用于初始化一些变量。 + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // 如果 Fragment 有传入的参数,则获取并存储类别名称。 if (getArguments() != null) { category = getArguments().getString(ARG_CATEGORY); } @@ -58,15 +56,13 @@ public class CategoryFragment extends Fragment { List list = getListByClassName(category); - CategoryRecyclerViewAdapter adapter = new CategoryRecyclerViewAdapter(requireContext(),list); + WallpaperAdapter adapter = new WallpaperAdapter(requireContext(),list); binding.categoryRecycler.setAdapter(adapter); binding.categoryRecycler.setLayoutManager(new GridLayoutManager(getContext(), 2)); - // 为 RecyclerView 添加自定义的间距装饰。 ItemDecoration itemDecoration = new ItemDecoration(12, 10, 9); binding.categoryRecycler.addItemDecoration(itemDecoration); return binding.getRoot(); - } public List getListByClassName(String className) { @@ -75,14 +71,13 @@ public class CategoryFragment extends Fragment { return category.getList(); } } - // 如果没有找到,返回一个空列表 return new ArrayList<>(); } @Override public void onDestroy() { super.onDestroy(); - binding = null; // 释放 ViewBinding 的引用 + binding = null; } } \ No newline at end of file diff --git a/app/src/main/java/com/key/vibekeyboard/Fragment/FavoriteFragment.java b/app/src/main/java/com/key/vibekeyboard/ui/fragment/FavoriteFragment.java similarity index 70% rename from app/src/main/java/com/key/vibekeyboard/Fragment/FavoriteFragment.java rename to app/src/main/java/com/key/vibekeyboard/ui/fragment/FavoriteFragment.java index f2e7f5a..180efc0 100644 --- a/app/src/main/java/com/key/vibekeyboard/Fragment/FavoriteFragment.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/fragment/FavoriteFragment.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Fragment; +package com.key.vibekeyboard.ui.fragment; import android.os.Bundle; import android.view.LayoutInflater; @@ -11,10 +11,10 @@ import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.GridLayoutManager; -import com.key.vibekeyboard.Adapter.FavoriteRecyclerViewAdapter; -import com.key.vibekeyboard.Room.WallpaperInfo; -import com.key.vibekeyboard.Utils.ItemDecoration; -import com.key.vibekeyboard.ViewModel.FavoriteViewModel; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.ui.adapter.WallpaperAdapter; +import com.key.vibekeyboard.utils.ItemDecoration; +import com.key.vibekeyboard.viewmodel.WallpaperViewModel; import com.key.vibekeyboard.databinding.FragmentFavoriteBinding; import java.util.ArrayList; @@ -24,7 +24,7 @@ import java.util.List; public class FavoriteFragment extends Fragment { private FragmentFavoriteBinding binding; - private FavoriteRecyclerViewAdapter adapter; + private WallpaperAdapter adapter; private final List wallpaperInfoList = new ArrayList<>(); @Override @@ -32,18 +32,15 @@ public class FavoriteFragment extends Fragment { Bundle savedInstanceState) { binding = FragmentFavoriteBinding.inflate(inflater, container, false); - adapter = new FavoriteRecyclerViewAdapter(requireContext(), wallpaperInfoList); + adapter = new WallpaperAdapter(requireContext(), wallpaperInfoList); binding.favoriteRecyclerview.setAdapter(adapter); - // 初始化 RecyclerView 和 LayoutManager binding.favoriteRecyclerview.setLayoutManager(new GridLayoutManager(getContext(), 2)); binding.favoriteRecyclerview.addItemDecoration(new ItemDecoration(16, 19, 10)); - // 获取 ViewModel 实例 - FavoriteViewModel favoriteViewModel = new ViewModelProvider(this).get(FavoriteViewModel.class); + WallpaperViewModel wallpaperViewModel = new ViewModelProvider(this).get(WallpaperViewModel.class); - // 监听 LiveData 的变化并更新 RecyclerView - favoriteViewModel.getFavoriteList().observe(getViewLifecycleOwner(), new Observer>() { + wallpaperViewModel.getFavoriteList().observe(getViewLifecycleOwner(), new Observer>() { @Override public void onChanged(List wallpaperInfoList) { diff --git a/app/src/main/java/com/key/vibekeyboard/Fragment/HomeFragment.java b/app/src/main/java/com/key/vibekeyboard/ui/fragment/HomeFragment.java similarity index 69% rename from app/src/main/java/com/key/vibekeyboard/Fragment/HomeFragment.java rename to app/src/main/java/com/key/vibekeyboard/ui/fragment/HomeFragment.java index 21644d4..a30bc14 100644 --- a/app/src/main/java/com/key/vibekeyboard/Fragment/HomeFragment.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/fragment/HomeFragment.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Fragment; +package com.key.vibekeyboard.ui.fragment; import android.content.Intent; import android.os.Bundle; @@ -16,25 +16,27 @@ import android.view.ViewTreeObserver; import android.widget.ImageView; import android.widget.LinearLayout; -import com.key.vibekeyboard.Activity.CategoryActivity; -import com.key.vibekeyboard.Activity.SearchActivity; -import com.key.vibekeyboard.Adapter.HomeRecyclerViewAdapter; -import com.key.vibekeyboard.Adapter.HomeViewPager2Adapter; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; +import com.key.vibekeyboard.ui.activity.CategoryActivity; +import com.key.vibekeyboard.ui.activity.SearchActivity; +import com.key.vibekeyboard.ui.adapter.HomeSliderAdapter; import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Room.Category; -import com.key.vibekeyboard.Utils.ItemDecoration; -import com.key.vibekeyboard.Utils.Mytool; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.ui.adapter.WallpaperAdapter; +import com.key.vibekeyboard.utils.ItemDecoration; +import com.key.vibekeyboard.utils.JsonUtils; import com.key.vibekeyboard.databinding.FragmentHomeBinding; import com.key.vibekeyboard.topon.AdManager; import com.key.vibekeyboard.topon.onActionListener; import java.util.List; +import java.util.Random; public class HomeFragment extends Fragment { private FragmentHomeBinding binding; - private HomeViewPager2Adapter homeViewPager2Adapter; + private HomeSliderAdapter homeSliderAdapter; private List categories; @Override @@ -53,21 +55,21 @@ public class HomeFragment extends Fragment { } public void initData() { - // 解析Json - categories = Mytool.parseJsonToList("keyboard.json"); + categories = JsonUtils.parseJson("keyboard.json"); Log.d("dsd", "size" + categories.size()); - // 设置ViewPager2 - homeViewPager2Adapter = new HomeViewPager2Adapter(requireContext(), categories); - binding.homeViewPager.setAdapter(homeViewPager2Adapter); + homeSliderAdapter = new HomeSliderAdapter(requireContext(), categories); + binding.homeViewPager.setAdapter(homeSliderAdapter); setupIndicators(categories.size()); - // 设置RecyclerView + Random random = new Random(); + int randomIndex = random.nextInt(categories.size()); + List wallpaperInfos = categories.get(randomIndex).getList(); + binding.homeRecycler.setLayoutManager(new GridLayoutManager(getContext(), 2)); - HomeRecyclerViewAdapter homeRecyclerViewAdapter = new HomeRecyclerViewAdapter(requireContext(), categories); + WallpaperAdapter homeRecyclerViewAdapter = new WallpaperAdapter(requireContext(), wallpaperInfos); binding.homeRecycler.setAdapter(homeRecyclerViewAdapter); - // 为 RecyclerView 添加自定义的间距装饰。 ItemDecoration itemDecoration = new ItemDecoration(16, 19, 10); binding.homeRecycler.addItemDecoration(itemDecoration); @@ -91,8 +93,7 @@ public class HomeFragment extends Fragment { binding.homeViewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { - if (position == homeViewPager2Adapter.getItemCount() - 1) { - // 如果用户手动滑到了最后的虚拟页面,切换回第一张 + if (position == homeSliderAdapter.getItemCount() - 1) { binding.homeViewPager.postDelayed(() -> binding.homeViewPager.setCurrentItem(0, false), 300); } } @@ -101,51 +102,43 @@ public class HomeFragment extends Fragment { binding.homeSearch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(getContext(), SearchActivity.class); - startActivity(intent); + Intent intent = new Intent(getContext(), SearchActivity.class); + startActivity(intent); } }); binding.homeViewPager.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { - // 移除布局监听器,避免重复执行 binding.homeViewPager.getViewTreeObserver().removeOnGlobalLayoutListener(this); - // 动态生成圆点指示器 setupIndicators(categories.size()); - // 初始设置选中的圆点 updateIndicators(0); } }); - // 设置自动轮播功能 autoSlideImages(); setupViewPagerListener(); } - // 自动轮播图片 private void autoSlideImages() { - final int delay = 3000; // 延迟 3 秒 + final int delay = 3000; binding.homeViewPager.postDelayed(new Runnable() { @Override public void run() { if (binding == null) { - return; // 如果已经销毁,终止任务 + return; } int currentItem = binding.homeViewPager.getCurrentItem(); int nextItem = currentItem + 1; - if (nextItem >= homeViewPager2Adapter.getItemCount()) { - // 如果到达了最后的虚拟页面,瞬间跳回第一张,禁用动画 + if (nextItem >= homeSliderAdapter.getItemCount()) { binding.homeViewPager.setCurrentItem(0, false); } else { - // 正常切换到下一张,有动画效果 binding.homeViewPager.setCurrentItem(nextItem, true); } - // 继续下一次轮播 binding.homeViewPager.postDelayed(this, delay); } }, delay); @@ -156,9 +149,7 @@ public class HomeFragment extends Fragment { @Override public void onPageSelected(int position) { super.onPageSelected(position); - - updateIndicators(position); // 更新圆点 - + updateIndicators(position); } }); @@ -166,20 +157,19 @@ public class HomeFragment extends Fragment { private void setupIndicators(int count) { LinearLayout indicatorLayout = binding.indicatorLayout; - indicatorLayout.removeAllViews(); // 清空原有的圆点 + indicatorLayout.removeAllViews(); for (int i = 0; i < count; i++) { ImageView indicator = new ImageView(getContext()); - indicator.setImageResource(R.drawable.circle_indicator); // 默认圆点 + indicator.setImageResource(R.drawable.circle_indicator); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - params.setMargins(8, 0, 8, 0); // 设置圆点间距 + params.setMargins(8, 0, 8, 0); indicator.setLayoutParams(params); indicatorLayout.addView(indicator); } - // 延迟设置选中的圆点 - indicatorLayout.post(() -> updateIndicators(0)); // 设置第一个圆点为选中状态 + indicatorLayout.post(() -> updateIndicators(0)); } private void updateIndicators(int position) { @@ -189,13 +179,12 @@ public class HomeFragment extends Fragment { for (int i = 0; i < childCount; i++) { ImageView indicator = (ImageView) indicatorLayout.getChildAt(i); if (i == position) { - indicator.setImageResource(R.drawable.circle_indicator_selected); // 当前页选中的圆点 + indicator.setImageResource(R.drawable.circle_indicator_selected); } else { - indicator.setImageResource(R.drawable.circle_indicator); // 默认圆点 + indicator.setImageResource(R.drawable.circle_indicator); } } - // 强制更新布局,确保圆点大小正确 indicatorLayout.requestLayout(); } @@ -203,7 +192,6 @@ public class HomeFragment extends Fragment { public void onDestroy() { super.onDestroy(); if (binding != null) { - // 移除所有绑定到 ViewPager 的回调任务 binding.homeViewPager.removeCallbacks(null); } binding = null; diff --git a/app/src/main/java/com/key/vibekeyboard/Fragment/SettingFragment.java b/app/src/main/java/com/key/vibekeyboard/ui/fragment/SettingFragment.java similarity index 88% rename from app/src/main/java/com/key/vibekeyboard/Fragment/SettingFragment.java rename to app/src/main/java/com/key/vibekeyboard/ui/fragment/SettingFragment.java index aae2bf4..3dd8252 100644 --- a/app/src/main/java/com/key/vibekeyboard/Fragment/SettingFragment.java +++ b/app/src/main/java/com/key/vibekeyboard/ui/fragment/SettingFragment.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.Fragment; +package com.key.vibekeyboard.ui.fragment; import android.os.Bundle; @@ -8,8 +8,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import com.key.vibekeyboard.R; -import com.key.vibekeyboard.Utils.SettingUtil; +import com.key.vibekeyboard.utils.SettingUtil; import com.key.vibekeyboard.databinding.FragmentSettingBinding; public class SettingFragment extends Fragment { @@ -27,7 +26,6 @@ public class SettingFragment extends Fragment { SettingUtil.shareApp(requireContext()); }); - return binding.getRoot(); } diff --git a/app/src/main/java/com/key/vibekeyboard/utils/DownloadUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/DownloadUtils.java new file mode 100644 index 0000000..828c338 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/DownloadUtils.java @@ -0,0 +1,63 @@ +package com.key.vibekeyboard.utils; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; +import com.key.vibekeyboard.viewmodel.callbacks.DownloadCallback; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + +public class DownloadUtils { + + public static void downloadFile(Context context, String url, DownloadCallback callback) { + Glide.with(context) + .asFile() + .load(url) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target target, boolean isFirstResource) { + try { + callback.onDownloadCall(false, null); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + return false; + } + + @Override + public boolean onResourceReady(@NonNull File resource, @NonNull Object model, Target target, @NonNull DataSource dataSource, boolean isFirstResource) { + try { + File externalDir = context.getExternalFilesDir(null); + if (externalDir == null) { + externalDir = context.getFilesDir(); + } + + File downloadDir = new File(externalDir, "DownloadedFiles"); + if (!downloadDir.exists()) { + boolean mkdirs = downloadDir.mkdirs(); + } + + File destinationFile = new File(downloadDir, resource.getName()); + FileUtils.cloneFile(resource, destinationFile); + + callback.onDownloadCall(true, destinationFile); + Log.d("--------", "resource: " + destinationFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + return false; + } + }).preload(); + } + +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/DrawableUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/DrawableUtils.java new file mode 100644 index 0000000..593458a --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/DrawableUtils.java @@ -0,0 +1,55 @@ +package com.key.vibekeyboard.utils; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.inputmethodservice.Keyboard; +import android.util.TypedValue; + +import com.key.vibekeyboard.inputmethod.view.CustomKeyboardView; + +public class DrawableUtils { + + public static void drawKeyIcon(Keyboard.Key currentKey, + Drawable drawKeyIcon, + Canvas myCanvas, + CustomKeyboardView customKeyboardView) { + currentKey.icon = drawKeyIcon; + currentKey.icon.setBounds(getIconBounds(currentKey, drawKeyIcon, customKeyboardView)); + currentKey.icon.draw(myCanvas); + } + + private static Rect getIconBounds(Keyboard.Key currentKey, + Drawable drawKeyIcon, + CustomKeyboardView customKeyboardView) { + float icon_w = drawKeyIcon.getIntrinsicWidth(); + float icon_h = drawKeyIcon.getIntrinsicHeight(); + float icon_wr = icon_w / currentKey.width; + float icon_hr = icon_h / currentKey.height; + + float tep1, tep2; + if (icon_wr > icon_hr) { + tep2 = icon_wr; + tep1 = Math.max(icon_wr, 0.5f); + } else { + tep2 = icon_hr; + tep1 = Math.max(icon_hr, 0.5f); + } + + icon_h = (icon_h / tep2) * tep1; + icon_w = (icon_w / tep2) * tep1; + + int top = (int) (currentKey.y + customKeyboardView.getPaddingTop() + (currentKey.height - icon_h) / 2); + int left = (int) (currentKey.x + customKeyboardView.getPaddingLeft() + (currentKey.width - icon_w) / 2); + int bottom = top + (int) icon_h; + int right = left + (int) icon_w; + + return new Rect(left, top, right, bottom); + } + + public static float spToPx(Float values, Context context) { + return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, values, context.getResources().getDisplayMetrics()); + } + +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/FileUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/FileUtils.java new file mode 100644 index 0000000..8e08b08 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/FileUtils.java @@ -0,0 +1,41 @@ +package com.key.vibekeyboard.utils; + +import android.os.Build; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.nio.file.Files; + +public class FileUtils { + + public static void cloneFile(File sourceFile, File destinationFile) throws IOException { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + try (InputStream in = Files.newInputStream(sourceFile.toPath()); + OutputStream out = Files.newOutputStream(destinationFile.toPath())) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(buffer)) != -1) { + out.write(buffer, 0, bytesRead); + } + } + } + } + + public static String readFileAsString(File file) throws IOException { + FileInputStream fileInputStream = new FileInputStream(file); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream)); + StringBuilder stringBuilder = new StringBuilder(); + String lin = ""; + while ((lin = bufferedReader.readLine()) != null) { + stringBuilder.append(lin); + } + bufferedReader.close(); + return stringBuilder.toString(); + } + +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/InputMethodUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/InputMethodUtils.java new file mode 100644 index 0000000..3680dc1 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/InputMethodUtils.java @@ -0,0 +1,31 @@ +package com.key.vibekeyboard.utils; + +import android.content.Context; +import android.provider.Settings; +import android.view.inputmethod.InputMethodInfo; +import android.view.inputmethod.InputMethodManager; + +import com.key.vibekeyboard.MyApplication; + +import java.util.List; + +public class InputMethodUtils { + private static final InputMethodManager methodManager = + (InputMethodManager) MyApplication.instance.getSystemService(Context.INPUT_METHOD_SERVICE); + + public static boolean isInputMethodEnabled() { + List enabledInputMethods = methodManager.getEnabledInputMethodList(); + for (InputMethodInfo inputMethodInfo : enabledInputMethods) { + if (inputMethodInfo.getId().startsWith(MyApplication.instance.getPackageName())) { + return true; + } + } + return false; + } + + public static boolean isCurrentInputMethodActive() { + String currentInputMethod = Settings.Secure.getString(MyApplication.instance.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); + return currentInputMethod != null && currentInputMethod.startsWith(MyApplication.instance.getPackageName()); + } +} + diff --git a/app/src/main/java/com/key/vibekeyboard/utils/ItemDecoration.java b/app/src/main/java/com/key/vibekeyboard/utils/ItemDecoration.java new file mode 100644 index 0000000..257d695 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/ItemDecoration.java @@ -0,0 +1,78 @@ +package com.key.vibekeyboard.utils; + +import android.graphics.Rect; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.StaggeredGridLayoutManager; + +import com.key.vibekeyboard.MyApplication; + + +public class ItemDecoration extends RecyclerView.ItemDecoration { + + private final int v; + private final int h; + private final int ex; + + public ItemDecoration(int v, int h, int ex) { + this.v = Math.round(dpToPx(v)); + this.h = Math.round(dpToPx(h)); + this.ex = Math.round(dpToPx(ex)); + } + + @Override + public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); + + int spanCount = 1; + int spanSize = 1; + int spanIndex = 0; + + int childAdapterPosition = parent.getChildAdapterPosition(view); + RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); + + if (layoutManager instanceof StaggeredGridLayoutManager) { + StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager; + StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams(); + spanCount = staggeredGridLayoutManager.getSpanCount(); + if (layoutParams.isFullSpan()) { + spanSize = spanCount; + } + spanIndex = layoutParams.getSpanIndex(); + + } else if (layoutManager instanceof GridLayoutManager) { + GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager; + GridLayoutManager.LayoutParams layoutParams = (GridLayoutManager.LayoutParams) view.getLayoutParams(); + spanCount = gridLayoutManager.getSpanCount(); + spanSize = gridLayoutManager.getSpanSizeLookup().getSpanSize(childAdapterPosition); + spanIndex = layoutParams.getSpanIndex(); + + } else if (layoutManager instanceof LinearLayoutManager) { + outRect.left = v; + outRect.right = v; + outRect.bottom = h; + } + + if (spanSize == spanCount) { + outRect.left = v + ex; + outRect.right = v + ex; + + } else { + int itemAllSpacing = (v * (spanCount + 1) + ex * 2) / spanCount; + int left = v * (spanIndex + 1) - itemAllSpacing * spanIndex + ex; + int right = itemAllSpacing - left; + outRect.left = left; + outRect.right = right; + } + outRect.bottom = h; + } + + public static float dpToPx(float dpValue) { + float density = MyApplication.getContext().getResources().getDisplayMetrics().density; + return density * dpValue + 0.5f; + } +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/JsonUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/JsonUtils.java new file mode 100644 index 0000000..68d8138 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/JsonUtils.java @@ -0,0 +1,70 @@ +package com.key.vibekeyboard.utils; + +import android.content.res.AssetManager; + +import com.key.vibekeyboard.MyApplication; +import com.key.vibekeyboard.data.bean.Category; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class JsonUtils { + + private static JSONArray loadJSONFromAsset(String filename) { + String json; + try { + AssetManager assetManager = MyApplication.getContext().getAssets(); + InputStream inputStream = assetManager.open(filename); + int size = inputStream.available(); + byte[] buffer = new byte[size]; + int i = inputStream.read(buffer); + inputStream.close(); + json = new String(buffer, StandardCharsets.UTF_8); + return new JSONArray(json); + } catch (IOException | JSONException e) { + e.printStackTrace(); + return null; + } + } + + public static List parseJson(String filename) { + List categories = new ArrayList<>(); + try { + JSONArray jsonObject = loadJSONFromAsset(filename); + for (int a = 0; a < Objects.requireNonNull(jsonObject).length(); a++) { + JSONObject list = jsonObject.getJSONObject(a); + Category myData = new Category(); + List wallpaperInfos = new ArrayList<>(); + myData.setClassName(list.getString("className")); + JSONArray classArray = list.getJSONArray("list"); + for (int i = 0; i < classArray.length(); i++) { + JSONObject item = classArray.getJSONObject(i); + WallpaperInfo wallpaperInfo = new WallpaperInfo(); + wallpaperInfo.setDownloaded(false); + wallpaperInfo.setIslike(false); + wallpaperInfo.setClassName(myData.getClassName()); + wallpaperInfo.setPreview(item.getString("preview")); + wallpaperInfo.setThumb(item.getString("thumb")); + wallpaperInfo.setTitle(item.getString("title")); + wallpaperInfo.setZipUrl(item.getString("zipUrl")); + wallpaperInfos.add(wallpaperInfo); + } + myData.setList(wallpaperInfos); + categories.add(myData); + } + } catch (JSONException e) { + e.printStackTrace(); + } + return categories; + } + +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/PathRepository.java b/app/src/main/java/com/key/vibekeyboard/utils/PathRepository.java new file mode 100644 index 0000000..0b379a0 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/PathRepository.java @@ -0,0 +1,12 @@ +package com.key.vibekeyboard.utils; + +public class PathRepository { + public static String NORMAL_KEY_BACKGROUND = "btn_keyboard_key_normal_normal.9.png"; + public static String ACTION_KEY_BACKGROUND = "btn_keyboard_key_functional_normal.9.png"; + + public static String DELETE_ICON = "sym_keyboard_delete_normal.png"; + public static String SHIFT_ICON = "sym_keyboard_shift.png"; + public static String SHIFT_LOCK_ICON = "sym_keyboard_shift_locked.png"; + public static String RETURN_ICON = "sym_keyboard_return_normal.png"; +} + diff --git a/app/src/main/java/com/key/vibekeyboard/utils/SettingUtil.java b/app/src/main/java/com/key/vibekeyboard/utils/SettingUtil.java new file mode 100644 index 0000000..19a830e --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/SettingUtil.java @@ -0,0 +1,32 @@ +package com.key.vibekeyboard.utils; + +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; + +public class SettingUtil { + + public static String getCurrentVersion(Context context) { + try { + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); + return packageInfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return null; + } + } + + public static void shareApp(Context context) { + String appPackageName = context.getPackageName(); + String appName = context.getApplicationInfo().loadLabel(context.getPackageManager()).toString(); + String appPlayStoreLink = "https://play.google.com/store/apps/details?id=" + appPackageName; + + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Check out this app: " + appName); + shareIntent.putExtra(Intent.EXTRA_TEXT, "Download " + appName + " from Google Play: " + appPlayStoreLink); + context.startActivity(Intent.createChooser(shareIntent, "Share " + appName + " via")); + } +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/TaskExecutorUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/TaskExecutorUtils.java new file mode 100644 index 0000000..348a8cd --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/TaskExecutorUtils.java @@ -0,0 +1,21 @@ +package com.key.vibekeyboard.utils; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class TaskExecutorUtils { + + private static ExecutorService executorService; + + public static void executeIO(Runnable task) { + getExecutorService().execute(task); + } + + private static ExecutorService getExecutorService() { + if (executorService == null) { + executorService = Executors.newSingleThreadExecutor(); + } + return executorService; + } + +} diff --git a/app/src/main/java/com/key/vibekeyboard/utils/unzipUtils.java b/app/src/main/java/com/key/vibekeyboard/utils/unzipUtils.java new file mode 100644 index 0000000..8472e48 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/utils/unzipUtils.java @@ -0,0 +1,64 @@ +package com.key.vibekeyboard.utils; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +import com.key.vibekeyboard.R; +import com.key.vibekeyboard.viewmodel.callbacks.UnzipCallback; + +import net.sf.sevenzipjbinding.ArchiveFormat; +import net.sf.sevenzipjbinding.IInArchive; +import net.sf.sevenzipjbinding.SevenZip; +import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream; +import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream; +import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; + +public class unzipUtils { + + public static void unzipFile(Context context, File resource, UnzipCallback callback) throws IOException { + if (!resource.exists()) { + Toast.makeText(context, context.getString(R.string.error_decompression_file_missing), Toast.LENGTH_SHORT).show(); + } else { + String itemFilePath = ""; + + File externalDir = context.getExternalFilesDir(null); + if (externalDir == null) { + externalDir = context.getFilesDir(); + } + + String extractPath = new File(externalDir, "ExtractedFiles").getAbsolutePath(); + + RandomAccessFile accessFile = new RandomAccessFile(resource, "r"); + RandomAccessFileInStream inStream = new RandomAccessFileInStream(accessFile); + IInArchive iInArchive = SevenZip.openInArchive(ArchiveFormat.SEVEN_ZIP, inStream); + ISimpleInArchiveItem[] archiveItems = iInArchive.getSimpleInterface().getArchiveItems(); + + for (ISimpleInArchiveItem simple : archiveItems) { + File file = new File(extractPath, simple.getPath()); + if (!simple.isFolder()) { + RandomAccessFileOutStream outStream = new RandomAccessFileOutStream(new RandomAccessFile(file, "rw")); + simple.extractSlow(outStream); + itemFilePath = file.getPath(); + Log.d("--------", "path: " + itemFilePath); + } else { + boolean mkdirs = file.mkdirs(); + } + } + + inStream.close(); + iInArchive.close(); + + int res = itemFilePath.indexOf("res"); + String substring = itemFilePath.substring(0, res + 3); + Log.d("--------", "substring: " + substring); + + callback.onUnzipCall(true, substring); + } + } + +} diff --git a/app/src/main/java/com/key/vibekeyboard/viewmodel/WallpaperViewModel.java b/app/src/main/java/com/key/vibekeyboard/viewmodel/WallpaperViewModel.java new file mode 100644 index 0000000..f0c6287 --- /dev/null +++ b/app/src/main/java/com/key/vibekeyboard/viewmodel/WallpaperViewModel.java @@ -0,0 +1,22 @@ +package com.key.vibekeyboard.viewmodel; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; + +import com.key.vibekeyboard.data.database.AppDatabase; +import com.key.vibekeyboard.data.database.entity.WallpaperInfo; + +import java.util.List; + +public class WallpaperViewModel extends ViewModel { + private final LiveData> favoriteList; + + public WallpaperViewModel() { + AppDatabase database = AppDatabase.getInstance(); + favoriteList = database.wallpaperInfoDao().getLiveLikeList(true); + } + + public LiveData> getFavoriteList() { + return favoriteList; + } +} diff --git a/app/src/main/java/com/key/vibekeyboard/callback/DownloadCallback.java b/app/src/main/java/com/key/vibekeyboard/viewmodel/callbacks/DownloadCallback.java similarity index 77% rename from app/src/main/java/com/key/vibekeyboard/callback/DownloadCallback.java rename to app/src/main/java/com/key/vibekeyboard/viewmodel/callbacks/DownloadCallback.java index 1e57225..b6eb4c8 100644 --- a/app/src/main/java/com/key/vibekeyboard/callback/DownloadCallback.java +++ b/app/src/main/java/com/key/vibekeyboard/viewmodel/callbacks/DownloadCallback.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.callback; +package com.key.vibekeyboard.viewmodel.callbacks; import java.io.File; import java.io.IOException; diff --git a/app/src/main/java/com/key/vibekeyboard/callback/UnzipCallback.java b/app/src/main/java/com/key/vibekeyboard/viewmodel/callbacks/UnzipCallback.java similarity index 66% rename from app/src/main/java/com/key/vibekeyboard/callback/UnzipCallback.java rename to app/src/main/java/com/key/vibekeyboard/viewmodel/callbacks/UnzipCallback.java index 29b67e2..8e32a9f 100644 --- a/app/src/main/java/com/key/vibekeyboard/callback/UnzipCallback.java +++ b/app/src/main/java/com/key/vibekeyboard/viewmodel/callbacks/UnzipCallback.java @@ -1,4 +1,4 @@ -package com.key.vibekeyboard.callback; +package com.key.vibekeyboard.viewmodel.callbacks; public interface UnzipCallback { diff --git a/app/src/main/res/drawable/permission_select.xml b/app/src/main/res/drawable/permission_select.xml index 5c2e819..9861287 100644 --- a/app/src/main/res/drawable/permission_select.xml +++ b/app/src/main/res/drawable/permission_select.xml @@ -1,7 +1,7 @@ + - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_category.xml b/app/src/main/res/layout/activity_category.xml index 23d2e0f..2ded260 100644 --- a/app/src/main/res/layout/activity_category.xml +++ b/app/src/main/res/layout/activity_category.xml @@ -5,7 +5,7 @@ android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".Activity.CategoryActivity"> + tools:context=".ui.activity.CategoryActivity"> + tools:context=".ui.activity.DownloadActivity"> + tools:context=".ui.activity.MainActivity"> - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index 1cbe121..3ad724f 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -2,6 +2,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:id="@+id/main" android:background="@mipmap/activity_background" android:orientation="vertical"> diff --git a/app/src/main/res/layout/activity_write.xml b/app/src/main/res/layout/activity_write.xml index a87721d..47bbae1 100644 --- a/app/src/main/res/layout/activity_write.xml +++ b/app/src/main/res/layout/activity_write.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/activity_background" - tools:context=".Activity.WriteActivity"> + tools:context=".ui.activity.WriteActivity"> + diff --git a/app/src/main/res/layout/dialog_permission.xml b/app/src/main/res/layout/dialog_permission.xml index 4ca4086..20db4f9 100644 --- a/app/src/main/res/layout/dialog_permission.xml +++ b/app/src/main/res/layout/dialog_permission.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="#00BCD4"> + android:background="@android:color/transparent"> + android:src="@mipmap/ic_launcher_foreground" /> + android:src="@mipmap/ic_launcher_foreground" /> + android:paddingBottom="25dp" + android:background="@color/white"> diff --git a/app/src/main/res/layout/fragment_category.xml b/app/src/main/res/layout/fragment_category.xml index 6772e1e..0651e2a 100644 --- a/app/src/main/res/layout/fragment_category.xml +++ b/app/src/main/res/layout/fragment_category.xml @@ -3,7 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".Fragment.CategoryFragment"> + tools:context=".ui.fragment.CategoryFragment"> + tools:context=".ui.fragment.FavoriteFragment"> + tools:context=".ui.fragment.HomeFragment"> + tools:context=".ui.fragment.SettingFragment"> - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a19079c..848645c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ Mobile Keyboard + The decompression file does not exist Hello blank fragment "No favorite photos in this folder yet." Type a Message diff --git a/app/src/main/res/xml/im.xml b/app/src/main/res/xml/im.xml index 3a66f89..b6ccf6b 100644 --- a/app/src/main/res/xml/im.xml +++ b/app/src/main/res/xml/im.xml @@ -2,7 +2,7 @@ diff --git a/app/src/main/res/xml/view_1.xml b/app/src/main/res/xml/keyboard_lowercase.xml similarity index 94% rename from app/src/main/res/xml/view_1.xml rename to app/src/main/res/xml/keyboard_lowercase.xml index 0ab8f5d..1d1d80e 100644 --- a/app/src/main/res/xml/view_1.xml +++ b/app/src/main/res/xml/keyboard_lowercase.xml @@ -8,35 +8,45 @@ android:codes="113" android:keyEdgeFlags="left" android:keyLabel="q" /> + + + + + + + + + + + + + + + + + + - + android:keyEdgeFlags="left" + android:keyLabel="Shift" /> + + + + + + + @@ -108,7 +133,8 @@ android:isModifier="true" android:isRepeatable="true" android:keyWidth="14.25%" - android:keyEdgeFlags="right" /> + android:keyEdgeFlags="right" + android:keyLabel="" /> + + android:keyLabel="Space" /> - + + + + - @@ -157,10 +161,11 @@ + + android:keyLabel="Space" /> + @@ -17,9 +18,11 @@ + + @@ -31,17 +34,21 @@ + + + + + + @@ -77,18 +86,20 @@ + + - + + android:keyEdgeFlags="right" + android:keyLabel="" /> + android:keyLabel="Space" /> - + + + + + + + + + + + + + + + + + + + + android:keyEdgeFlags="left" + android:keyLabel="Shift" /> + + + + + + + + android:keyEdgeFlags="right" + android:keyLabel="" /> + android:keyLabel="Space" /> - + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2bc8935..e0666b8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.5.1" +agp = "8.8.0" junit = "4.13.2" junitVersion = "1.2.1" espressoCore = "3.6.1" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9060ddd..83c4a82 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Fri Sep 06 10:10:49 CST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://mirrors.huaweicloud.com/repository/toolkit/gradle/gradle-8.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists