mirror of https://github.com/FongMi/TV.git
parent
7f853b6abc
commit
cdbb2d9590
@ -1,101 +0,0 @@ |
||||
package com.fongmi.android.tv.ui.custom; |
||||
|
||||
import android.content.Context; |
||||
import android.util.AttributeSet; |
||||
import android.view.FocusFinder; |
||||
import android.view.KeyEvent; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.view.ViewParent; |
||||
import android.view.animation.Animation; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.Nullable; |
||||
import androidx.leanback.widget.HorizontalGridView; |
||||
|
||||
import com.fongmi.android.tv.R; |
||||
import com.fongmi.android.tv.utils.KeyUtil; |
||||
import com.fongmi.android.tv.utils.ResUtil; |
||||
|
||||
public class CustomHorizontalGridView extends HorizontalGridView { |
||||
|
||||
private Animation shake; |
||||
|
||||
public CustomHorizontalGridView(@NonNull Context context) { |
||||
super(context); |
||||
} |
||||
|
||||
public CustomHorizontalGridView(@NonNull Context context, @Nullable AttributeSet attrs) { |
||||
super(context, attrs); |
||||
} |
||||
|
||||
public CustomHorizontalGridView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) { |
||||
super(context, attrs, defStyle); |
||||
} |
||||
|
||||
@Override |
||||
protected void initAttributes(@NonNull Context context, @Nullable AttributeSet attrs) { |
||||
super.initAttributes(context, attrs); |
||||
this.shake = isInEditMode() ? null : ResUtil.getAnim(R.anim.shake); |
||||
} |
||||
|
||||
@Override |
||||
public View focusSearch(View focused, int direction) { |
||||
if (focused != null) { |
||||
View found = FocusFinder.getInstance().findNextFocus(this, focused, direction); |
||||
if (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT) { |
||||
if ((found == null || found.getId() != R.id.text) && getScrollState() == SCROLL_STATE_IDLE) { |
||||
focused.clearAnimation(); |
||||
focused.startAnimation(shake); |
||||
return null; |
||||
} |
||||
} |
||||
} |
||||
return super.focusSearch(focused, direction); |
||||
} |
||||
|
||||
@Override |
||||
public boolean dispatchKeyEvent(@NonNull KeyEvent event) { |
||||
return super.dispatchKeyEvent(event) || executeKeyEvent(event); |
||||
} |
||||
|
||||
public boolean executeKeyEvent(@NonNull KeyEvent event) { |
||||
if (KeyUtil.isActionDown(event) && KeyUtil.isLeftKey(event)) return arrowScroll(FOCUS_LEFT); |
||||
if (KeyUtil.isActionDown(event) && KeyUtil.isRightKey(event)) return arrowScroll(FOCUS_RIGHT); |
||||
return false; |
||||
} |
||||
|
||||
public boolean arrowScroll(int direction) { |
||||
View currentFocused = findFocus(); |
||||
if (currentFocused == this) { |
||||
currentFocused = null; |
||||
} else if (currentFocused != null) { |
||||
boolean isChild = false; |
||||
for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent.getParent()) { |
||||
if (parent == this) { |
||||
isChild = true; |
||||
break; |
||||
} |
||||
} |
||||
if (!isChild) { |
||||
currentFocused = null; |
||||
} |
||||
} |
||||
boolean handled = false; |
||||
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction); |
||||
if (nextFocused == null || nextFocused == currentFocused) { |
||||
if (direction == FOCUS_LEFT || direction == FOCUS_RIGHT) { |
||||
shake(currentFocused); |
||||
handled = true; |
||||
} |
||||
} |
||||
return handled; |
||||
} |
||||
|
||||
private void shake(View currentFocused) { |
||||
if (currentFocused != null && getScrollState() == SCROLL_STATE_IDLE) { |
||||
currentFocused.clearAnimation(); |
||||
currentFocused.startAnimation(shake); |
||||
} |
||||
} |
||||
} |
||||
@ -1,159 +1,24 @@ |
||||
package com.fongmi.android.tv.ui.custom; |
||||
|
||||
import android.content.Context; |
||||
import android.graphics.Rect; |
||||
import android.util.AttributeSet; |
||||
import android.view.FocusFinder; |
||||
import android.view.KeyEvent; |
||||
import android.view.SoundEffectConstants; |
||||
import android.view.View; |
||||
import android.view.ViewGroup; |
||||
import android.view.ViewParent; |
||||
import android.view.animation.Animation; |
||||
import android.widget.TextView; |
||||
|
||||
import androidx.annotation.NonNull; |
||||
import androidx.annotation.Nullable; |
||||
import androidx.viewpager.widget.ViewPager; |
||||
|
||||
import com.fongmi.android.tv.R; |
||||
import com.fongmi.android.tv.utils.KeyUtil; |
||||
import com.fongmi.android.tv.utils.ResUtil; |
||||
|
||||
public class CustomViewPager extends ViewPager { |
||||
|
||||
private Animation shake; |
||||
private Rect rect; |
||||
|
||||
public CustomViewPager(@NonNull Context context) { |
||||
super(context); |
||||
} |
||||
|
||||
public CustomViewPager(@NonNull Context context, @Nullable AttributeSet attrs) { |
||||
super(context, attrs); |
||||
init(); |
||||
} |
||||
|
||||
private void init() { |
||||
this.rect = new Rect(); |
||||
this.shake = ResUtil.getAnim(R.anim.shake); |
||||
} |
||||
|
||||
@Override |
||||
public void setCurrentItem(int item) { |
||||
super.setCurrentItem(item, false); |
||||
} |
||||
|
||||
@Override |
||||
public boolean executeKeyEvent(@NonNull KeyEvent event) { |
||||
if (findFocus() instanceof TextView) return false; |
||||
if (KeyUtil.isActionDown(event) && KeyUtil.isLeftKey(event)) return arrowScroll(FOCUS_LEFT); |
||||
if (KeyUtil.isActionDown(event) && KeyUtil.isRightKey(event)) return arrowScroll(FOCUS_RIGHT); |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public boolean arrowScroll(int direction) { |
||||
boolean handled = false; |
||||
View currentFocused = findFocus(); |
||||
if (currentFocused == this) { |
||||
currentFocused = null; |
||||
} else if (currentFocused != null) { |
||||
boolean isChild = false; |
||||
for (ViewParent parent = currentFocused.getParent(); parent instanceof ViewGroup; parent = parent.getParent()) { |
||||
if (parent == this) { |
||||
isChild = true; |
||||
break; |
||||
} |
||||
} |
||||
if (!isChild) { |
||||
currentFocused = null; |
||||
} |
||||
} |
||||
View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction); |
||||
if (nextFocused != null && nextFocused != currentFocused) { |
||||
if (direction == View.FOCUS_LEFT) { |
||||
int nextLeft = getChildRectInPagerCoordinates(rect, nextFocused).left; |
||||
int currLeft = getChildRectInPagerCoordinates(rect, currentFocused).left; |
||||
if (currentFocused != null && nextLeft >= currLeft) { |
||||
handled = pageLeft(); |
||||
} else { |
||||
handled = nextFocused.requestFocus(); |
||||
} |
||||
} else if (direction == View.FOCUS_RIGHT) { |
||||
int nextLeft = getChildRectInPagerCoordinates(rect, nextFocused).left; |
||||
int currLeft = getChildRectInPagerCoordinates(rect, currentFocused).left; |
||||
if (currentFocused != null && nextLeft <= currLeft) { |
||||
handled = pageRight(); |
||||
} else { |
||||
handled = nextFocused.requestFocus(); |
||||
} |
||||
} |
||||
} else if (direction == FOCUS_LEFT) { |
||||
if (getCurrentItem() == 0) { |
||||
shake(currentFocused); |
||||
handled = true; |
||||
} else { |
||||
handled = pageLeft(); |
||||
} |
||||
} else if (direction == FOCUS_RIGHT) { |
||||
if (getAdapter() != null && getCurrentItem() == getAdapter().getCount() - 1) { |
||||
shake(currentFocused); |
||||
handled = true; |
||||
} else { |
||||
handled = pageRight(); |
||||
} |
||||
} |
||||
if (handled) { |
||||
playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); |
||||
} |
||||
return handled; |
||||
} |
||||
|
||||
private Rect getChildRectInPagerCoordinates(Rect outRect, View child) { |
||||
if (outRect == null) { |
||||
outRect = new Rect(); |
||||
} |
||||
if (child == null) { |
||||
outRect.set(0, 0, 0, 0); |
||||
return outRect; |
||||
} |
||||
outRect.left = child.getLeft(); |
||||
outRect.right = child.getRight(); |
||||
outRect.top = child.getTop(); |
||||
outRect.bottom = child.getBottom(); |
||||
ViewParent parent = child.getParent(); |
||||
while (parent instanceof ViewGroup && parent != this) { |
||||
ViewGroup group = (ViewGroup) parent; |
||||
outRect.left += group.getLeft(); |
||||
outRect.right += group.getRight(); |
||||
outRect.top += group.getTop(); |
||||
outRect.bottom += group.getBottom(); |
||||
parent = group.getParent(); |
||||
} |
||||
return outRect; |
||||
} |
||||
|
||||
private boolean pageLeft() { |
||||
if (getCurrentItem() > 0) { |
||||
setCurrentItem(getCurrentItem() - 1, false); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private boolean pageRight() { |
||||
if (getAdapter() != null && getCurrentItem() < getAdapter().getCount() - 1) { |
||||
setCurrentItem(getCurrentItem() + 1, false); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
private void shake(View currentFocused) { |
||||
if (currentFocused != null) { |
||||
currentFocused.clearAnimation(); |
||||
currentFocused.startAnimation(shake); |
||||
} |
||||
} |
||||
} |
||||
|
||||
Loading…
Reference in new issue