pull/149/head
FongMi 3 years ago
parent e0b0a66720
commit 4ca431cf62
  1. 10
      app/src/leanback/java/com/fongmi/android/tv/ui/activity/VideoActivity.java
  2. 10
      app/src/leanback/java/com/fongmi/android/tv/ui/custom/dialog/DescDialog.java
  3. 5
      app/src/leanback/res/layout/activity_video.xml
  4. 199
      app/src/main/java/com/fongmi/android/tv/ui/custom/CustomMovement.java

@ -10,7 +10,6 @@ import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.KeyEvent;
import android.view.View;
@ -63,6 +62,7 @@ import com.fongmi.android.tv.player.danmu.Parser;
import com.fongmi.android.tv.ui.adapter.QualityAdapter;
import com.fongmi.android.tv.ui.base.BaseActivity;
import com.fongmi.android.tv.ui.custom.CustomKeyDownVod;
import com.fongmi.android.tv.ui.custom.CustomMovement;
import com.fongmi.android.tv.ui.custom.dialog.DescDialog;
import com.fongmi.android.tv.ui.custom.dialog.TrackDialog;
import com.fongmi.android.tv.ui.presenter.ArrayPresenter;
@ -524,11 +524,11 @@ public class VideoActivity extends BaseActivity implements CustomKeyDownVod.List
}
private void setText(TextView view, int resId, String text) {
view.setTag(text);
view.setLinkTextColor(MDColor.YELLOW_500);
view.setVisibility(text.isEmpty() ? View.GONE : View.VISIBLE);
view.setText(getSpan(resId, text), TextView.BufferType.SPANNABLE);
if (Sniffer.CLICKER.matcher(text).find()) view.setMovementMethod(LinkMovementMethod.getInstance());
view.setVisibility(text.isEmpty() ? View.GONE : View.VISIBLE);
view.setLinkTextColor(MDColor.YELLOW_500);
CustomMovement.bind(view);
view.setTag(text);
}
private SpannableString getSpan(int resId, String text) {

@ -1,15 +1,13 @@
package com.fongmi.android.tv.ui.custom.dialog;
import android.app.Activity;
import android.text.Editable;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.LayoutInflater;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import com.fongmi.android.tv.databinding.DialogDescBinding;
import com.fongmi.android.tv.ui.custom.CustomMovement;
import com.github.bassaer.library.MDColor;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@ -28,10 +26,8 @@ public class DescDialog {
}
private void initView(TextView view, CharSequence desc) {
view.setLinkTextColor(MDColor.BLUE_500);
view.setText(desc, TextView.BufferType.SPANNABLE);
Editable e = new Editable.Factory().newEditable(view.getText());
ClickableSpan[] spans = e.getSpans(0, e.length(), ClickableSpan.class);
if (spans.length > 0) view.setMovementMethod(LinkMovementMethod.getInstance());
view.setLinkTextColor(MDColor.BLUE_500);
CustomMovement.bind(view);
}
}

@ -18,6 +18,7 @@
android:focusableInTouchMode="true"
android:foreground="@drawable/selector_video"
android:nextFocusLeft="@id/video"
android:nextFocusRight="@id/desc"
android:nextFocusUp="@id/video"
android:nextFocusDown="@id/flag">
@ -146,7 +147,7 @@
<TextView
android:id="@+id/director"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/row1"
android:layout_alignStart="@+id/name"
@ -159,7 +160,7 @@
<TextView
android:id="@+id/actor"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/director"
android:layout_alignStart="@+id/name"

