diff --git a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java index 23229f2bd..8c0ac7f00 100644 --- a/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java +++ b/app/src/leanback/java/com/fongmi/android/tv/ui/activity/CollectActivity.java @@ -24,7 +24,6 @@ import com.fongmi.android.tv.bean.Collect; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.databinding.ActivityCollectBinding; import com.fongmi.android.tv.model.SiteViewModel; -import com.fongmi.android.tv.ui.custom.CustomScroller; import com.fongmi.android.tv.ui.fragment.CollectFragment; import com.fongmi.android.tv.ui.presenter.CollectPresenter; import com.fongmi.android.tv.utils.ResUtil; diff --git a/app/src/main/res/layout/dialog_tracks.xml b/app/src/leanback/res/layout/dialog_tracks.xml similarity index 100% rename from app/src/main/res/layout/dialog_tracks.xml rename to app/src/leanback/res/layout/dialog_tracks.xml diff --git a/app/src/main/res/layout/dialog_update.xml b/app/src/leanback/res/layout/dialog_update.xml similarity index 100% rename from app/src/main/res/layout/dialog_update.xml rename to app/src/leanback/res/layout/dialog_update.xml diff --git a/app/src/leanback/res/drawable/ic_history.xml b/app/src/main/res/drawable/ic_history.xml similarity index 100% rename from app/src/leanback/res/drawable/ic_history.xml rename to app/src/main/res/drawable/ic_history.xml diff --git a/app/src/mobile/AndroidManifest.xml b/app/src/mobile/AndroidManifest.xml index 7b7b72756..302bf2ddd 100644 --- a/app/src/mobile/AndroidManifest.xml +++ b/app/src/mobile/AndroidManifest.xml @@ -35,7 +35,8 @@ + android:screenOrientation="fullSensor" + android:windowSoftInputMode="adjustPan" /> \ No newline at end of file diff --git a/app/src/mobile/java/com/fongmi/android/tv/impl/ConfigCallback.java b/app/src/mobile/java/com/fongmi/android/tv/impl/ConfigCallback.java new file mode 100644 index 000000000..ea53c9671 --- /dev/null +++ b/app/src/mobile/java/com/fongmi/android/tv/impl/ConfigCallback.java @@ -0,0 +1,6 @@ +package com.fongmi.android.tv.impl; + +public interface ConfigCallback { + + void setConfig(String url); +} diff --git a/app/src/mobile/java/com/fongmi/android/tv/impl/SiteCallback.java b/app/src/mobile/java/com/fongmi/android/tv/impl/SiteCallback.java new file mode 100644 index 000000000..c5a24bbec --- /dev/null +++ b/app/src/mobile/java/com/fongmi/android/tv/impl/SiteCallback.java @@ -0,0 +1,8 @@ +package com.fongmi.android.tv.impl; + +import com.fongmi.android.tv.bean.Site; + +public interface SiteCallback { + + void setSite(Site item); +} diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/SplashActivity.java b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/SplashActivity.java index ecd089b0f..38b899617 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/activity/SplashActivity.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/activity/SplashActivity.java @@ -10,6 +10,7 @@ import androidx.core.splashscreen.SplashScreen; import androidx.viewbinding.ViewBinding; import com.fongmi.android.tv.api.ApiConfig; +import com.fongmi.android.tv.bean.Config; import com.fongmi.android.tv.databinding.ActivitySplashBinding; import com.fongmi.android.tv.net.Callback; import com.fongmi.android.tv.utils.Notify; @@ -32,15 +33,15 @@ public class SplashActivity extends BaseActivity { @Override protected void initView() { - mBinding.title.animate().alpha(1).setDuration(2000).setListener(onAnimationEnd()).start(); + mBinding.title.animate().alpha(1).setDuration(1000).setListener(onAnimationEnd()).start(); } private AnimatorListenerAdapter onAnimationEnd() { return new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mBinding.title.setVisibility(View.GONE); mBinding.info.animate().alpha(1).setDuration(500).start(); + mBinding.title.setVisibility(View.GONE); loadConfig(); } }; @@ -51,6 +52,7 @@ public class SplashActivity extends BaseActivity { @Override public void success() { MainActivity.start(getActivity()); + Config.save(); } @Override diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/SiteAdapter.java b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/SiteAdapter.java index b1ee817d7..d377a5b08 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/SiteAdapter.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/adapter/SiteAdapter.java @@ -1,7 +1,6 @@ package com.fongmi.android.tv.ui.adapter; import android.view.LayoutInflater; -import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; @@ -25,22 +24,20 @@ public class SiteAdapter extends RecyclerView.Adapter { public interface OnClickListener { - void onItemClick(Site item); + void onTextClick(Site item); + + void onSearchClick(Site item); + + void onFilterClick(Site item); } - class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + static class ViewHolder extends RecyclerView.ViewHolder { private final AdapterSiteBinding binding; ViewHolder(@NonNull AdapterSiteBinding binding) { super(binding.getRoot()); this.binding = binding; - binding.getRoot().setOnClickListener(this); - } - - @Override - public void onClick(View view) { - mListener.onItemClick(mItems.get(getLayoutPosition())); } } @@ -59,5 +56,10 @@ public class SiteAdapter extends RecyclerView.Adapter { public void onBindViewHolder(@NonNull ViewHolder holder, int position) { Site item = mItems.get(position); holder.binding.text.setText(item.getActivatedName()); + holder.binding.filter.setImageResource(item.getFilterIcon()); + holder.binding.search.setImageResource(item.getSearchIcon()); + holder.binding.text.setOnClickListener(v -> mListener.onTextClick(item)); + holder.binding.search.setOnClickListener(v -> mListener.onSearchClick(item)); + holder.binding.filter.setOnClickListener(v -> mListener.onFilterClick(item)); } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/ConfigDialog.java b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/ConfigDialog.java index b2f65ad15..14cbae37f 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/ConfigDialog.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/ConfigDialog.java @@ -8,21 +8,22 @@ import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import com.fongmi.android.tv.databinding.DialogConfigBinding; +import com.fongmi.android.tv.impl.ConfigCallback; import com.fongmi.android.tv.utils.Prefers; import com.google.android.material.dialog.MaterialAlertDialogBuilder; public class ConfigDialog { private DialogConfigBinding binding; + private ConfigCallback callback; private AlertDialog dialog; - private Callback callback; public static void show(Fragment fragment) { new ConfigDialog().create(fragment); } public void create(Fragment fragment) { - callback = (Callback) fragment; + callback = (ConfigCallback) fragment; binding = DialogConfigBinding.inflate(LayoutInflater.from(fragment.getContext())); dialog = new MaterialAlertDialogBuilder(fragment.getContext()).setView(binding.getRoot()).create(); initDialog(); @@ -59,9 +60,4 @@ public class ConfigDialog { private void onNegative(View view) { dialog.dismiss(); } - - public interface Callback { - - void setConfig(String url); - } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/SiteDialog.java b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/SiteDialog.java index 3797bff8c..22d7357e8 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/custom/SiteDialog.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/custom/SiteDialog.java @@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment; import com.fongmi.android.tv.api.ApiConfig; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.databinding.DialogSiteBinding; +import com.fongmi.android.tv.impl.SiteCallback; import com.fongmi.android.tv.ui.adapter.SiteAdapter; import com.fongmi.android.tv.utils.ResUtil; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -16,9 +17,9 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; public class SiteDialog implements SiteAdapter.OnClickListener { private DialogSiteBinding binding; + private SiteCallback callback; private SiteAdapter adapter; private AlertDialog dialog; - private Callback callback; public static void show(Fragment fragment) { if (ApiConfig.get().getSites().isEmpty()) return; @@ -26,37 +27,43 @@ public class SiteDialog implements SiteAdapter.OnClickListener { } public void create(Fragment fragment) { - callback = (Callback) fragment; + callback = (SiteCallback) fragment; binding = DialogSiteBinding.inflate(LayoutInflater.from(fragment.getContext())); - dialog = new MaterialAlertDialogBuilder(fragment.getContext()).setView(binding.getRoot()).create(); - initDialog(); - initView(); + dialog = new MaterialAlertDialogBuilder(fragment.getActivity()).setView(binding.getRoot()).create(); + setRecyclerView(); + setDialog(); } - private void initDialog() { + private void setRecyclerView() { + binding.recycler.setHasFixedSize(true); + binding.recycler.setAdapter(adapter = new SiteAdapter(this)); + binding.recycler.addItemDecoration(new SpaceItemDecoration(1, 16)); + binding.recycler.scrollToPosition(ApiConfig.getHomeIndex()); + } + + private void setDialog() { WindowManager.LayoutParams params = dialog.getWindow().getAttributes(); - params.height = (int) (ResUtil.getScreenHeightPx() * 0.6f); + params.height = (int) (ResUtil.getScreenHeightPx() * 0.615f); dialog.getWindow().setAttributes(params); dialog.getWindow().setDimAmount(0); dialog.show(); } - private void initView() { - int position = ApiConfig.get().getSites().indexOf(ApiConfig.get().getHome()); - adapter = new SiteAdapter(this); - binding.recycler.setHasFixedSize(true); - binding.recycler.setAdapter(adapter); - binding.recycler.scrollToPosition(position); - } - @Override - public void onItemClick(Site item) { + public void onTextClick(Site item) { callback.setSite(item); dialog.dismiss(); } - public interface Callback { + @Override + public void onSearchClick(Site item) { + item.setSearchable(!item.isSearchable()).save(); + adapter.notifyDataSetChanged(); + } - void setSite(Site item); + @Override + public void onFilterClick(Site item) { + item.setFilterable(!item.isFilterable()).save(); + adapter.notifyDataSetChanged(); } } diff --git a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java index 98a023452..88990a149 100644 --- a/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java +++ b/app/src/mobile/java/com/fongmi/android/tv/ui/fragment/SettingFragment.java @@ -3,31 +3,41 @@ package com.fongmi.android.tv.ui.fragment; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; +import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.Settings; import android.view.LayoutInflater; +import android.view.View; import android.view.ViewGroup; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; import androidx.core.content.ContextCompat; import androidx.viewbinding.ViewBinding; +import com.fongmi.android.tv.BuildConfig; +import com.fongmi.android.tv.R; import com.fongmi.android.tv.api.ApiConfig; +import com.fongmi.android.tv.bean.Config; import com.fongmi.android.tv.bean.Site; import com.fongmi.android.tv.databinding.FragmentSettingBinding; import com.fongmi.android.tv.event.RefreshEvent; +import com.fongmi.android.tv.impl.ConfigCallback; +import com.fongmi.android.tv.impl.SiteCallback; import com.fongmi.android.tv.net.Callback; import com.fongmi.android.tv.ui.activity.BaseFragment; import com.fongmi.android.tv.ui.custom.ConfigDialog; import com.fongmi.android.tv.ui.custom.SiteDialog; import com.fongmi.android.tv.utils.Notify; import com.fongmi.android.tv.utils.Prefers; +import com.fongmi.android.tv.utils.ResUtil; +import com.fongmi.android.tv.utils.Updater; -public class SettingFragment extends BaseFragment implements ConfigDialog.Callback, SiteDialog.Callback { +public class SettingFragment extends BaseFragment implements ConfigCallback, SiteCallback { private final ActivityResultLauncher launcherString = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> loadConfig()); private final ActivityResultLauncher launcherIntent = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> loadConfig()); @@ -43,12 +53,21 @@ public class SettingFragment extends BaseFragment implements ConfigDialog.Callba protected void initView() { mBinding.url.setText(Prefers.getUrl()); mBinding.home.setText(ApiConfig.getHomeName()); + mBinding.scaleText.setText(ResUtil.getStringArray(R.array.select_scale)[Prefers.getScale()]); + mBinding.renderText.setText(ResUtil.getStringArray(R.array.select_render)[Prefers.getRender()]); + mBinding.qualityText.setText(ResUtil.getStringArray(R.array.select_quality)[Prefers.getQuality()]); + mBinding.versionText.setText(BuildConfig.VERSION_NAME); } @Override protected void initEvent() { - mBinding.site.setOnClickListener(v -> SiteDialog.show(this)); - mBinding.config.setOnClickListener(v -> ConfigDialog.show(this)); + mBinding.site.setOnClickListener(view -> SiteDialog.show(this)); + mBinding.config.setOnClickListener(view -> ConfigDialog.show(this)); + //mBinding.history.setOnClickListener(view -> HistoryDialog.show(this)); + mBinding.version.setOnClickListener(view -> Updater.create(getActivity()).force().start()); + mBinding.quality.setOnClickListener(this::setQuality); + mBinding.render.setOnClickListener(this::setRender); + mBinding.scale.setOnClickListener(this::setScale); } @Override @@ -68,7 +87,7 @@ public class SettingFragment extends BaseFragment implements ConfigDialog.Callba private void checkUrl(String url) { if (url.startsWith("file://") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) { - launcherIntent.launch(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)); + openSetting(); } else if (url.startsWith("file://") && Build.VERSION.SDK_INT < Build.VERSION_CODES.R && ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { launcherString.launch(Manifest.permission.READ_EXTERNAL_STORAGE); } else { @@ -76,24 +95,57 @@ public class SettingFragment extends BaseFragment implements ConfigDialog.Callba } } + @RequiresApi(api = Build.VERSION_CODES.R) + private void openSetting() { + try { + launcherIntent.launch(new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, Uri.parse("package:" + BuildConfig.APPLICATION_ID))); + } catch (Exception e) { + launcherIntent.launch(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)); + } + } + private void loadConfig() { ApiConfig.get().clear().loadConfig(new Callback() { @Override public void success() { - mBinding.home.setText(ApiConfig.getHomeName()); - RefreshEvent.history(); - RefreshEvent.video(); - Notify.dismiss(); + Config.save(); + setSite(0); } @Override public void error(int resId) { - mBinding.home.setText(ApiConfig.getHomeName()); - RefreshEvent.history(); - RefreshEvent.video(); - Notify.dismiss(); - Notify.show(resId); + setSite(resId); } }); } + + private void setSite(int resId) { + mBinding.home.setText(ApiConfig.getHomeName()); + RefreshEvent.history(); + RefreshEvent.video(); + Notify.show(resId); + Notify.dismiss(); + } + + private void setQuality(View view) { + CharSequence[] array = ResUtil.getStringArray(R.array.select_quality); + int index = Prefers.getQuality(); + Prefers.putQuality(index = index == array.length - 1 ? 0 : ++index); + mBinding.qualityText.setText(array[index]); + RefreshEvent.image(); + } + + private void setRender(View view) { + CharSequence[] array = ResUtil.getStringArray(R.array.select_render); + int index = Prefers.getRender(); + Prefers.putRender(index = index == array.length - 1 ? 0 : ++index); + mBinding.renderText.setText(array[index]); + } + + private void setScale(View view) { + CharSequence[] array = ResUtil.getStringArray(R.array.select_scale); + int index = Prefers.getScale(); + Prefers.putScale(index = index == array.length - 1 ? 0 : ++index); + mBinding.scaleText.setText(array[index]); + } } diff --git a/app/src/mobile/res/drawable/selector_text.xml b/app/src/mobile/res/drawable/selector_text.xml deleted file mode 100644 index c6934619f..000000000 --- a/app/src/mobile/res/drawable/selector_text.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/mobile/res/drawable/shape_text_activated.xml b/app/src/mobile/res/drawable/shape_text_activated.xml deleted file mode 100644 index b7afb8cba..000000000 --- a/app/src/mobile/res/drawable/shape_text_activated.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/mobile/res/drawable/shape_text_focused.xml b/app/src/mobile/res/drawable/shape_text_focused.xml deleted file mode 100644 index bad85c441..000000000 --- a/app/src/mobile/res/drawable/shape_text_focused.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/mobile/res/drawable/shape_text_normal.xml b/app/src/mobile/res/drawable/shape_text_normal.xml deleted file mode 100644 index bb15f6d3c..000000000 --- a/app/src/mobile/res/drawable/shape_text_normal.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/mobile/res/layout/adapter_site.xml b/app/src/mobile/res/layout/adapter_site.xml index 94c66ea5b..bda51b136 100644 --- a/app/src/mobile/res/layout/adapter_site.xml +++ b/app/src/mobile/res/layout/adapter_site.xml @@ -3,18 +3,41 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_margin="8dp" - android:background="@drawable/shape_text" - android:foreground="?android:attr/selectableItemBackground"> + android:orientation="horizontal"> + + + + \ No newline at end of file diff --git a/app/src/mobile/res/layout/dialog_site.xml b/app/src/mobile/res/layout/dialog_site.xml index e7a3c349a..82358b6ed 100644 --- a/app/src/mobile/res/layout/dialog_site.xml +++ b/app/src/mobile/res/layout/dialog_site.xml @@ -6,5 +6,5 @@ android:layout_height="wrap_content" android:clipChildren="false" android:clipToPadding="false" - android:padding="8dp" + android:padding="16dp" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> \ No newline at end of file diff --git a/app/src/mobile/res/layout/dialog_tracks.xml b/app/src/mobile/res/layout/dialog_tracks.xml new file mode 100644 index 000000000..ddbe3893a --- /dev/null +++ b/app/src/mobile/res/layout/dialog_tracks.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/mobile/res/layout/dialog_update.xml b/app/src/mobile/res/layout/dialog_update.xml new file mode 100644 index 000000000..6842941c4 --- /dev/null +++ b/app/src/mobile/res/layout/dialog_update.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/mobile/res/layout/fragment_setting.xml b/app/src/mobile/res/layout/fragment_setting.xml index 8fd20bde2..29c85d91b 100644 --- a/app/src/mobile/res/layout/fragment_setting.xml +++ b/app/src/mobile/res/layout/fragment_setting.xml @@ -21,19 +21,123 @@ android:layout_weight="1" android:text="@string/setting_site" android:textColor="@color/white" - android:textSize="18sp" /> + android:textSize="16sp" /> + android:textSize="16sp" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:textSize="16sp" /> + + + + + + + + + android:textSize="16sp" + tools:text="1.2.1" /> \ No newline at end of file