Add home site change

pull/102/head
FongMi 4 years ago
parent d147432400
commit f8a8a12bce
  1. 6
      app/src/leanback/java/com/fongmi/android/tv/impl/ConfigCallback.java
  2. 4
      app/src/leanback/java/com/fongmi/android/tv/impl/SiteCallback.java
  3. 28
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/HomeActivity.java
  4. 5
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/SettingActivity.java
  5. 36
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomKeyDown.java
  6. 81
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/CustomTitleView.java
  7. 6
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/ConfigDialog.java
  8. 6
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/HistoryDialog.java
  9. 21
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/SiteDialog.java
  10. 9
      app/src/leanback/res/layout/activity_home.xml
  11. 4
      app/src/main/java/com/fongmi/android/tv/api/ApiConfig.java
  12. 12
      app/src/main/java/com/fongmi/android/tv/bean/Result.java
  13. 2
      app/src/main/java/com/fongmi/android/tv/model/SiteViewModel.java
  14. 21
      app/src/main/java/com/fongmi/android/tv/utils/Utils.java

@ -0,0 +1,6 @@
package com.fongmi.android.tv.impl;
public interface ConfigCallback {
void setConfig(String url);
}

@ -2,9 +2,7 @@ package com.fongmi.android.tv.impl;
import com.fongmi.android.tv.bean.Site;
public interface SettingCallback {
void setConfig(String url);
public interface SiteCallback {
void setSite(Site item);
}

@ -25,13 +25,13 @@ import com.fongmi.android.tv.bean.Vod;
import com.fongmi.android.tv.databinding.ActivityHomeBinding;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.event.ServerEvent;
import com.fongmi.android.tv.impl.SiteCallback;
import com.fongmi.android.tv.model.SiteViewModel;
import com.fongmi.android.tv.player.Players;
import com.fongmi.android.tv.server.Server;
import com.fongmi.android.tv.ui.custom.CustomRowPresenter;
import com.fongmi.android.tv.ui.custom.CustomSelector;
import com.fongmi.android.tv.ui.custom.CustomTitleView;
import com.fongmi.android.tv.ui.custom.dialog.SiteDialog;
import com.fongmi.android.tv.ui.presenter.FuncPresenter;
import com.fongmi.android.tv.ui.presenter.HeaderPresenter;
import com.fongmi.android.tv.ui.presenter.HistoryPresenter;
@ -49,7 +49,7 @@ import org.greenrobot.eventbus.ThreadMode;
import java.util.List;
public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, SiteCallback, VodPresenter.OnClickListener, FuncPresenter.OnClickListener, HistoryPresenter.OnClickListener {
public class HomeActivity extends BaseActivity implements CustomTitleView.Listener, VodPresenter.OnClickListener, FuncPresenter.OnClickListener, HistoryPresenter.OnClickListener {
private ActivityHomeBinding mBinding;
private ArrayObjectAdapter mAdapter;
@ -112,7 +112,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
mSiteViewModel = new ViewModelProvider(this).get(SiteViewModel.class);
mSiteViewModel.result.observe(this, result -> {
mAdapter.remove("progress");
if (result != null) addVideo(result);
addVideo(result);
});
}
@ -123,7 +123,10 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
}
private void getVideo() {
mSiteViewModel.getResult().setValue(Result.empty());
if (mAdapter.size() > getRecommendIndex()) mAdapter.removeItems(getRecommendIndex(), mAdapter.size() - getRecommendIndex());
if (ApiConfig.get().getHome().getName().isEmpty()) mBinding.title.setText(R.string.app_name);
else mBinding.title.setText(ApiConfig.getHomeName());
if (ApiConfig.get().getHome().getKey().isEmpty()) return;
mSiteViewModel.homeContent();
mAdapter.add("progress");
@ -217,23 +220,14 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
}
@Override
public void showSite() {
public void showDialog() {
SiteDialog.show(this);
}
@Override
public void setSite(Site item) {
}
@Override
public void nextSite() {
}
@Override
public void prevSite() {
ApiConfig.get().setHome(item);
getVideo();
}
@Subscribe(threadMode = ThreadMode.MAIN)
@ -266,7 +260,7 @@ public class HomeActivity extends BaseActivity implements CustomTitleView.Listen
mHistoryPresenter.setDelete(false);
mHistoryAdapter.notifyArrayItemRangeChanged(0, mHistoryAdapter.size());
} else if (mBinding.recycler.getSelectedPosition() != 0) {
mBinding.recycler.smoothScrollToPosition(0);
mBinding.recycler.scrollToPosition(0);
} else if (!mConfirmExit) {
mConfirmExit = true;
Notify.show(R.string.app_exit);

@ -23,7 +23,8 @@ import com.fongmi.android.tv.bean.Config;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.databinding.ActivitySettingBinding;
import com.fongmi.android.tv.event.RefreshEvent;
import com.fongmi.android.tv.impl.SettingCallback;
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.custom.dialog.ConfigDialog;
import com.fongmi.android.tv.ui.custom.dialog.HistoryDialog;
@ -32,7 +33,7 @@ import com.fongmi.android.tv.utils.Notify;
import com.fongmi.android.tv.utils.Prefers;
import com.fongmi.android.tv.utils.ResUtil;
public class SettingActivity extends BaseActivity implements SettingCallback {
public class SettingActivity extends BaseActivity implements ConfigCallback, SiteCallback {
private final ActivityResultLauncher<String> launcherString = registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> loadConfig());
private final ActivityResultLauncher<Intent> launcherIntent = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> loadConfig());

@ -2,6 +2,8 @@ package com.fongmi.android.tv.ui.custom;
import android.view.KeyEvent;
import com.fongmi.android.tv.utils.Utils;
public class CustomKeyDown {
private final Listener mListener;
@ -16,15 +18,13 @@ public class CustomKeyDown {
}
public boolean onKeyDown(KeyEvent event) {
boolean isLeft = isLeftKey(event);
boolean isRight = isRightKey(event);
if (event.getAction() == KeyEvent.ACTION_DOWN && (isLeft || isRight)) {
mListener.onSeeking(isRight ? addTime() : subTime());
} else if (event.getAction() == KeyEvent.ACTION_UP && (isLeft || isRight)) {
if (event.getAction() == KeyEvent.ACTION_DOWN && (Utils.isLeftKey(event) || Utils.isRightKey(event))) {
mListener.onSeeking(Utils.isRightKey(event) ? addTime() : subTime());
} else if (event.getAction() == KeyEvent.ACTION_UP && (Utils.isLeftKey(event) || Utils.isRightKey(event))) {
mListener.onSeekTo(mHoldTime);
} else if (event.getAction() == KeyEvent.ACTION_UP && isDownKey(event)) {
} else if (event.getAction() == KeyEvent.ACTION_UP && Utils.isDownKey(event)) {
mListener.onKeyDown();
} else if (event.getAction() == KeyEvent.ACTION_UP && isEnterKey(event)) {
} else if (event.getAction() == KeyEvent.ACTION_UP && Utils.isEnterKey(event)) {
mListener.onKeyCenter();
}
return true;
@ -43,27 +43,7 @@ public class CustomKeyDown {
}
public boolean hasEvent(KeyEvent event) {
return isEnterKey(event) || isUpKey(event) || isDownKey(event) || isLeftKey(event) || isRightKey(event);
}
private boolean isEnterKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER || event.getKeyCode() == KeyEvent.KEYCODE_ENTER || event.getKeyCode() == KeyEvent.KEYCODE_SPACE || event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER;
}
private boolean isUpKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP || event.getKeyCode() == KeyEvent.KEYCODE_CHANNEL_UP || event.getKeyCode() == KeyEvent.KEYCODE_PAGE_UP || event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PREVIOUS;
}
private boolean isDownKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_CHANNEL_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_PAGE_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_NEXT;
}
private boolean isLeftKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT;
}
private boolean isRightKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT;
return Utils.isEnterKey(event) || Utils.isUpKey(event) || Utils.isDownKey(event) || Utils.isLeftKey(event) || Utils.isRightKey(event);
}
public interface Listener {

@ -0,0 +1,81 @@
package com.fongmi.android.tv.ui.custom;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.animation.Animation;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatTextView;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.api.ApiConfig;
import com.fongmi.android.tv.bean.Site;
import com.fongmi.android.tv.impl.SiteCallback;
import com.fongmi.android.tv.utils.ResUtil;
import com.fongmi.android.tv.utils.Utils;
import java.util.List;
public class CustomTitleView extends AppCompatTextView {
private Listener mListener;
private Animation mFlicker;
public CustomTitleView(@NonNull Context context) {
super(context);
}
public CustomTitleView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mFlicker = ResUtil.getAnim(R.anim.flicker);
}
public void setListener(Listener listener) {
this.mListener = listener;
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) startAnimation(mFlicker);
else clearAnimation();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (ApiConfig.get().getSites().isEmpty()) return false;
if (hasEvent(event)) return onKeyDown(event);
else return super.dispatchKeyEvent(event);
}
private boolean onKeyDown(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && Utils.isEnterKey(event)) {
mListener.showDialog();
} else if (event.getAction() == KeyEvent.ACTION_DOWN && Utils.isLeftKey(event)) {
mListener.setSite(getSite(true));
} else if (event.getAction() == KeyEvent.ACTION_DOWN && Utils.isRightKey(event)) {
mListener.setSite(getSite(false));
}
return true;
}
private Site getSite(boolean next) {
List<Site> items = ApiConfig.get().getSites();
int position = ApiConfig.getHomeIndex();
if (next) position = position > 0 ? --position : items.size() - 1;
else position = position < items.size() - 1 ? ++position : 0;
return items.get(position);
}
private boolean hasEvent(KeyEvent event) {
return Utils.isEnterKey(event) || Utils.isLeftKey(event) || Utils.isRightKey(event);
}
public interface Listener extends SiteCallback {
void showDialog();
}
}

