package com.gh.gamecenter.fragment; import static com.gh.gamecenter.MainActivity.EB_SKIP_MAIN; import android.graphics.Bitmap; import android.graphics.PorterDuff; import android.graphics.drawable.Animatable; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.CheckedTextView; import android.widget.ImageView; import androidx.annotation.ColorRes; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProviders; import com.airbnb.lottie.LottieAnimationView; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.drawee.controller.BaseControllerListener; import com.facebook.drawee.interfaces.DraweeController; import com.facebook.drawee.view.SimpleDraweeView; import com.facebook.fresco.animation.drawable.AnimatedDrawable2; import com.facebook.fresco.animation.drawable.BaseAnimationListener; import com.facebook.imagepipeline.image.ImageInfo; import com.gh.common.constant.Config; import com.gh.common.dialog.PrivacyPolicyDialogFragment; import com.gh.common.dialog.ReserveDialog; import com.gh.common.exposure.ExposureSource; import com.gh.common.util.FloatingBackViewManager; import com.gh.common.util.HomeBottomBarHelper; import com.gh.common.util.IntegralLogHelper; import com.gh.common.util.LogUtils; import com.gh.common.util.NewLogUtils; import com.gh.gamecenter.R; import com.gh.gamecenter.category2.CategoryV2Fragment; import com.gh.gamecenter.common.base.fragment.BaseFragment_ViewPager_Checkable; import com.gh.gamecenter.common.callback.BiCallback; import com.gh.gamecenter.common.callback.OnDoubleTapListener; import com.gh.gamecenter.common.constant.EntranceConsts; import com.gh.gamecenter.common.syncpage.SyncPageRepository; import com.gh.gamecenter.common.tracker.TrackerLogger; import com.gh.gamecenter.common.utils.ExtensionsKt; import com.gh.gamecenter.common.utils.ImageUtils; import com.gh.gamecenter.common.utils.NightModeUtils; import com.gh.gamecenter.core.utils.DisplayUtils; import com.gh.gamecenter.databinding.FragmentMainBinding; import com.gh.gamecenter.entity.SettingsEntity; import com.gh.gamecenter.entity.SubjectData; import com.gh.gamecenter.entity.SubjectRecommendEntity; import com.gh.gamecenter.entity.WelcomeDialogEntity; import com.gh.gamecenter.eventbus.EBReuse; import com.gh.gamecenter.eventbus.EBSkip; import com.gh.gamecenter.eventbus.EBUISwitch; import com.gh.gamecenter.forum.home.CommunityHomeFragment; import com.gh.gamecenter.game.GameFragment; import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment; import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment; import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment; import com.gh.gamecenter.message.MessageUnreadRepository; import com.gh.gamecenter.message.MessageUnreadViewModel; import com.gh.gamecenter.personal.PersonalFragment; import com.gh.gamecenter.servers.GameServersPublishFragment; import com.gh.gamecenter.servers.GameServersTestFragment; import com.gh.gamecenter.subject.SubjectFragment; import com.gh.gamecenter.video.detail.HomeVideoFragment; import com.halo.assistant.HaloApp; import com.halo.assistant.fragment.WebFragment; import com.lightgame.listeners.OnBackPressedListener; import com.lightgame.view.CheckableLinearLayout; import com.lightgame.view.NoScrollableViewPager; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; import java.util.List; public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implements OnBackPressedListener { public static final int INDEX_HOME = 0; public static final int INDEX_GAME = 1; public static final int INDEX_BBS = 2; public static final int INDEX_VIDEO = 3; public static final int INDEX_PERSONAL = 4; public static final String EB_MAIN_SCROLL_TOP = "main_scroll_top"; private FragmentMainBinding mBinding; private MainWrapperViewModel mViewModel; private SearchToolWrapperFragment mGameWrapperFragment; private HomeSearchToolWrapperFragment mHomeFragment; private HomeVideoFragment mHomeVideoFragment; private CommunityHomeFragment mCommunityHomeFragment; private final String[] resAssets = {"lottie/tab_home.json", "lottie/tab_game.json", "lottie/tab_forum.json", "lottie/tab_video.json", "tab_mine.gif"}; @Override protected int getLayoutId() { return 0; } @Override protected View getInflatedLayout() { mBinding = FragmentMainBinding.inflate(getLayoutInflater()); return mBinding.getRoot(); } @Override protected int getCheckableGroupId() { return R.id.lightgame_tab_container; } @Override protected int getViewPagerId() { return R.id.lightgame_tab_viewpager; } @Override protected void initFragmentList(List fragments) { mHomeFragment = new HomeSearchToolWrapperFragment(); fragments.add(mHomeFragment); initGameWrapperFragment(); fragments.add(mGameWrapperFragment); mHomeVideoFragment = new HomeVideoFragment(); Bundle videoArgs = new Bundle(); videoArgs.putBoolean(EntranceConsts.KEY_IS_HOME_VIDEO, true); mHomeVideoFragment.setArguments(videoArgs); mCommunityHomeFragment = new CommunityHomeFragment(); mCommunityHomeFragment.setArguments(getArguments()); fragments.add(mCommunityHomeFragment); fragments.add(mHomeVideoFragment); if (mViewModel.shouldHideVideoTab()) { mBinding.mainTabVideo.setVisibility(View.GONE); } fragments.add(new PersonalFragment()); } private void initGameWrapperFragment() { mGameWrapperFragment = new SearchToolWrapperFragment(); Bundle homeArgs = new Bundle(); String className = GameFragment.class.getName(); SubjectRecommendEntity entity = mViewModel.getNavBar().getValue(); if (entity == null) { entity = HomeBottomBarHelper.getDefaultGameBarData(); } if (entity.getType() != null) { switch (entity.getType()) { case "block": className = GameFragment.class.getName(); break; case "column": className = SubjectFragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_ENTRANCE, "游戏库"); homeArgs.putParcelable( EntranceConsts.KEY_SUBJECT_DATA, new SubjectData(entity.getLink(), entity.getText(), false, "", "", "", "", true, false) ); break; case "column_collection": className = ColumnCollectionDetailFragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_ENTRANCE, "游戏库"); homeArgs.putString(EntranceConsts.KEY_COLLECTION_ID, entity.getLink()); homeArgs.putInt(EntranceConsts.KEY_POSITION, 0); homeArgs.putString(EntranceConsts.KEY_COLUMNNAME, entity.getText()); homeArgs.putBoolean(EntranceConsts.KEY_IS_COLUMN_COLLECTION, true); break; case "server": className = GameServersPublishFragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_ENTRANCE, "游戏库"); break; case "column_test": className = GameServersTestFragment.class.getName(); homeArgs.putString(GameServersTestFragment.TEST_COLUMN_ID, entity.getLink()); break; case "category_v2": className = CategoryV2Fragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_CATEGORY_ID, entity.getLink()); homeArgs.putString(EntranceConsts.KEY_CATEGORY_TITLE, entity.getText()); break; case "common_collection": className = CommonCollectionDetailFragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_ENTRANCE, "游戏库"); homeArgs.putString(EntranceConsts.KEY_COLLECTION_ID, entity.getLink()); homeArgs.putString(EntranceConsts.KEY_COLUMNNAME, entity.getText()); break; case "game_list_square": className = GameCollectionSquareFragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_ENTRANCE, "游戏库"); homeArgs.putInt(EntranceConsts.KEY_TAB_INDEX, 0); homeArgs.putString(EntranceConsts.KEY_NAME, entity.getName()); break; case "web": className = WebFragment.class.getName(); homeArgs.putString(EntranceConsts.KEY_URL, entity.getLink()); homeArgs.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, false); homeArgs.putBoolean(WebFragment.KEY_ENABLE_HORIZONTAL_SCROLL_DISPATCH, true); if (entity.getLink() != null && entity.getLink().contains("leave_web_page_handle_back_pressed=true")) { homeArgs.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_BACK_PRESSED, true); } break; } } homeArgs.putString(SearchToolWrapperFragment.WRAPPER_FRAGMENT_NAME, className); homeArgs.putBoolean(EntranceConsts.KEY_IS_HOME, true); homeArgs.putParcelable( EntranceConsts.KEY_EXPOSURE_SOURCE, new ExposureSource("游戏库", "") ); mGameWrapperFragment.setArguments(homeArgs); } @Override public ArrayList restoreFragments() { ArrayList restoreFragments = super.restoreFragments(); for (Fragment fragment : restoreFragments) { if (fragment instanceof SearchToolWrapperFragment && !(fragment instanceof HomeSearchToolWrapperFragment)) { mGameWrapperFragment = (SearchToolWrapperFragment) fragment; } else if (fragment instanceof HomeVideoFragment) { mHomeVideoFragment = (HomeVideoFragment) fragment; } else if (fragment instanceof CommunityHomeFragment) { mCommunityHomeFragment = (CommunityHomeFragment) fragment; } else if (fragment instanceof HomeSearchToolWrapperFragment) { mHomeFragment = (HomeSearchToolWrapperFragment) fragment; } } return restoreFragments; } @Override public void onCreate(Bundle savedInstanceState) { mViewModel = ViewModelProviders.of(this, new MainWrapperViewModel.Factory(HaloApp.getInstance())).get(MainWrapperViewModel.class); super.onCreate(savedInstanceState); mBinding.viewShadow.setVisibility(NightModeUtils.INSTANCE.isNightMode(requireContext()) ? View.GONE : View.VISIBLE); mViewModel.getNavBar().observe(this, this::updateGameBarContent); mViewModel.getReserveDialog().observe(this, reserveData -> { if (reserveData != null && !reserveData.isEmpty()) { ReserveDialog reserveDialog = ReserveDialog.getInstance(reserveData); reserveDialog.setOnDismissListener(() -> { MessageUnreadRepository.INSTANCE.loadMessageUnreadData(); return null; }); reserveDialog.show(getChildFragmentManager(), "reserveDialog"); } else { MessageUnreadRepository.INSTANCE.loadMessageUnreadData(); } }); ViewModelProviders.of(this) .get(MessageUnreadViewModel.class) .getUnreadMessageTotalLiveData().observe(this, isShow -> ExtensionsKt.goneIf(mBinding.mainIvMessageHint, !isShow)); } public void getDialog() { mViewModel.requestOpeningData(); mViewModel.getPrivacyPolicyDialog().observe(this, it -> { if (it != null) { PrivacyPolicyDialogFragment.show(requireActivity(), it, isSuccess -> { showWelcomeDialogIfNeeded(mViewModel.getOpeningDialog().getValue()); return null; }); } else { showWelcomeDialogIfNeeded(mViewModel.getOpeningDialog().getValue()); } }); } private void showWelcomeDialogIfNeeded(WelcomeDialogEntity welcomeDialogEntity) { // 判断启动本次应用是否已经弹窗,不是的话弹启动弹窗 if (welcomeDialogEntity != null && HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) { HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false); ImageUtils.getBitmap(welcomeDialogEntity.getIcon(), new BiCallback() { @Override public void onFirst(Bitmap bitmap) { // 网络速度追不上用户操作的时候可能会出现要弹启动弹窗但用户已经不停留在 MainActivity 的情况 if (!isAdded()) return; WelcomeDialogFragment welcomeDialog = WelcomeDialogFragment.getInstance(welcomeDialogEntity); welcomeDialog.setOnDismissListener(() -> { mViewModel.requestReserveDialog(); return null; }); welcomeDialog.show(getChildFragmentManager(), "openingDialog"); } @Override public void onSecond(Boolean aBoolean) { mViewModel.requestReserveDialog(); } }); } else { mViewModel.requestReserveDialog(); } } private void updateGameBarContent(SubjectRecommendEntity navBarEntity) { if (navBarEntity != null) { mBinding.mainTabGame.setVisibility(View.VISIBLE); mBinding.mainTabGameName.setText(navBarEntity.getName()); ImageUtils.getPicasso() .load(Uri.parse(navBarEntity.getIconUnselect())) //.placeholder(R.drawable.ic_game_unselect) .into(mBinding.mainTabGameIcon); if (navBarEntity.getDefault()) setCurrentItem(INDEX_GAME); } else { mBinding.mainTabGame.setVisibility(View.GONE); } } @Override public void onPause() { super.onPause(); SyncPageRepository.clearSyncData(); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (mViewPager instanceof NoScrollableViewPager) { ((NoScrollableViewPager) mViewPager).setScrollable(false); } // 启动时即当选中第一个 tab onPageChanged(INDEX_HOME); for (int i = 0; i < mCheckableGroup.getChildCount(); i++) { View child = mCheckableGroup.getChildAt(i); int finalI = i; child.setOnTouchListener(new OnDoubleTapListener(getContext()) { @Override public void onDoubleTap() { EventBus.getDefault().post(new EBUISwitch(EB_MAIN_SCROLL_TOP, finalI)); } }); } } @Override protected boolean handleOnClick(View view) { final int toCheck = mCheckableGroup.indexOfChild(view); playTabAnimation(toCheck); changeColor(toCheck); return super.handleOnClick(view); } private void changeColor(int toCheck) { if (toCheck == INDEX_VIDEO) { mBinding.viewShadow.setVisibility(View.GONE); mCheckableGroup.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.transparent)); changeTabImageColor(R.color.text_A1A5B7, PorterDuff.Mode.SRC_ATOP); changeTabTextColor(R.color.text_A1A5B7, false); } else { mBinding.viewShadow.setVisibility(NightModeUtils.INSTANCE.isNightMode(requireContext()) ? View.GONE : View.VISIBLE); mCheckableGroup.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.background_white)); changeTabImageColor(R.color.text_50556B, PorterDuff.Mode.DST); changeTabTextColor(R.color.tab_selector, true); } } private void playTabAnimation(int toCheck) { switch (toCheck) { case INDEX_HOME: stopAnimation(mBinding.lottieGame, INDEX_GAME); stopAnimation(mBinding.lottieVideo, INDEX_VIDEO); stopAnimation(mBinding.lottieCommunity, INDEX_BBS); stopAnimation(mBinding.lottieMine, INDEX_PERSONAL); playAnimation(mBinding.lottieHome, toCheck); break; case INDEX_GAME: SubjectRecommendEntity value = mViewModel.getNavBar().getValue(); if (value != null && !TextUtils.isEmpty(value.getAnimationCode())) { stopAnimation(mBinding.lottieHome, INDEX_HOME); stopAnimation(mBinding.lottieVideo, INDEX_VIDEO); stopAnimation(mBinding.lottieCommunity, INDEX_BBS); stopAnimation(mBinding.lottieMine, INDEX_PERSONAL); playGameAnimation(value, toCheck); } break; case INDEX_BBS: stopAnimation(mBinding.lottieHome, INDEX_HOME); stopAnimation(mBinding.lottieGame, INDEX_GAME); stopAnimation(mBinding.lottieVideo, INDEX_VIDEO); stopAnimation(mBinding.lottieMine, INDEX_PERSONAL); playAnimation(mBinding.lottieCommunity, toCheck); break; case INDEX_VIDEO: stopAnimation(mBinding.lottieHome, INDEX_HOME); stopAnimation(mBinding.lottieGame, INDEX_GAME); stopAnimation(mBinding.lottieCommunity, INDEX_BBS); stopAnimation(mBinding.lottieMine, INDEX_PERSONAL); playAnimation(mBinding.lottieVideo, toCheck); break; case INDEX_PERSONAL: stopAnimation(mBinding.lottieHome, INDEX_HOME); stopAnimation(mBinding.lottieGame, INDEX_GAME); stopAnimation(mBinding.lottieVideo, INDEX_VIDEO); stopAnimation(mBinding.lottieCommunity, INDEX_BBS); playAnimation(mBinding.lottieMine, toCheck); break; default: break; } } private void changeTabImageColor(@ColorRes int colorRes, PorterDuff.Mode mode) { for (int i = 0; i < mCheckableGroup.getChildCount(); i++) { if (i != INDEX_VIDEO) { CheckableLinearLayout checkableGroupChild = (CheckableLinearLayout) mCheckableGroup.getChildAt(i); ImageView checkableView = (ImageView) checkableGroupChild.findCheckableImageView(checkableGroupChild); if (checkableView != null) { checkableView.setColorFilter(ContextCompat.getColor(requireContext(), colorRes), mode); } } } } private void changeTabTextColor(@ColorRes int colorRes, boolean isSelector) { for (int i = 0; i < mCheckableGroup.getChildCount(); i++) { if (i != INDEX_VIDEO) { CheckableLinearLayout checkableGroupChild = (CheckableLinearLayout) mCheckableGroup.getChildAt(i); CheckedTextView checkableView = (CheckedTextView) checkableGroupChild.findCheckableTextView(checkableGroupChild); if (checkableView != null) { if (isSelector) { checkableView.setTextColor(ContextCompat.getColorStateList(requireContext(), colorRes)); } else { checkableView.setTextColor(ContextCompat.getColor(requireContext(), colorRes)); } } } } } private void playGameAnimation(SubjectRecommendEntity entity, int position) { CheckableLinearLayout checkableGroupChild = (CheckableLinearLayout) mCheckableGroup.getChildAt(position); View checkableView = checkableGroupChild.findCheckableImageView(checkableGroupChild); if (checkableView != null) checkableView.setVisibility(View.INVISIBLE); mBinding.lottieGame.setVisibility(View.VISIBLE); mBinding.lottieGame.setAnimationFromJson(entity.getAnimationCode(), entity.getIconSelect()); mBinding.lottieGame.playAnimation(); ExtensionsKt.doOnAnimationEnd(mBinding.lottieGame, () -> { mBinding.lottieGame.setVisibility(View.GONE); if (checkableView != null) checkableView.setVisibility(View.VISIBLE); return null; }); } private void playAnimation(View view, int position) { CheckableLinearLayout checkableGroupChild = (CheckableLinearLayout) mCheckableGroup.getChildAt(position); View checkableView = checkableGroupChild.findCheckableImageView(checkableGroupChild); if (checkableView != null) checkableView.setVisibility(View.INVISIBLE); view.setVisibility(View.VISIBLE); if (view instanceof LottieAnimationView) { LottieAnimationView lottieView = (LottieAnimationView) view; lottieView.setAnimation(resAssets[position]); lottieView.playAnimation(); ExtensionsKt.doOnAnimationEnd(lottieView, () -> { lottieView.setVisibility(View.GONE); if (checkableView != null) checkableView.setVisibility(View.VISIBLE); return null; }); } else { SimpleDraweeView lottieView = (SimpleDraweeView) view; Uri uri = Uri.parse("asset:///" + resAssets[position]); DraweeController controller = Fresco.newDraweeControllerBuilder() .setUri(uri) .setAutoPlayAnimations(true) .setControllerListener(new BaseControllerListener() { @Override public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) { super.onFinalImageSet(id, imageInfo, animatable); if (animatable != null) { AnimatedDrawable2 animatedDrawable = (AnimatedDrawable2) animatable; animatedDrawable.setAnimationListener(new BaseAnimationListener() { @Override public void onAnimationStop(AnimatedDrawable2 drawable) { super.onAnimationStop(drawable); lottieView.setVisibility(View.GONE); if (checkableView != null) checkableView.setVisibility(View.VISIBLE); } }); } } }).build(); lottieView.setController(controller); } } private void stopAnimation(View lottieView, int position) { CheckableLinearLayout checkableGroupChild = (CheckableLinearLayout) mCheckableGroup.getChildAt(position); View checkableView = checkableGroupChild.findCheckableImageView(checkableGroupChild); if (checkableView != null) checkableView.setVisibility(View.VISIBLE); lottieView.setVisibility(View.GONE); } @Override protected void onPageChanged(int index) { super.onPageChanged(index); String tabText = ""; switch (index) { case INDEX_HOME: tabText = "首页"; NewLogUtils.logBottomNavigationClick("首页", "", "", ""); break; case INDEX_GAME: tabText = "游戏库"; SubjectRecommendEntity entity = mViewModel.getNavBar().getValue(); if (entity == null) { entity = HomeBottomBarHelper.getDefaultGameBarData(); } NewLogUtils.logBottomNavigationClick("游戏库", entity.getType() != null ? entity.getType() : "", entity.getText() != null ? entity.getText() : "", entity.getLink() != null ? entity.getLink() : ""); break; case INDEX_BBS: tabText = "论坛"; LogUtils.uploadAccessBbsTab(); NewLogUtils.logBottomNavigationClick("社区", "", "", ""); break; case INDEX_VIDEO: tabText = "视频"; DisplayUtils.setLightStatusBar(requireActivity(), false); NewLogUtils.logBottomNavigationClick("视频", "", "", ""); break; case INDEX_PERSONAL: tabText = "我的光环"; IntegralLogHelper.INSTANCE.log("view_me", "我的光环"); NewLogUtils.logBottomNavigationClick("我的光环", "", "", ""); break; } TrackerLogger.logHomeTabSelected(index, tabText); if (index != INDEX_BBS) { FloatingBackViewManager.disableBackView(); FloatingBackViewManager.dismissBackView(); } SubjectRecommendEntity navBarEntity = mViewModel.getNavBar().getValue(); if (navBarEntity != null) { if (index == INDEX_GAME) { ImageUtils.getPicasso() .load(Uri.parse(navBarEntity.getIconSelect())) //.placeholder(R.drawable.ic_game_select) .into(mBinding.mainTabGameIcon); } else { ImageUtils.getPicasso() .load(Uri.parse(navBarEntity.getIconUnselect())) //.placeholder(R.drawable.ic_game_unselect) .into(mBinding.mainTabGameIcon); } } } @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(EBSkip skip) { if (EB_SKIP_MAIN.equals(skip.getType())) { checkIndex(skip.getCurrentItem()); changeColor(skip.getCurrentItem()); mViewPager.setCurrentItem(skip.getCurrentItem(), false); } } @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(EBReuse reuse) { if ("Refresh".equals(reuse.getType())) { SettingsEntity settings = Config.getSettings(); if (settings != null && !settings.showCommunityEntrance()) { mBinding.mainTabCommunity.setVisibility(View.GONE); } else { mBinding.mainTabCommunity.setVisibility(View.VISIBLE); } } } public void setCurrentItem(int page) { mViewPager.setCurrentItem(page, false); changeColor(page); } public int getCurrentItem() { return mViewPager.getCurrentItem(); } @Override public boolean onHandleBackPressed() { if (mHomeVideoFragment.getCurrentFragment() != null) { return mHomeVideoFragment.getCurrentFragment().onHandleBackPressed(); } if (mViewPager.getCurrentItem() == INDEX_HOME) { return mHomeFragment.onBackPressed(); } if (mViewPager.getCurrentItem() == INDEX_GAME) { return mGameWrapperFragment.onBackPressed(); } if (mViewPager.getCurrentItem() == INDEX_BBS) { return mCommunityHomeFragment.onBackPressed(); } return false; } @Override public int getChildCount() { return 5; } @Override protected void onNightModeChange() { super.onNightModeChange(); changeColor(mViewPager.getCurrentItem()); } }