@ -0,0 +1,199 @@
package com.fongmi.android.tv.ui.custom;
import android.text.Editable;
import android.text.Layout;
import android.text.NoCopySpan;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ClickableSpan;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class CustomMovement extends ScrollingMovementMethod {
private static final int CLICK = 1;
private static final int UP = 2;
private static final int DOWN = 3;
private static final Object FROM_BELOW = new NoCopySpan.Concrete();
private static CustomMovement sInstance;
public static CustomMovement getInstance() {
if (sInstance == null) sInstance = new CustomMovement();
return sInstance;
}
public static void bind(TextView view) {
Editable e = new Editable.Factory().newEditable(view.getText());
ClickableSpan[] spans = e.getSpans(0, e.length(), ClickableSpan.class);
view.setMovementMethod(spans.length > 0 ? CustomMovement.getInstance() : null);
}
@Override
public boolean canSelectArbitrarily() {
return true;
}
@Override
protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode, int movementMetaState, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0 && action(CLICK, widget, buffer)) {
return true;
}
}
break;
}
return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
}
private void findFocus(TextView widget, int direction) {
View view = widget.focusSearch(direction);
if (view != null) view.requestFocus();
}
@Override
protected boolean up(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) return true;
findFocus(widget, View.FOCUS_UP);
return super.up(widget, buffer);
}
@Override
protected boolean down(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) return true;
findFocus(widget, View.FOCUS_DOWN);
return super.down(widget, buffer);
}
@Override
protected boolean left(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) return true;
findFocus(widget, View.FOCUS_LEFT);
return super.left(widget, buffer);
}
@Override
protected boolean right(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) return true;
findFocus(widget, View.FOCUS_RIGHT);
return super.right(widget, buffer);
}
private boolean action(int what, TextView widget, Spannable buffer) {
Layout layout = widget.getLayout();
int padding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom();
int areaTop = widget.getScrollY();
int areaBot = areaTop + widget.getHeight() - padding;
int lineTop = layout.getLineForVertical(areaTop);
int lineBot = layout.getLineForVertical(areaBot);
int first = layout.getLineStart(lineTop);
int last = layout.getLineEnd(lineBot);
ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);
int a = Selection.getSelectionStart(buffer);
int b = Selection.getSelectionEnd(buffer);
int selStart = Math.min(a, b);
int selEnd = Math.max(a, b);
if (selStart < 0) {
if (buffer.getSpanStart(FROM_BELOW) >= 0) {
selStart = selEnd = buffer.length();
}
}
if (selStart > last) selStart = selEnd = Integer.MAX_VALUE;
if (selEnd < first) selStart = selEnd = -1;
switch (what) {
case CLICK:
if (selStart == selEnd) return false;
ClickableSpan[] links = buffer.getSpans(selStart, selEnd, ClickableSpan.class);
if (links.length != 1) return false;
ClickableSpan link = links[0];
link.onClick(widget);
break;
case UP:
int bestStart, bestEnd;
bestStart = -1;
bestEnd = -1;
for (ClickableSpan candidate : candidates) {
int end = buffer.getSpanEnd(candidate);
if (end < selEnd || selStart == selEnd) {
if (end > bestEnd) {
bestStart = buffer.getSpanStart(candidate);
bestEnd = end;
}
}
}
if (bestStart >= 0) {
Selection.setSelection(buffer, bestEnd, bestStart);
return true;
}
break;
case DOWN:
bestStart = Integer.MAX_VALUE;
bestEnd = Integer.MAX_VALUE;
for (ClickableSpan candidate : candidates) {
int start = buffer.getSpanStart(candidate);
if (start > selStart || selStart == selEnd) {
if (start < bestStart) {
bestStart = start;
bestEnd = buffer.getSpanEnd(candidate);
}
}
}
if (bestEnd < Integer.MAX_VALUE) {
Selection.setSelection(buffer, bestStart, bestEnd);
return true;
}
break;
}
return false;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
if (links.length != 0) {
ClickableSpan link = links[0];
if (action == MotionEvent.ACTION_UP) {
link.onClick(widget);
} else {
Selection.setSelection(buffer, buffer.getSpanStart(link), buffer.getSpanEnd(link));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
@Override
public void initialize(TextView widget, Spannable text) {
Selection.removeSelection(text);
text.removeSpan(FROM_BELOW);
}
@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
}
Loading…
Cancel
Save