@ -10,9 +10,9 @@ import android.view.inputmethod.EditorInfo;
import androidx.appcompat.app.AlertDialog;
import com.fongmi.android.tv.R;
import com.fongmi.android.tv.impl.SettingCallback;
import com.fongmi.android.tv.databinding.DialogConfigBinding;
import com.fongmi.android.tv.event.ServerEvent;
import com.fongmi.android.tv.impl.ConfigCallback;
import com.fongmi.android.tv.server.Server;
import com.fongmi.android.tv.utils.Prefers;
import com.fongmi.android.tv.utils.QRCode;
@ -26,7 +26,7 @@ import org.greenrobot.eventbus.ThreadMode;
public class ConfigDialog implements DialogInterface.OnDismissListener {
private DialogConfigBinding binding;
private SettingCallback callback;
private ConfigCallback callback;
private AlertDialog dialog;
public static void show(Activity activity) {
@ -34,7 +34,7 @@ public class ConfigDialog implements DialogInterface.OnDismissListener {
}
public void create(Activity activity) {
callback = (SettingCallback) activity;
callback = (ConfigCallback) activity;
binding = DialogConfigBinding.inflate(LayoutInflater.from(activity));
dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create();
EventBus.getDefault().register(this);

@ -7,9 +7,9 @@ import android.view.WindowManager;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.fongmi.android.tv.impl.SettingCallback;
import com.fongmi.android.tv.bean.Config;
import com.fongmi.android.tv.databinding.DialogHistoryBinding;
import com.fongmi.android.tv.impl.ConfigCallback;
import com.fongmi.android.tv.ui.adapter.ConfigAdapter;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@ -17,7 +17,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class HistoryDialog implements ConfigAdapter.OnClickListener {
private DialogHistoryBinding binding;
private SettingCallback callback;
private ConfigCallback callback;
private ConfigAdapter adapter;
private AlertDialog dialog;
@ -26,7 +26,7 @@ public class HistoryDialog implements ConfigAdapter.OnClickListener {
}
public void create(Activity activity) {
callback = (SettingCallback) activity;
callback = (ConfigCallback) activity;
binding = DialogHistoryBinding.inflate(LayoutInflater.from(activity));
dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create();
setRecyclerView();

@ -1,6 +1,6 @@
package com.fongmi.android.tv.ui.custom.dialog;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.WindowManager;
@ -8,10 +8,10 @@ import androidx.appcompat.app.AlertDialog;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.ItemBridgeAdapter;
import com.fongmi.android.tv.impl.SettingCallback;
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.presenter.SitePresenter;
import com.fongmi.android.tv.utils.ResUtil;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@ -20,29 +20,28 @@ public class SiteDialog implements SitePresenter.OnClickListener {
private ArrayObjectAdapter adapter;
private DialogSiteBinding binding;
private SettingCallback callback;
private SiteCallback callback;
private AlertDialog dialog;
public static void show(Activity activity) {
public static void show(Context context) {
if (ApiConfig.get().getSites().isEmpty()) return;
new SiteDialog().create(activity);
new SiteDialog().create(context);
}
public void create(Activity activity) {
callback = (SettingCallback) activity;
binding = DialogSiteBinding.inflate(LayoutInflater.from(activity));
dialog = new MaterialAlertDialogBuilder(activity).setView(binding.getRoot()).create();
public void create(Context context) {
callback = (SiteCallback) context;
binding = DialogSiteBinding.inflate(LayoutInflater.from(context));
dialog = new MaterialAlertDialogBuilder(context).setView(binding.getRoot()).create();
setRecyclerView();
setDialog();
}
private void setRecyclerView() {
int position = ApiConfig.get().getSites().indexOf(ApiConfig.get().getHome());
adapter = new ArrayObjectAdapter(new SitePresenter(this));
adapter.addAll(0, ApiConfig.get().getSites());
binding.recycler.setVerticalSpacing(ResUtil.dp2px(16));
binding.recycler.setAdapter(new ItemBridgeAdapter(adapter));
binding.recycler.scrollToPosition(position);
binding.recycler.scrollToPosition(ApiConfig.getHomeIndex());
}
private void setDialog() {

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -15,11 +16,13 @@
android:paddingEnd="24dp"
android:paddingBottom="8dp">
<TextView
<com.fongmi.android.tv.ui.custom.CustomTitleView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="24sp" />
@ -45,6 +48,8 @@
android:paddingStart="24dp"
android:paddingTop="8dp"
android:paddingEnd="24dp"
android:paddingBottom="24dp" />
android:paddingBottom="24dp"
app:focusOutEnd="true"
app:focusOutFront="true" />
</LinearLayout>

@ -54,6 +54,10 @@ public class ApiConfig {
return get().getHome().getName();
}
public static int getHomeIndex() {
return get().getSites().indexOf(get().getHome());
}
public static String getSiteName(String key) {
return get().getSite(key).getName();
}

@ -64,9 +64,9 @@ public class Result {
Type type = new TypeToken<LinkedHashMap<String, List<Filter>>>() {}.getType();
Gson gson = new GsonBuilder().registerTypeAdapter(type, new FiltersAdapter()).create();
Result result = gson.fromJson(str, Result.class);
return result == null ? new Result() : result;
return result == null ? empty() : result;
} catch (Exception e) {
return new Result();
return empty();
}
}
@ -74,7 +74,7 @@ public class Result {
try {
return new Persister().read(Result.class, str);
} catch (Exception e) {
return new Result();
return empty();
}
}
@ -86,10 +86,14 @@ public class Result {
try {
return new Gson().fromJson(str, Result.class);
} catch (Exception e) {
return new Result();
return empty();
}
}
public static Result empty() {
return new Result();
}
public List<Class> getTypes() {
return types == null ? Collections.emptyList() : types;
}

@ -189,7 +189,7 @@ public class SiteViewModel extends ViewModel {
} catch (Exception e) {
e.printStackTrace();
if (e instanceof InterruptedException) return;
if (!Thread.interrupted()) result.postValue(new Result());
if (!Thread.interrupted()) result.postValue(Result.empty());
}
});
}

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.os.IBinder;
import android.util.Base64;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
@ -15,6 +16,26 @@ public class Utils {
private static final Pattern SNIFFER = Pattern.compile("http((?!http).){20,}?\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg)\\?.*|http((?!http).){20,}\\.(m3u8|mp4|flv|avi|mkv|rm|wmv|mpg)|http((?!http).){20,}?\\/m3u8\\?pt=m3u8.*|http((?!http).)*?default\\.ixigua\\.com\\/.*|http((?!http).)*?cdn-tos[^\\?]*|http((?!http).)*?\\/obj\\/tos[^\\?]*|http.*?\\/player\\/m3u8play\\.php\\?url=.*|http.*?\\/player\\/.*?[pP]lay\\.php\\?url=.*|http.*?\\/playlist\\/m3u8\\/\\?vid=.*|http.*?\\.php\\?type=m3u8&.*|http.*?\\/download.aspx\\?.*|http.*?\\/api\\/up_api.php\\?.*|https.*?\\.66yk\\.cn.*|http((?!http).)*?netease\\.com\\/file\\/.*");
public static boolean isEnterKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER || event.getKeyCode() == KeyEvent.KEYCODE_ENTER || event.getKeyCode() == KeyEvent.KEYCODE_SPACE || event.getKeyCode() == KeyEvent.KEYCODE_NUMPAD_ENTER;
}
public static boolean isUpKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP || event.getKeyCode() == KeyEvent.KEYCODE_CHANNEL_UP || event.getKeyCode() == KeyEvent.KEYCODE_PAGE_UP || event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PREVIOUS;
}
public static boolean isDownKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_CHANNEL_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_PAGE_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_NEXT;
}
public static boolean isLeftKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_LEFT;
}
public static boolean isRightKey(KeyEvent event) {
return event.getKeyCode() == KeyEvent.KEYCODE_DPAD_RIGHT;
}
public static void hideSystemUI(Activity activity) {
int flags = View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
activity.getWindow().getDecorView().setSystemUiVisibility(flags);

Loading…
Cancel
Save