From 79e114899c2e3a8935272cea60e54822ff156aee Mon Sep 17 00:00:00 2001 From: FongMi Date: Tue, 5 Jul 2022 14:59:46 +0800 Subject: [PATCH] Improve UX --- .../fongmi/bear/ui/activity/HomeActivity.java | 2 +- .../fongmi/bear/ui/activity/VodActivity.java | 5 +- .../ui/custom/CustomHorizontalGridView.java | 8 +- .../ui/custom/CustomVerticalGridView.java | 75 +++++++++++++++++++ .../bear/ui/custom/CustomViewPager.java | 28 +++---- .../fongmi/bear/ui/fragment/VodFragment.java | 8 ++ app/src/main/res/layout/activity_detail.xml | 27 ++----- app/src/main/res/layout/activity_vod.xml | 1 - app/src/main/res/layout/adapter_item.xml | 2 +- app/src/main/res/layout/fragment_vod.xml | 4 +- 10 files changed, 115 insertions(+), 45 deletions(-) create mode 100644 app/src/main/java/com/fongmi/bear/ui/custom/CustomVerticalGridView.java diff --git a/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java b/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java index 395f3259a..c4d1169ba 100644 --- a/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java +++ b/app/src/main/java/com/fongmi/bear/ui/activity/HomeActivity.java @@ -107,7 +107,7 @@ public class HomeActivity extends BaseActivity implements VodPresenter.OnClickLi switch (item.getResId()) { case R.string.home_vod: Result result = mSiteViewModel.getResult().getValue(); - if (result != null) VodActivity.start(this, result); + VodActivity.start(this, result); break; case R.string.home_setting: SettingActivity.start(this); diff --git a/app/src/main/java/com/fongmi/bear/ui/activity/VodActivity.java b/app/src/main/java/com/fongmi/bear/ui/activity/VodActivity.java index f35de39d5..8940e4325 100644 --- a/app/src/main/java/com/fongmi/bear/ui/activity/VodActivity.java +++ b/app/src/main/java/com/fongmi/bear/ui/activity/VodActivity.java @@ -11,8 +11,6 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.leanback.widget.ArrayObjectAdapter; -import androidx.leanback.widget.FocusHighlight; -import androidx.leanback.widget.FocusHighlightHelper; import androidx.leanback.widget.ItemBridgeAdapter; import androidx.leanback.widget.OnChildViewHolderSelectedListener; import androidx.recyclerview.widget.RecyclerView; @@ -37,6 +35,7 @@ public class VodActivity extends BaseActivity { } public static void start(Activity activity, Result result) { + if (result == null || result.getTypes().isEmpty()) return; Intent intent = new Intent(activity, VodActivity.class); intent.putExtra("result", result.toString()); activity.startActivity(intent); @@ -68,6 +67,7 @@ public class VodActivity extends BaseActivity { public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable RecyclerView.ViewHolder child, int position, int subposition) { mBinding.pager.setCurrentItem(position); if (mOldView != null) mOldView.setActivated(false); + if (child == null) return; mOldView = child.itemView; mOldView.setActivated(true); } @@ -81,7 +81,6 @@ public class VodActivity extends BaseActivity { adapter.addAll(0, mResult.getTypes()); ItemBridgeAdapter bridgeAdapter = new ItemBridgeAdapter(adapter); mBinding.recycler.setAdapter(bridgeAdapter); - FocusHighlightHelper.setupBrowseItemFocusHighlight(bridgeAdapter, FocusHighlight.ZOOM_FACTOR_MEDIUM, false); } private void setPager() { diff --git a/app/src/main/java/com/fongmi/bear/ui/custom/CustomHorizontalGridView.java b/app/src/main/java/com/fongmi/bear/ui/custom/CustomHorizontalGridView.java index 7dcee7d3f..7728ba229 100644 --- a/app/src/main/java/com/fongmi/bear/ui/custom/CustomHorizontalGridView.java +++ b/app/src/main/java/com/fongmi/bear/ui/custom/CustomHorizontalGridView.java @@ -41,8 +41,8 @@ public class CustomHorizontalGridView extends HorizontalGridView { @Override public View focusSearch(View focused, int direction) { if (focused != null) { - final FocusFinder finder = FocusFinder.getInstance(); - final View found = finder.findNextFocus(this, focused, direction); + FocusFinder finder = FocusFinder.getInstance(); + View found = finder.findNextFocus(this, focused, direction); if (direction == View.FOCUS_LEFT || direction == View.FOCUS_RIGHT) { if ((found == null || found.getId() != R.id.name) && getScrollState() == SCROLL_STATE_IDLE) { focused.clearAnimation(); @@ -103,14 +103,14 @@ public class CustomHorizontalGridView extends HorizontalGridView { View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction); if (nextFocused == null || nextFocused == currentFocused) { if (direction == FOCUS_LEFT || direction == FOCUS_RIGHT) { - shakeX(currentFocused); + shake(currentFocused); handled = true; } } return handled; } - private void shakeX(View currentFocused) { + private void shake(View currentFocused) { if (currentFocused != null && getScrollState() == SCROLL_STATE_IDLE) { currentFocused.clearAnimation(); currentFocused.startAnimation(shake); diff --git a/app/src/main/java/com/fongmi/bear/ui/custom/CustomVerticalGridView.java b/app/src/main/java/com/fongmi/bear/ui/custom/CustomVerticalGridView.java new file mode 100644 index 000000000..1b31e4412 --- /dev/null +++ b/app/src/main/java/com/fongmi/bear/ui/custom/CustomVerticalGridView.java @@ -0,0 +1,75 @@ +package com.fongmi.bear.ui.custom; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.leanback.widget.OnChildViewHolderSelectedListener; +import androidx.leanback.widget.VerticalGridView; +import androidx.recyclerview.widget.RecyclerView; + +public class CustomVerticalGridView extends VerticalGridView { + + private View mTabView; + private boolean pressUp; + private boolean pressDown; + + public CustomVerticalGridView(@NonNull Context context) { + super(context); + } + + public CustomVerticalGridView(@NonNull Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public CustomVerticalGridView(@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); + setOnChildViewHolderSelectedListener(new OnChildViewHolderSelectedListener() { + @Override + public void onChildViewHolderSelected(@NonNull RecyclerView parent, @Nullable ViewHolder child, int position, int subposition) { + if (pressUp && position == 0) { + mTabView.setVisibility(View.VISIBLE); + } else if (pressDown && position == 1) { + mTabView.setVisibility(View.GONE); + } + } + }); + } + + public void setTabView(View tabView) { + this.mTabView = tabView; + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() != KeyEvent.ACTION_DOWN) return super.dispatchKeyEvent(event); + pressUp = false; + pressDown = false; + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_DPAD_UP: + pressUp = true; + return super.dispatchKeyEvent(event); + case KeyEvent.KEYCODE_DPAD_DOWN: + pressDown = true; + return super.dispatchKeyEvent(event); + case KeyEvent.KEYCODE_BACK: + moveToTop(); + return true; + default: + return super.dispatchKeyEvent(event); + } + } + + public void moveToTop() { + mTabView.setVisibility(View.VISIBLE); + scrollToPosition(0); + } +} diff --git a/app/src/main/java/com/fongmi/bear/ui/custom/CustomViewPager.java b/app/src/main/java/com/fongmi/bear/ui/custom/CustomViewPager.java index cfc00a8cc..6364c89ab 100644 --- a/app/src/main/java/com/fongmi/bear/ui/custom/CustomViewPager.java +++ b/app/src/main/java/com/fongmi/bear/ui/custom/CustomViewPager.java @@ -37,12 +37,12 @@ public class CustomViewPager extends ViewPager { this.shake = AnimationUtils.loadAnimation(getContext(), R.anim.shake); setPageTransformer(false, (page, position) -> { page.setTranslationX(page.getWidth() * -position); - if (position <= -1.0F || position >= 1.0F) { - page.setAlpha(0.0F); - } else if (position == 0.0F) { - page.setAlpha(1.0F); + if (position <= -1 || position >= 1) { + page.setAlpha(0); + } else if (position == 0) { + page.setAlpha(1); } else { - page.setAlpha(1.0F - Math.abs(position)); + page.setAlpha(1 - Math.abs(position)); } }); } @@ -87,16 +87,16 @@ public class CustomViewPager extends ViewPager { View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction); if (nextFocused != null && nextFocused != currentFocused) { if (direction == View.FOCUS_LEFT) { - final int nextLeft = getChildRectInPagerCoordinates(rect, nextFocused).left; - final int currLeft = getChildRectInPagerCoordinates(rect, currentFocused).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) { - final int nextLeft = getChildRectInPagerCoordinates(rect, nextFocused).left; - final int currLeft = getChildRectInPagerCoordinates(rect, currentFocused).left; + int nextLeft = getChildRectInPagerCoordinates(rect, nextFocused).left; + int currLeft = getChildRectInPagerCoordinates(rect, currentFocused).left; if (currentFocused != null && nextLeft <= currLeft) { handled = pageRight(); } else { @@ -105,14 +105,14 @@ public class CustomViewPager extends ViewPager { } } else if (direction == FOCUS_LEFT) { if (getCurrentItem() == 0) { - shakeX(currentFocused); + shake(currentFocused); handled = true; } else { handled = pageLeft(); } } else if (direction == FOCUS_RIGHT) { if (getAdapter() != null && getCurrentItem() == getAdapter().getCount() - 1) { - shakeX(currentFocused); + shake(currentFocused); handled = true; } else { handled = pageRight(); @@ -138,7 +138,7 @@ public class CustomViewPager extends ViewPager { outRect.bottom = child.getBottom(); ViewParent parent = child.getParent(); while (parent instanceof ViewGroup && parent != this) { - final ViewGroup group = (ViewGroup) parent; + ViewGroup group = (ViewGroup) parent; outRect.left += group.getLeft(); outRect.right += group.getRight(); outRect.top += group.getTop(); @@ -157,14 +157,14 @@ public class CustomViewPager extends ViewPager { } boolean pageRight() { - if (getAdapter() != null && getCurrentItem() < (getAdapter().getCount() - 1)) { + if (getAdapter() != null && getCurrentItem() < getAdapter().getCount() - 1) { setCurrentItem(getCurrentItem() + 1, true); return true; } return false; } - private void shakeX(View currentFocused) { + private void shake(View currentFocused) { if (currentFocused != null) { currentFocused.clearAnimation(); currentFocused.startAnimation(shake); diff --git a/app/src/main/java/com/fongmi/bear/ui/fragment/VodFragment.java b/app/src/main/java/com/fongmi/bear/ui/fragment/VodFragment.java index 63c084d02..7c27a057f 100644 --- a/app/src/main/java/com/fongmi/bear/ui/fragment/VodFragment.java +++ b/app/src/main/java/com/fongmi/bear/ui/fragment/VodFragment.java @@ -13,6 +13,7 @@ import androidx.leanback.widget.ItemBridgeAdapter; import androidx.leanback.widget.ListRow; import androidx.lifecycle.ViewModelProvider; +import com.fongmi.bear.R; import com.fongmi.bear.bean.Filter; import com.fongmi.bear.bean.Vod; import com.fongmi.bear.databinding.FragmentVodBinding; @@ -80,6 +81,7 @@ public class VodFragment extends Fragment implements Scroller.Callback, VodPrese selector.addPresenter(ListRow.class, new CustomRowPresenter(16), VodPresenter.class); selector.addPresenter(ListRow.class, new CustomRowPresenter(8), FilterPresenter.class); mBinding.recycler.addOnScrollListener(mScroller = new Scroller(this)); + mBinding.recycler.setTabView(getActivity().findViewById(R.id.recycler)); mBinding.recycler.setVerticalSpacing(ResUtil.dp2px(16)); mBinding.recycler.setAdapter(new ItemBridgeAdapter(mAdapter = new ArrayObjectAdapter(selector))); } @@ -138,4 +140,10 @@ public class VodFragment extends Fragment implements Scroller.Callback, VodPrese public void onLoadMore(String page) { getVideo(page); } + + @Override + public void onResume() { + super.onResume(); + mBinding.recycler.moveToTop(); + } } diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml index e802bb5e9..ecd053cb1 100644 --- a/app/src/main/res/layout/activity_detail.xml +++ b/app/src/main/res/layout/activity_detail.xml @@ -6,10 +6,10 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - - - - diff --git a/app/src/main/res/layout/adapter_item.xml b/app/src/main/res/layout/adapter_item.xml index 198ac6aeb..56f3d3c70 100644 --- a/app/src/main/res/layout/adapter_item.xml +++ b/app/src/main/res/layout/adapter_item.xml @@ -9,5 +9,5 @@ android:focusableInTouchMode="true" android:gravity="center" android:textColor="@color/white" - android:textSize="18sp" + android:textSize="16sp" tools:text="泥巴" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_vod.xml b/app/src/main/res/layout/fragment_vod.xml index 0dbf76553..f351c003d 100644 --- a/app/src/main/res/layout/fragment_vod.xml +++ b/app/src/main/res/layout/fragment_vod.xml @@ -4,14 +4,14 @@ android:layout_width="match_parent" android:layout_height="match_parent"> -