From 4248f4137df26340af6ff2c1ef6f5856d52b82a1 Mon Sep 17 00:00:00 2001 From: BlackMesa123 Date: Wed, 26 Jan 2022 16:30:17 +0100 Subject: [PATCH 1/2] app: SamsungTabLayout update -unified TabLayout & BNV -added SESL_AUTO modes for managing tab width/scroll -add badges in tabs Signed-off-by: BlackMesa123 --- .../yanndroid/oneuiexample/MainActivity.java | 53 +- .../fragments/MainActivityFirstFragment.java | 8 +- .../yanndroid/oneuiexample/tabs/IconsTab.java | 15 +- app/src/main/res/layout/activity_main.xml | 4 +- app/src/main/res/layout/fragment_first.xml | 4 +- .../sesl/appbar/SamsungAppBarLayout.java | 3866 ++++++++--------- .../colorpicker/detailed/SeslColorPicker.java | 6 +- .../tabs/ElasticTabIndicatorInterpolator.java | 40 + .../oneui/sesl/tabs/SamsungBaseTabLayout.java | 2706 ------------ .../oneui/sesl/tabs/SamsungTabLayout.java | 3098 +++++++++++++ ...torView.java => SeslAbsIndicatorView.java} | 30 +- ...ator.java => SeslTabDotLineIndicator.java} | 37 +- .../sesl/tabs/SeslTabRoundRectIndicator.java | 140 + .../sesl/tabs/TabIndicatorInterpolator.java | 64 + .../yanndroid/oneui/sesl/tabs/TabItem.java | 36 +- .../sesl/tabs/TabRoundRectIndicator.java | 124 - .../utils/CustomButtonClickListener.java | 10 +- .../oneui/widget/BottomNavigationView.java | 201 - .../yanndroid/oneui/widget/TabLayout.java | 233 +- ...sl4_tablayout_selected_indicator_color.xml | 5 +- .../sesl4_tablayout_selected_text_color.xml | 5 +- ...esl_tablayout_selected_indicator_color.xml | 3 +- .../sesl_tablayout_selected_text_color.xml | 3 +- .../sesl_tablayout_subtab_sub_text_color.xml | 7 + .../sesl_tablayout_subtab_text_color.xml | 11 +- .../res/color/sesl_tablayout_text_color.xml | 9 +- ...esl_tablayout_maintab_touch_background.xml | 3 +- ...sesl_tablayout_subtab_indicator_ripple.xml | 5 +- .../sesl_tab_n_badge_mtrl.9.png | Bin 0 -> 776 bytes ...oui_tablayout_custombutton_background.xml} | 0 ...sesl4_tablayout_subtab_indicator_shape.xml | 2 +- .../src/main/res/drawable/sesl_dot_badge.xml | 5 + .../main/res/drawable/sesl_tab_n_badge.xml | 3 + ...maintab_indicator_opentheme_background.xml | 6 +- ...esl_tablayout_maintab_touch_background.xml | 3 +- ..._tablayout_subtab_indicator_background.xml | 9 +- ...sesl_tablayout_subtab_indicator_ripple.xml | 5 +- .../sesl_tablayout_subtab_indicator_shape.xml | 14 +- .../drawable/sesl_tabs_default_indicator.xml | 3 +- .../main/res/layout/sesl_layout_tab_icon.xml | 3 + .../res/layout/sesl_layout_tab_sub_text.xml | 3 + .../main/res/layout/sesl_layout_tab_text.xml | 3 + .../res/layout/sesl_tabs_main_tab_layout.xml | 41 +- .../res/layout/sesl_tabs_sub_tab_layout.xml | 23 +- .../src/main/res/values-night/colors.xml | 23 +- yanndroid/oneui/src/main/res/values/attrs.xml | 80 +- .../oneui/src/main/res/values/colors.xml | 26 +- .../oneui/src/main/res/values/dimens.xml | 20 +- yanndroid/oneui/src/main/res/values/ids.xml | 2 + .../oneui/src/main/res/values/integer.xml | 1 + .../oneui/src/main/res/values/strings.xml | 3 + .../oneui/src/main/res/values/styles.xml | 23 +- 52 files changed, 5680 insertions(+), 5347 deletions(-) create mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/ElasticTabIndicatorInterpolator.java delete mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungBaseTabLayout.java create mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungTabLayout.java rename yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/{AbsIndicatorView.java => SeslAbsIndicatorView.java} (70%) rename yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/{TabDotLineIndicator.java => SeslTabDotLineIndicator.java} (54%) create mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabRoundRectIndicator.java create mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabIndicatorInterpolator.java delete mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabRoundRectIndicator.java delete mode 100644 yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/BottomNavigationView.java create mode 100644 yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_sub_text_color.xml mode change 100755 => 100644 yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_text_color.xml mode change 100755 => 100644 yanndroid/oneui/src/main/res/color/sesl_tablayout_text_color.xml create mode 100644 yanndroid/oneui/src/main/res/drawable-xxhdpi/sesl_tab_n_badge_mtrl.9.png rename yanndroid/oneui/src/main/res/drawable/{oui_bottomnavview_button_background.xml => oui_tablayout_custombutton_background.xml} (100%) create mode 100644 yanndroid/oneui/src/main/res/drawable/sesl_dot_badge.xml create mode 100644 yanndroid/oneui/src/main/res/drawable/sesl_tab_n_badge.xml create mode 100644 yanndroid/oneui/src/main/res/layout/sesl_layout_tab_icon.xml create mode 100644 yanndroid/oneui/src/main/res/layout/sesl_layout_tab_sub_text.xml create mode 100644 yanndroid/oneui/src/main/res/layout/sesl_layout_tab_text.xml diff --git a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java index 0f2018b7..0b3b7e7d 100644 --- a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java +++ b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java @@ -19,6 +19,7 @@ import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; +import androidx.core.content.res.ResourcesCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; @@ -32,11 +33,12 @@ import de.dlyt.yanndroid.oneui.menu.MenuItem; import de.dlyt.yanndroid.oneui.menu.PopupMenu; import de.dlyt.yanndroid.oneui.sesl.support.ViewSupport; +import de.dlyt.yanndroid.oneui.sesl.tabs.SamsungTabLayout; import de.dlyt.yanndroid.oneui.sesl.utils.ReflectUtils; import de.dlyt.yanndroid.oneui.utils.CustomButtonClickListener; import de.dlyt.yanndroid.oneui.utils.ThemeUtil; import de.dlyt.yanndroid.oneui.view.Snackbar; -import de.dlyt.yanndroid.oneui.widget.BottomNavigationView; +import de.dlyt.yanndroid.oneui.widget.TabLayout; import de.dlyt.yanndroid.oneuiexample.base.BaseThemeActivity; import de.dlyt.yanndroid.oneuiexample.utils.TabsManager; @@ -53,7 +55,7 @@ public class MainActivity extends BaseThemeActivity { private TabsManager mTabsManager; private DrawerLayout drawerLayout; - private BottomNavigationView bnvLayout; + private TabLayout tabLayout; private PopupMenu bnvPopupMenu; private ActivityResultLauncher activityResultLauncher; @@ -90,29 +92,11 @@ public void onConfigurationChanged(Configuration newConfig) { } } - @Override - public void onPause() { - super.onPause(); - - if (bnvLayout != null) { - bnvLayout.setResumeStatus(false); - } - } - - @Override - protected void onResume() { - super.onResume(); - - if (bnvLayout != null) { - bnvLayout.setResumeStatus(true); - } - } - private void init() { ViewSupport.semSetRoundedCorners(getWindow().getDecorView(), 0); drawerLayout = findViewById(R.id.drawer_view); - bnvLayout = findViewById(R.id.main_samsung_tabs); + tabLayout = findViewById(R.id.main_samsung_tabs); sharedPrefName = "mainactivity_tabs"; mTabsTagName = getResources().getStringArray(R.array.mainactivity_tab_tag); @@ -172,40 +156,43 @@ public void onVoiceInputClick(Intent intent) { } }); - //BottomNavigationLayout - Drawable icon = getDrawable(R.drawable.ic_samsung_drawer); - icon.setColorFilter(getResources().getColor(R.color.sesl_tablayout_text_color), PorterDuff.Mode.SRC_IN); + // TabLayout + tabLayout.setTabMode(SamsungTabLayout.SESL_MODE_FIXED_AUTO); + for (String s : mTabsTitleName) { - bnvLayout.addTab(bnvLayout.newTab().setText(s)); + tabLayout.addTab(tabLayout.newTab().setText(s)); } - bnvLayout.addTabCustomButton(icon, new CustomButtonClickListener(bnvLayout) { + + Drawable icon = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_samsung_drawer, getTheme()); + icon.setColorFilter(getResources().getColor(R.color.sesl_tablayout_text_color), PorterDuff.Mode.SRC_IN); + tabLayout.addTabCustomButton(icon, new CustomButtonClickListener(tabLayout) { @Override public void onClick(View v) { popupView(v); } }); - bnvLayout.addOnTabSelectedListener(new BottomNavigationView.OnTabSelectedListener() { - public void onTabSelected(BottomNavigationView.Tab tab) { + tabLayout.addOnTabSelectedListener(new SamsungTabLayout.OnTabSelectedListener() { + public void onTabSelected(SamsungTabLayout.Tab tab) { int tabPosition = tab.getPosition(); mTabsManager.setTabPosition(tabPosition); setCurrentItem(); } - public void onTabUnselected(BottomNavigationView.Tab tab) { + public void onTabUnselected(SamsungTabLayout.Tab tab) { } - public void onTabReselected(BottomNavigationView.Tab tab) { + public void onTabReselected(SamsungTabLayout.Tab tab) { } }); - bnvLayout.updateWidget(this); + setCurrentItem(); } private void setCurrentItem() { - if (bnvLayout.isEnabled()) { + if (tabLayout.isEnabled()) { int tabPosition = mTabsManager.getCurrentTab(); - BottomNavigationView.Tab tab = bnvLayout.getTabAt(tabPosition); + SamsungTabLayout.Tab tab = tabLayout.getTabAt(tabPosition); if (tab != null) { tab.select(); setFragment(tabPosition); diff --git a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/fragments/MainActivityFirstFragment.java b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/fragments/MainActivityFirstFragment.java index 54b8e586..6e800de9 100644 --- a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/fragments/MainActivityFirstFragment.java +++ b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/fragments/MainActivityFirstFragment.java @@ -8,8 +8,8 @@ import androidx.fragment.app.Fragment; -import de.dlyt.yanndroid.oneui.widget.TabLayout; import de.dlyt.yanndroid.oneui.view.ViewPager; +import de.dlyt.yanndroid.oneui.widget.TabLayout; import de.dlyt.yanndroid.oneuiexample.R; import de.dlyt.yanndroid.oneuiexample.base.BaseThemeActivity; import de.dlyt.yanndroid.oneuiexample.tabs.ViewPagerAdapter; @@ -40,11 +40,11 @@ public void onViewCreated(View view, Bundle savedInstanceState) { getView().setBackgroundColor(getResources().getColor(mActivity.mUseOUI4Theme ? R.color.sesl4_round_and_bgcolor : R.color.sesl_round_and_bgcolor)); // TabLayout and ViewPager - TabLayout tabLayout = mRootView.findViewById(R.id.tabLayout); + TabLayout subTabs = mRootView.findViewById(R.id.sub_tabs); + subTabs.seslSetSubTabStyle(); ViewPager viewPager = mRootView.findViewById(R.id.viewPager); viewPager.setAdapter(new ViewPagerAdapter(getChildFragmentManager())); - tabLayout.setupWithViewPager(viewPager); - tabLayout.updateWidget(); + subTabs.setupWithViewPager(viewPager); } } diff --git a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/tabs/IconsTab.java b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/tabs/IconsTab.java index 07f889a8..ad94579e 100644 --- a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/tabs/IconsTab.java +++ b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/tabs/IconsTab.java @@ -28,13 +28,12 @@ import de.dlyt.yanndroid.oneui.sesl.recyclerview.LinearLayoutManager; import de.dlyt.yanndroid.oneui.view.RecyclerView; import de.dlyt.yanndroid.oneui.view.ViewPager; -import de.dlyt.yanndroid.oneui.widget.BottomNavigationView; import de.dlyt.yanndroid.oneui.view.IndexScrollView; import de.dlyt.yanndroid.oneui.widget.TabLayout; import de.dlyt.yanndroid.oneuiexample.R; public class IconsTab extends Fragment { - //229 + //230 Integer[] imageIDs = {R.drawable.ic_samsung_accessibility, R.drawable.ic_samsung_account, R.drawable.ic_samsung_advanced_feature, @@ -333,8 +332,8 @@ public void handleOnBackPressed() { public void setSelecting(boolean enabled) { DrawerLayout drawerLayout = ((DrawerLayout) getActivity().findViewById(R.id.drawer_view)); - TabLayout tabLayout = getActivity().findViewById(R.id.tabLayout); - BottomNavigationView bnv = getActivity().findViewById(R.id.main_samsung_tabs); + TabLayout subTabs = getActivity().findViewById(R.id.sub_tabs); + TabLayout mainTabs = getActivity().findViewById(R.id.main_samsung_tabs); ViewPager viewPager = getActivity().findViewById(R.id.viewPager); if (enabled) { @@ -357,8 +356,8 @@ public void setSelecting(boolean enabled) { for (Boolean b : selected.values()) if (b) count++; drawerLayout.setSelectModeCount(count); }); - tabLayout.setEnabled(false); - bnv.setEnabled(false); + subTabs.setEnabled(false); + mainTabs.setEnabled(false); viewPager.setPagingEnabled(false); onBackPressedCallback.setEnabled(true); } else { @@ -368,8 +367,8 @@ public void setSelecting(boolean enabled) { drawerLayout.setSelectModeCount(0); drawerLayout.dismissSelectMode(); - tabLayout.setEnabled(true); - bnv.setEnabled(true); + subTabs.setEnabled(true); + mainTabs.setEnabled(true); viewPager.setPagingEnabled(true); onBackPressedCallback.setEnabled(false); } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4e56a3db..75e32509 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -13,10 +13,10 @@ android:layout_height="match_parent" app:layout_location="main_content" /> - diff --git a/app/src/main/res/layout/fragment_first.xml b/app/src/main/res/layout/fragment_first.xml index 31aaf600..33e67bba 100644 --- a/app/src/main/res/layout/fragment_first.xml +++ b/app/src/main/res/layout/fragment_first.xml @@ -6,9 +6,9 @@ android:orientation="vertical"> + android:layout_height="wrap_content" /> liftOnScrollTargetView; - @IdRes private int liftOnScrollTargetViewId; - private boolean liftable; - private boolean liftableOverride; - private boolean lifted = false; - private List listeners; - private SeslAppbarState mAppbarState; - private Drawable mBackground; - private int mBottomPadding = 0; - private float mCollapsedHeight; - private int mCurrentOrientation; - private int mCurrentScreenHeight; - private int mCustomHeight = -1; - private float mCustomHeightProportion; - private float mHeightProportion; - private boolean mImmHideStatusBar = false; - private List mImmOffsetListener; - private int mImmersiveTopInset = 0; - private boolean mIsActivatedByUser = false; - private boolean mIsActivatedImmersiveScroll = false; - private boolean mIsCanScroll = false; - private boolean mIsDetachedState = false; - private boolean mIsReservedImmersiveDetachOption = false; - private boolean mReservedFitSystemWindow = false; - private Resources mResources; - private boolean mRestoreAnim = false; - private int mSeslTCScrollRange = 0; - private boolean mSetCustomHeight; - private boolean mSetCustomProportion; - private boolean mUseCollapsedHeight = false; - private boolean mUseCustomHeight; - private boolean mUseCustomPadding; - private int pendingAction = PENDING_ACTION_NONE; - @Nullable - private Drawable statusBarForeground; - private int[] tmpStatesArray; - private int totalScrollRange = INVALID_SCROLL_RANGE; - - public interface BaseOnOffsetChangedListener { - void onOffsetChanged(T appBarLayout, int verticalOffset); - } - - public interface OnOffsetChangedListener extends BaseOnOffsetChangedListener { - void onOffsetChanged(SamsungAppBarLayout appBarLayout, int verticalOffset); - } - - public interface SeslBaseOnImmOffsetChangedListener { - void onOffsetChanged(T appBarLayout, int verticalOffset); - } - - public interface SeslOnImmOffsetChangedListener extends SeslBaseOnImmOffsetChangedListener { - void onOffsetChanged(SamsungAppBarLayout appBarLayout, int verticalOffset); - } - - public static class SeslAppbarState { - private int mCurrentState = SESL_STATE_IDLE; - - void onStateChanged(int state) { - mCurrentState = state; - } - - public int getState() { - return mCurrentState; - } - } - - public SamsungAppBarLayout(@NonNull Context context) { - this(context, null); - } - - public SamsungAppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs) { - this(context, attrs, R.attr.appBarLayoutStyle); - } - - @SuppressLint("RestrictedApi") - public SamsungAppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(MaterialThemeOverlay.wrap(context, attrs, defStyleAttr, DEF_STYLE_RES), attrs, defStyleAttr); - context = getContext(); - mIsOneUI4 = context.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); - setOrientation(VERTICAL); - - if (Build.VERSION.SDK_INT >= 21) { - ViewUtilsLollipop.setStateListAnimatorFromAttrs(this, attrs, defStyleAttr, DEF_STYLE_RES); - } - - final TypedArray a = ThemeEnforcement.obtainStyledAttributes(context, attrs, R.styleable.SamsungAppBarLayout, defStyleAttr, DEF_STYLE_RES); - - mAppbarState = new SeslAppbarState(); - mResources = getResources(); - - if (a.hasValue(R.styleable.SamsungAppBarLayout_android_background)) { - mBackground = a.getDrawable(R.styleable.SamsungAppBarLayout_android_background);; - ViewCompat.setBackground(this, mBackground); - } else { - mBackground = null; - setBackgroundColor(mResources.getColor(mIsOneUI4 ? R.color.sesl4_action_bar_background_color : R.color.sesl_action_bar_background_color)); - } - - if (getBackground() instanceof ColorDrawable) { - ColorDrawable background = (ColorDrawable) getBackground(); - MaterialShapeDrawable materialShapeDrawable = new MaterialShapeDrawable(); - materialShapeDrawable.setFillColor(ColorStateList.valueOf(background.getColor())); - materialShapeDrawable.initializeElevationOverlay(context); - ViewCompat.setBackground(this, materialShapeDrawable); + private boolean mIsOneUI4; + private static final float DEFAULT_HEIGHT_RATIO_TO_SCREEN = 0.39f; + private static final int DEF_STYLE_RES = R.style.OneUI4_AppBarLayoutStyle; + public static final int IMMERSIVE_DETACH_OPTION_SET_FIT_SYSTEM_WINDOW = 1; + private static final int INVALID_SCROLL_RANGE = -1; + static final int PENDING_ACTION_ANIMATE_ENABLED = 4; + static final int PENDING_ACTION_COLLAPSED = 2; + static final int PENDING_ACTION_COLLAPSED_IMM = 512; + static final int PENDING_ACTION_EXPANDED = 1; + static final int PENDING_ACTION_FORCE = 8; + static final int PENDING_ACTION_NONE = 0; + public static final int SESL_STATE_COLLAPSED = 0; + public static final int SESL_STATE_EXPANDED = 1; + public static final int SESL_STATE_HIDE = 2; + public static final int SESL_STATE_IDLE = 3; + private static final String TAG = "AppBarLayout"; + private int currentOffset; + private int downPreScrollRange = INVALID_SCROLL_RANGE; + private int downScrollRange = INVALID_SCROLL_RANGE; + @Nullable private ValueAnimator elevationOverlayAnimator; + private boolean haveChildWithInterpolator; + private boolean isMouse = false; + @Nullable private WindowInsetsCompat lastInsets; + private boolean liftOnScroll; + @Nullable private WeakReference liftOnScrollTargetView; + @IdRes private int liftOnScrollTargetViewId; + private boolean liftable; + private boolean liftableOverride; + private boolean lifted = false; + private List listeners; + private SeslAppbarState mAppbarState; + private Drawable mBackground; + private int mBottomPadding = 0; + private float mCollapsedHeight; + private int mCurrentOrientation; + private int mCurrentScreenHeight; + private int mCustomHeight = -1; + private float mCustomHeightProportion; + private float mHeightProportion; + private boolean mImmHideStatusBar = false; + private List mImmOffsetListener; + private int mImmersiveTopInset = 0; + private boolean mIsActivatedByUser = false; + private boolean mIsActivatedImmersiveScroll = false; + private boolean mIsCanScroll = false; + private boolean mIsDetachedState = false; + private boolean mIsReservedImmersiveDetachOption = false; + private boolean mReservedFitSystemWindow = false; + private Resources mResources; + private boolean mRestoreAnim = false; + private int mSeslTCScrollRange = 0; + private boolean mSetCustomHeight; + private boolean mSetCustomProportion; + private boolean mUseCollapsedHeight = false; + private boolean mUseCustomHeight; + private boolean mUseCustomPadding; + private int pendingAction = PENDING_ACTION_NONE; + @Nullable + private Drawable statusBarForeground; + private int[] tmpStatesArray; + private int totalScrollRange = INVALID_SCROLL_RANGE; + + public interface BaseOnOffsetChangedListener { + void onOffsetChanged(T appBarLayout, int verticalOffset); } - if (a.hasValue(R.styleable.SamsungAppBarLayout_expanded)) { - setExpanded(a.getBoolean(R.styleable.SamsungAppBarLayout_expanded, false), false, false); + public interface OnOffsetChangedListener extends BaseOnOffsetChangedListener { + void onOffsetChanged(SamsungAppBarLayout appBarLayout, int verticalOffset); } - if (a.hasValue(R.styleable.SamsungAppBarLayout_seslUseCustomHeight)) { - mUseCustomHeight = a.getBoolean(R.styleable.SamsungAppBarLayout_seslUseCustomHeight, false); + public interface SeslBaseOnImmOffsetChangedListener { + void onOffsetChanged(T appBarLayout, int verticalOffset); } - if (a.hasValue(R.styleable.SamsungAppBarLayout_seslHeightProportion)) { - mSetCustomProportion = true; - mCustomHeightProportion = a.getFloat(R.styleable.SamsungAppBarLayout_seslHeightProportion, DEFAULT_HEIGHT_RATIO_TO_SCREEN); - } else { - mSetCustomProportion = false; - mCustomHeightProportion = DEFAULT_HEIGHT_RATIO_TO_SCREEN; + public interface SeslOnImmOffsetChangedListener extends SeslBaseOnImmOffsetChangedListener { + void onOffsetChanged(SamsungAppBarLayout appBarLayout, int verticalOffset); } - mHeightProportion = ResourcesCompat.getFloat(mResources, mIsOneUI4 ? R.dimen.sesl4_appbar_height_proportion : R.dimen.sesl_appbar_height_proportion); + public static class SeslAppbarState { + private int mCurrentState = SESL_STATE_IDLE; + + void onStateChanged(int state) { + mCurrentState = state; + } - if (a.hasValue(R.styleable.SamsungAppBarLayout_seslUseCustomPadding)) { - mUseCustomPadding = a.getBoolean(R.styleable.SamsungAppBarLayout_seslUseCustomPadding, false); + public int getState() { + return mCurrentState; + } } - if (mUseCustomPadding) { - mBottomPadding = a.getDimensionPixelSize(R.styleable.SamsungAppBarLayout_android_paddingBottom, 0); - } else { - mBottomPadding = mIsOneUI4 ? 0 : mResources.getDimensionPixelOffset(R.dimen.sesl_extended_appbar_bottom_padding); + public SamsungAppBarLayout(@NonNull Context context) { + this(context, null); } - setPadding(0, 0, 0, mBottomPadding); + public SamsungAppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, R.attr.appBarLayoutStyle); + } - mCollapsedHeight = (float) (mResources.getDimensionPixelSize(mIsOneUI4 ? R.dimen.sesl4_action_bar_height_with_padding : R.dimen.sesl_action_bar_height_with_padding) + mBottomPadding); + @SuppressLint("RestrictedApi") + public SamsungAppBarLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(MaterialThemeOverlay.wrap(context, attrs, defStyleAttr, DEF_STYLE_RES), attrs, defStyleAttr); + context = getContext(); + mIsOneUI4 = context.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); + setOrientation(VERTICAL); - seslSetCollapsedHeight(mCollapsedHeight, false); + if (Build.VERSION.SDK_INT >= 21) { + ViewUtilsLollipop.setStateListAnimatorFromAttrs(this, attrs, defStyleAttr, DEF_STYLE_RES); + } - if (Build.VERSION.SDK_INT >= 21 && a.hasValue(R.styleable.SamsungAppBarLayout_elevation)) { - ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, a.getDimensionPixelSize(R.styleable.SamsungAppBarLayout_elevation, 0)); - } + final TypedArray a = ThemeEnforcement.obtainStyledAttributes(context, attrs, R.styleable.SamsungAppBarLayout, defStyleAttr, DEF_STYLE_RES); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - if (a.hasValue(R.styleable.SamsungAppBarLayout_android_keyboardNavigationCluster)) { - setKeyboardNavigationCluster(a.getBoolean(R.styleable.SamsungAppBarLayout_android_keyboardNavigationCluster, false)); - } - if (a.hasValue(R.styleable.SamsungAppBarLayout_android_touchscreenBlocksFocus)) { - setTouchscreenBlocksFocus(a.getBoolean(R.styleable.SamsungAppBarLayout_android_touchscreenBlocksFocus, false)); - } - } + mAppbarState = new SeslAppbarState(); + mResources = getResources(); + + if (a.hasValue(R.styleable.SamsungAppBarLayout_android_background)) { + mBackground = a.getDrawable(R.styleable.SamsungAppBarLayout_android_background);; + ViewCompat.setBackground(this, mBackground); + } else { + mBackground = null; + setBackgroundColor(mResources.getColor(mIsOneUI4 ? R.color.sesl4_action_bar_background_color : R.color.sesl_action_bar_background_color)); + } + + if (getBackground() instanceof ColorDrawable) { + ColorDrawable background = (ColorDrawable) getBackground(); + MaterialShapeDrawable materialShapeDrawable = new MaterialShapeDrawable(); + materialShapeDrawable.setFillColor(ColorStateList.valueOf(background.getColor())); + materialShapeDrawable.initializeElevationOverlay(context); + ViewCompat.setBackground(this, materialShapeDrawable); + } + + if (a.hasValue(R.styleable.SamsungAppBarLayout_expanded)) { + setExpanded(a.getBoolean(R.styleable.SamsungAppBarLayout_expanded, false), false, false); + } - liftOnScroll = a.getBoolean(R.styleable.SamsungAppBarLayout_liftOnScroll, false); - liftOnScrollTargetViewId = a.getResourceId(R.styleable.SamsungAppBarLayout_liftOnScrollTargetViewId, View.NO_ID); + if (a.hasValue(R.styleable.SamsungAppBarLayout_seslUseCustomHeight)) { + mUseCustomHeight = a.getBoolean(R.styleable.SamsungAppBarLayout_seslUseCustomHeight, false); + } + + if (a.hasValue(R.styleable.SamsungAppBarLayout_seslHeightProportion)) { + mSetCustomProportion = true; + mCustomHeightProportion = a.getFloat(R.styleable.SamsungAppBarLayout_seslHeightProportion, DEFAULT_HEIGHT_RATIO_TO_SCREEN); + } else { + mSetCustomProportion = false; + mCustomHeightProportion = DEFAULT_HEIGHT_RATIO_TO_SCREEN; + } + + mHeightProportion = ResourcesCompat.getFloat(mResources, mIsOneUI4 ? R.dimen.sesl4_appbar_height_proportion : R.dimen.sesl_appbar_height_proportion); + + if (a.hasValue(R.styleable.SamsungAppBarLayout_seslUseCustomPadding)) { + mUseCustomPadding = a.getBoolean(R.styleable.SamsungAppBarLayout_seslUseCustomPadding, false); + } + + if (mUseCustomPadding) { + mBottomPadding = a.getDimensionPixelSize(R.styleable.SamsungAppBarLayout_android_paddingBottom, 0); + } else { + mBottomPadding = mIsOneUI4 ? 0 : mResources.getDimensionPixelOffset(R.dimen.sesl_extended_appbar_bottom_padding); + } + + setPadding(0, 0, 0, mBottomPadding); - setStatusBarForeground(a.getDrawable(R.styleable.SamsungAppBarLayout_statusBarForeground)); - a.recycle(); + mCollapsedHeight = (float) (mResources.getDimensionPixelSize(mIsOneUI4 ? R.dimen.sesl4_action_bar_height_with_padding : R.dimen.sesl_action_bar_height_with_padding) + mBottomPadding); - ViewCompat.setOnApplyWindowInsetsListener(this, new androidx.core.view.OnApplyWindowInsetsListener() { - @Override - public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { - return onWindowInsetChanged(insets); - } - }); + seslSetCollapsedHeight(mCollapsedHeight, false); - mCurrentOrientation = mResources.getConfiguration().orientation; - mCurrentScreenHeight = mResources.getConfiguration().screenHeightDp; - } + if (Build.VERSION.SDK_INT >= 21 && a.hasValue(R.styleable.SamsungAppBarLayout_elevation)) { + ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, a.getDimensionPixelSize(R.styleable.SamsungAppBarLayout_elevation, 0)); + } - void updateInternalCollapsedHeight() { - if (useCollapsedHeight()) { - return; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (a.hasValue(R.styleable.SamsungAppBarLayout_android_keyboardNavigationCluster)) { + setKeyboardNavigationCluster(a.getBoolean(R.styleable.SamsungAppBarLayout_android_keyboardNavigationCluster, false)); + } + if (a.hasValue(R.styleable.SamsungAppBarLayout_android_touchscreenBlocksFocus)) { + setTouchscreenBlocksFocus(a.getBoolean(R.styleable.SamsungAppBarLayout_android_touchscreenBlocksFocus, false)); + } + } + + liftOnScroll = a.getBoolean(R.styleable.SamsungAppBarLayout_liftOnScroll, false); + liftOnScrollTargetViewId = a.getResourceId(R.styleable.SamsungAppBarLayout_liftOnScrollTargetViewId, View.NO_ID); + + setStatusBarForeground(a.getDrawable(R.styleable.SamsungAppBarLayout_statusBarForeground)); + a.recycle(); + + ViewCompat.setOnApplyWindowInsetsListener(this, new androidx.core.view.OnApplyWindowInsetsListener() { + @Override + public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { + return onWindowInsetChanged(insets); + } + }); + + mCurrentOrientation = mResources.getConfiguration().orientation; + mCurrentScreenHeight = mResources.getConfiguration().screenHeightDp; } - if (getImmBehavior() == null || !getCanScroll()) { - float height = (float) (getHeight() - getTotalScrollRange()); - if (height != seslGetCollapsedHeight() && height > 0.0f) { - Log.i(TAG, "Internal collapsedHeight/ oldCollapsedHeight :" + seslGetCollapsedHeight() + " newCollapsedHeight :" + height); - seslSetCollapsedHeight(height, false); - updateInternalHeight(); - } + + void updateInternalCollapsedHeight() { + if (useCollapsedHeight()) { + return; + } + if (getImmBehavior() == null || !getCanScroll()) { + float height = (float) (getHeight() - getTotalScrollRange()); + if (height != seslGetCollapsedHeight() && height > 0.0f) { + Log.i(TAG, "Internal collapsedHeight/ oldCollapsedHeight :" + seslGetCollapsedHeight() + " newCollapsedHeight :" + height); + seslSetCollapsedHeight(height, false); + updateInternalHeight(); + } + } } - } - void updateInternalCollapsedHeightOnce() { - if (useCollapsedHeight()) { - return; - } - if (getImmBehavior() == null || !getCanScroll()) { - Log.i(TAG, "update InternalCollapsedHeight from updateInternalHeight() : " + seslGetCollapsedHeight()); - seslSetCollapsedHeight(seslGetCollapsedHeight(), false); - } - } - - public SeslAppbarState seslGetAppBarState() { - return mAppbarState; - } - - public void seslSetCustomHeightProportion(boolean enabled, float proportion) { - if (proportion > 1.0f) { - Log.e(TAG, "Height proportion float range is 0..1"); - return; + void updateInternalCollapsedHeightOnce() { + if (useCollapsedHeight()) { + return; + } + if (getImmBehavior() == null || !getCanScroll()) { + Log.i(TAG, "update InternalCollapsedHeight from updateInternalHeight() : " + seslGetCollapsedHeight()); + seslSetCollapsedHeight(seslGetCollapsedHeight(), false); + } } - mUseCustomHeight = enabled; - mSetCustomProportion = enabled; - mSetCustomHeight = false; - mCustomHeightProportion = proportion; - updateInternalHeight(); - requestLayout(); - } - - public void seslSetCustomHeight(int height) { - mCustomHeight = height; - mUseCustomHeight = true; - mSetCustomHeight = true; - mSetCustomProportion = false; - - SamsungCoordinatorLayout.LayoutParams lp; - try { - lp = (SamsungCoordinatorLayout.LayoutParams) getLayoutParams(); - } catch (ClassCastException e) { - Log.e(TAG, Log.getStackTraceString(e)); - lp = null; - } - if (lp != null) { - lp.height = height; - setLayoutParams(lp); - } - } - @SuppressWarnings("FunctionalInterfaceClash") - public void addOnOffsetChangedListener(@Nullable BaseOnOffsetChangedListener listener) { - if (listeners == null) { - listeners = new ArrayList<>(); + public SeslAppbarState seslGetAppBarState() { + return mAppbarState; } - if (listener != null && !listeners.contains(listener)) { - listeners.add(listener); + + public void seslSetCustomHeightProportion(boolean enabled, float proportion) { + if (proportion > 1.0f) { + Log.e(TAG, "Height proportion float range is 0..1"); + return; + } + mUseCustomHeight = enabled; + mSetCustomProportion = enabled; + mSetCustomHeight = false; + mCustomHeightProportion = proportion; + updateInternalHeight(); + requestLayout(); } - } - - @SuppressWarnings("FunctionalInterfaceClash") - public void addOnOffsetChangedListener(OnOffsetChangedListener listener) { - addOnOffsetChangedListener((BaseOnOffsetChangedListener) listener); - } - public void seslAddOnImmOffsetChangedListener(@Nullable SeslBaseOnImmOffsetChangedListener listener) { - if (mImmOffsetListener == null) { - mImmOffsetListener = new ArrayList(); + public void seslSetCustomHeight(int height) { + mCustomHeight = height; + mUseCustomHeight = true; + mSetCustomHeight = true; + mSetCustomProportion = false; + + SamsungCoordinatorLayout.LayoutParams lp; + try { + lp = (SamsungCoordinatorLayout.LayoutParams) getLayoutParams(); + } catch (ClassCastException e) { + Log.e(TAG, Log.getStackTraceString(e)); + lp = null; + } + if (lp != null) { + lp.height = height; + setLayoutParams(lp); + } } - if (listener != null && !mImmOffsetListener.contains(listener)) { - mImmOffsetListener.add(listener); + + @SuppressWarnings("FunctionalInterfaceClash") + public void addOnOffsetChangedListener(@Nullable BaseOnOffsetChangedListener listener) { + if (listeners == null) { + listeners = new ArrayList<>(); + } + if (listener != null && !listeners.contains(listener)) { + listeners.add(listener); + } } - } - public void seslAddOnImmOffsetChangedListener(SeslOnImmOffsetChangedListener listener) { - seslAddOnImmOffsetChangedListener((SeslBaseOnImmOffsetChangedListener) listener); - } + @SuppressWarnings("FunctionalInterfaceClash") + public void addOnOffsetChangedListener(OnOffsetChangedListener listener) { + addOnOffsetChangedListener((BaseOnOffsetChangedListener) listener); + } - @SuppressWarnings("FunctionalInterfaceClash") - public void removeOnOffsetChangedListener(@Nullable BaseOnOffsetChangedListener listener) { - if (listeners != null && listener != null) { - listeners.remove(listener); + public void seslAddOnImmOffsetChangedListener(@Nullable SeslBaseOnImmOffsetChangedListener listener) { + if (mImmOffsetListener == null) { + mImmOffsetListener = new ArrayList(); + } + if (listener != null && !mImmOffsetListener.contains(listener)) { + mImmOffsetListener.add(listener); + } } - } - - @SuppressWarnings("FunctionalInterfaceClash") - public void removeOnOffsetChangedListener(OnOffsetChangedListener listener) { - removeOnOffsetChangedListener((BaseOnOffsetChangedListener) listener); - } - - public void seslRemoveOnImmOffsetChangedListener(SeslBaseOnImmOffsetChangedListener listener) { - if (mImmOffsetListener != null && listener != null) { - mImmOffsetListener.remove(listener); - } - } - - public void seslRemoveOnImmOffsetChangedListener(OnOffsetChangedListener listener) { - seslRemoveOnImmOffsetChangedListener((SeslBaseOnImmOffsetChangedListener) listener); - } - - public void setStatusBarForeground(@Nullable Drawable drawable) { - if (statusBarForeground != drawable) { - if (statusBarForeground != null) { - statusBarForeground.setCallback(null); - } - statusBarForeground = drawable != null ? drawable.mutate() : null; - if (statusBarForeground != null) { - if (statusBarForeground.isStateful()) { - statusBarForeground.setState(getDrawableState()); - } - DrawableCompat.setLayoutDirection(statusBarForeground, ViewCompat.getLayoutDirection(this)); - statusBarForeground.setVisible(getVisibility() == VISIBLE, false); - statusBarForeground.setCallback(this); - } - updateWillNotDraw(); - ViewCompat.postInvalidateOnAnimation(this); - } - } - - public void setStatusBarForegroundColor(@ColorInt int color) { - setStatusBarForeground(new ColorDrawable(color)); - } - public void setStatusBarForegroundResource(@DrawableRes int resId) { - setStatusBarForeground(AppCompatResources.getDrawable(getContext(), resId)); - } + public void seslAddOnImmOffsetChangedListener(SeslOnImmOffsetChangedListener listener) { + seslAddOnImmOffsetChangedListener((SeslBaseOnImmOffsetChangedListener) listener); + } - @Nullable - public Drawable getStatusBarForeground() { - return statusBarForeground; - } + @SuppressWarnings("FunctionalInterfaceClash") + public void removeOnOffsetChangedListener(@Nullable BaseOnOffsetChangedListener listener) { + if (listeners != null && listener != null) { + listeners.remove(listener); + } + } - @Override - public void draw(@NonNull Canvas canvas) { - super.draw(canvas); + @SuppressWarnings("FunctionalInterfaceClash") + public void removeOnOffsetChangedListener(OnOffsetChangedListener listener) { + removeOnOffsetChangedListener((BaseOnOffsetChangedListener) listener); + } - if (shouldDrawStatusBarForeground()) { - int saveCount = canvas.save(); - canvas.translate(0f, -currentOffset); - statusBarForeground.draw(canvas); - canvas.restoreToCount(saveCount); + public void seslRemoveOnImmOffsetChangedListener(SeslBaseOnImmOffsetChangedListener listener) { + if (mImmOffsetListener != null && listener != null) { + mImmOffsetListener.remove(listener); + } } - } - @Override - protected void drawableStateChanged() { - super.drawableStateChanged(); + public void seslRemoveOnImmOffsetChangedListener(OnOffsetChangedListener listener) { + seslRemoveOnImmOffsetChangedListener((SeslBaseOnImmOffsetChangedListener) listener); + } - final int[] state = getDrawableState(); + public void setStatusBarForeground(@Nullable Drawable drawable) { + if (statusBarForeground != drawable) { + if (statusBarForeground != null) { + statusBarForeground.setCallback(null); + } + statusBarForeground = drawable != null ? drawable.mutate() : null; + if (statusBarForeground != null) { + if (statusBarForeground.isStateful()) { + statusBarForeground.setState(getDrawableState()); + } + DrawableCompat.setLayoutDirection(statusBarForeground, ViewCompat.getLayoutDirection(this)); + statusBarForeground.setVisible(getVisibility() == VISIBLE, false); + statusBarForeground.setCallback(this); + } + updateWillNotDraw(); + ViewCompat.postInvalidateOnAnimation(this); + } + } - Drawable d = statusBarForeground; - if (d != null && d.isStateful() && d.setState(state)) { - invalidateDrawable(d); + public void setStatusBarForegroundColor(@ColorInt int color) { + setStatusBarForeground(new ColorDrawable(color)); } - } - @Override - protected boolean verifyDrawable(@NonNull Drawable who) { - return super.verifyDrawable(who) || who == statusBarForeground; - } + public void setStatusBarForegroundResource(@DrawableRes int resId) { + setStatusBarForeground(AppCompatResources.getDrawable(getContext(), resId)); + } - @Override - public void setVisibility(int visibility) { - super.setVisibility(visibility); + @Nullable + public Drawable getStatusBarForeground() { + return statusBarForeground; + } - final boolean visible = visibility == VISIBLE; - if (statusBarForeground != null) { - statusBarForeground.setVisible(visible, false); + @Override + public void draw(@NonNull Canvas canvas) { + super.draw(canvas); + + if (shouldDrawStatusBarForeground()) { + int saveCount = canvas.save(); + canvas.translate(0f, -currentOffset); + statusBarForeground.draw(canvas); + canvas.restoreToCount(saveCount); + } } - } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - updateInternalHeight(); + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); - super.onMeasure(widthMeasureSpec, heightMeasureSpec); + final int[] state = getDrawableState(); - final int heightMode = MeasureSpec.getMode(heightMeasureSpec); - if (heightMode != MeasureSpec.EXACTLY && ViewCompat.getFitsSystemWindows(this) && shouldOffsetFirstChild()) { - int newHeight = getMeasuredHeight(); - switch (heightMode) { - case MeasureSpec.AT_MOST: - newHeight = MathUtils.clamp(getMeasuredHeight() + getTopInset(), 0, MeasureSpec.getSize(heightMeasureSpec)); - break; - case MeasureSpec.UNSPECIFIED: - newHeight += getTopInset(); - break; - default: - } - setMeasuredDimension(getMeasuredWidth(), newHeight); + Drawable d = statusBarForeground; + if (d != null && d.isStateful() && d.setState(state)) { + invalidateDrawable(d); + } } - invalidateScrollRanges(); - } + @Override + protected boolean verifyDrawable(@NonNull Drawable who) { + return super.verifyDrawable(who) || who == statusBarForeground; + } - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - super.onLayout(changed, l, t, r, b); + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); - if (ViewCompat.getFitsSystemWindows(this) && shouldOffsetFirstChild()) { - final int topInset = getTopInset(); - for (int z = getChildCount() - 1; z >= 0; z--) { - ViewCompat.offsetTopAndBottom(getChildAt(z), topInset); - } + final boolean visible = visibility == VISIBLE; + if (statusBarForeground != null) { + statusBarForeground.setVisible(visible, false); + } } - invalidateScrollRanges(); + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + updateInternalHeight(); - haveChildWithInterpolator = false; - for (int i = 0, z = getChildCount(); i < z; i++) { - final View child = getChildAt(i); - final LayoutParams childLp = (LayoutParams) child.getLayoutParams(); - final Interpolator interpolator = childLp.getScrollInterpolator(); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + if (heightMode != MeasureSpec.EXACTLY && ViewCompat.getFitsSystemWindows(this) && shouldOffsetFirstChild()) { + int newHeight = getMeasuredHeight(); + switch (heightMode) { + case MeasureSpec.AT_MOST: + newHeight = MathUtils.clamp(getMeasuredHeight() + getTopInset(), 0, MeasureSpec.getSize(heightMeasureSpec)); + break; + case MeasureSpec.UNSPECIFIED: + newHeight += getTopInset(); + break; + default: + } + setMeasuredDimension(getMeasuredWidth(), newHeight); + } - if (interpolator != null) { - haveChildWithInterpolator = true; - break; - } + invalidateScrollRanges(); } - if (statusBarForeground != null) { - statusBarForeground.setBounds(0, 0, getWidth(), getTopInset()); - } + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); - if (!liftableOverride) { - setLiftableState(liftOnScroll || hasCollapsibleChild()); - } - } + if (ViewCompat.getFitsSystemWindows(this) && shouldOffsetFirstChild()) { + final int topInset = getTopInset(); + for (int z = getChildCount() - 1; z >= 0; z--) { + ViewCompat.offsetTopAndBottom(getChildAt(z), topInset); + } + } - private void updateWillNotDraw() { - setWillNotDraw(!shouldDrawStatusBarForeground()); - } + invalidateScrollRanges(); - private boolean shouldDrawStatusBarForeground() { - return statusBarForeground != null && getTopInset() > 0; - } + haveChildWithInterpolator = false; + for (int i = 0, z = getChildCount(); i < z; i++) { + final View child = getChildAt(i); + final LayoutParams childLp = (LayoutParams) child.getLayoutParams(); + final Interpolator interpolator = childLp.getScrollInterpolator(); - private boolean hasCollapsibleChild() { - for (int i = 0, z = getChildCount(); i < z; i++) { - if (((LayoutParams) getChildAt(i).getLayoutParams()).isCollapsible()) { - return true; - } - } - return false; - } - - private void invalidateScrollRanges() { - totalScrollRange = INVALID_SCROLL_RANGE; - downPreScrollRange = INVALID_SCROLL_RANGE; - downScrollRange = INVALID_SCROLL_RANGE; - } - - @Override - public void setOrientation(int orientation) { - if (orientation != VERTICAL) { - throw new IllegalArgumentException("AppBarLayout is always vertical and does not support horizontal orientation"); - } - super.setOrientation(orientation); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mIsDetachedState = false; - MaterialShapeUtils.setParentAbsoluteElevation(this); - } - - @Override - @NonNull - public SamsungCoordinatorLayout.Behavior getBehavior() { - return new SamsungAppBarLayout.Behavior(); - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public void setElevation(float elevation) { - super.setElevation(elevation); - - MaterialShapeUtils.setElevation(this, elevation); - } - - public void setExpanded(boolean expanded) { - setExpanded(expanded, ViewCompat.isLaidOut(this)); - } - - public void setExpanded(boolean expanded, boolean animate) { - setExpanded(expanded, animate, true); - } - - private void setExpanded(boolean expanded, boolean animate, boolean force) { - setLifted(!expanded); - pendingAction = (expanded ? PENDING_ACTION_EXPANDED : seslGetImmersiveScroll() ? PENDING_ACTION_COLLAPSED_IMM : PENDING_ACTION_COLLAPSED) | (animate ? PENDING_ACTION_ANIMATE_ENABLED : 0) | (force ? PENDING_ACTION_FORCE : 0); - requestLayout(); - } - - @Override - protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { - return p instanceof LayoutParams; - } - - @Override - protected LayoutParams generateDefaultLayoutParams() { - return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); - } - - @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - @Override - protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { - if (Build.VERSION.SDK_INT >= 19 && p instanceof LinearLayout.LayoutParams) { - return new LayoutParams((LinearLayout.LayoutParams) p); - } else if (p instanceof MarginLayoutParams) { - return new LayoutParams((MarginLayoutParams) p); - } - return new LayoutParams(p); - } - - public void seslReserveImmersiveDetachOption(int flag) { - if (flag != 0) { - mIsReservedImmersiveDetachOption = true; - mReservedFitSystemWindow = (flag & IMMERSIVE_DETACH_OPTION_SET_FIT_SYSTEM_WINDOW) != 0; - return; - } - mIsReservedImmersiveDetachOption = false; - } - - @Override - protected void onDetachedFromWindow() { - mIsDetachedState = true; - if (mIsReservedImmersiveDetachOption && getImmBehavior() != null && mReservedFitSystemWindow) { - Log.i(TAG, "fits system window Immersive detached"); - getImmBehavior().setupDecorFitsSystemWindow(true); - } - - super.onDetachedFromWindow(); - - clearLiftOnScrollTargetView(); - } - - boolean hasChildWithInterpolator() { - return haveChildWithInterpolator; - } - - public final int getTotalScrollRange() { - if (totalScrollRange != INVALID_SCROLL_RANGE) { - return totalScrollRange; - } - - int range = 0; - for (int i = 0, z = getChildCount(); i < z; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - final int childHeight = child.getMeasuredHeight(); - final int flags = lp.scrollFlags; - - if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { - range += childHeight + lp.topMargin + lp.bottomMargin; - - if (i == 0 && ViewCompat.getFitsSystemWindows(child)) { - range -= getTopInset(); - } - if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { - if (getCanScroll()) { - range += getTopInset() + mBottomPadding + seslGetTCScrollRange(); - } else { - range -= ViewCompat.getMinimumHeight(child); - } - break; - } - } else { - break; - } - } - return totalScrollRange = Math.max(0, range); - } - - boolean hasScrollableChildren() { - return getTotalScrollRange() != 0; - } - - int getUpNestedPreScrollRange() { - return getTotalScrollRange(); - } - - // kang - int getDownNestedPreScrollRange() { - int var1 = this.downPreScrollRange; - if (var1 != -1) { - return var1; - } else { - int var2 = this.getChildCount() - 1; - var1 = 0; - - int var3; - while(true) { - var3 = var1; - if (var2 < 0) { - break; - } - - View var4 = this.getChildAt(var2); - SamsungAppBarLayout.LayoutParams var5 = (SamsungAppBarLayout.LayoutParams)var4.getLayoutParams(); - int var6 = var4.getMeasuredHeight(); - var3 = var5.scrollFlags; - if ((var3 & 5) != 5) { - var3 = var1; - if (this.getCanScroll()) { - var3 = (int)((float)var1 + this.seslGetCollapsedHeight() + (float)this.seslGetTCScrollRange()); - } - break; - } - - int var7; - label36: { - var7 = var5.topMargin + var5.bottomMargin; - if ((var3 & 8) != 0) { - var3 = ViewCompat.getMinimumHeight(var4); - } else { - if ((var3 & 2) == 0) { - var3 = var7 + var6; - break label36; - } - - var3 = var6 - ViewCompat.getMinimumHeight(var4); - } + if (interpolator != null) { + haveChildWithInterpolator = true; + break; + } + } + + if (statusBarForeground != null) { + statusBarForeground.setBounds(0, 0, getWidth(), getTopInset()); + } - var3 += var7; - } - - var7 = var3; - if (var2 == 0) { - var7 = var3; - if (ViewCompat.getFitsSystemWindows(var4)) { - var7 = Math.min(var3, var6 - this.getTopInset()); - } + if (!liftableOverride) { + setLiftableState(liftOnScroll || hasCollapsibleChild()); } - - var1 += var7; - --var2; - } - - var1 = Math.max(0, var3); - this.downPreScrollRange = var1; - return var1; - } - } - // kang - - int getDownNestedScrollRange() { - if (downScrollRange != INVALID_SCROLL_RANGE) { - return downScrollRange; } - int range = 0; - for (int i = 0, z = getChildCount(); i < z; i++) { - final View child = getChildAt(i); - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - int childHeight = child.getMeasuredHeight(); - childHeight += lp.topMargin + lp.bottomMargin; + private void updateWillNotDraw() { + setWillNotDraw(!shouldDrawStatusBarForeground()); + } - final int flags = lp.scrollFlags; - - if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { - range += childHeight; + private boolean shouldDrawStatusBarForeground() { + return statusBarForeground != null && getTopInset() > 0; + } - if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { - int newRange; - if (!mIsCanScroll || !(child instanceof SamsungCollapsingToolbarLayout)) { - newRange = ViewCompat.getMinimumHeight(child); - } else { - newRange = ((SamsungCollapsingToolbarLayout) child).seslGetMinimumHeightWithoutMargin(); - } - range -= newRange; - break; + private boolean hasCollapsibleChild() { + for (int i = 0, z = getChildCount(); i < z; i++) { + if (((LayoutParams) getChildAt(i).getLayoutParams()).isCollapsible()) { + return true; + } } - } else { - break; - } + return false; } - return downScrollRange = Math.max(0, range); - } - void onOffsetChanged(int offset) { - currentOffset = offset; + private void invalidateScrollRanges() { + totalScrollRange = INVALID_SCROLL_RANGE; + downPreScrollRange = INVALID_SCROLL_RANGE; + downScrollRange = INVALID_SCROLL_RANGE; + } - int totalScrollRange = getTotalScrollRange(); - int height = getHeight() - ((int) seslGetCollapsedHeight()); - if (Math.abs(offset) >= totalScrollRange) { - if (getCanScroll()) { - if (mAppbarState.getState() != SESL_STATE_HIDE) { - mAppbarState.onStateChanged(SESL_STATE_HIDE); + @Override + public void setOrientation(int orientation) { + if (orientation != VERTICAL) { + throw new IllegalArgumentException("AppBarLayout is always vertical and does not support horizontal orientation"); } - } else if (mAppbarState.getState() != SESL_STATE_COLLAPSED) { - mAppbarState.onStateChanged(SESL_STATE_COLLAPSED); - } - } else if (Math.abs(offset) >= height) { - if (mAppbarState.getState() != SESL_STATE_COLLAPSED) { - mAppbarState.onStateChanged(SESL_STATE_COLLAPSED); - } - } else if (Math.abs(offset) == 0) { - if (mAppbarState.getState() != SESL_STATE_EXPANDED) { - mAppbarState.onStateChanged(SESL_STATE_EXPANDED); - } - } else if (mAppbarState.getState() != SESL_STATE_IDLE) { - mAppbarState.onStateChanged(SESL_STATE_IDLE); + super.setOrientation(orientation); } - if (!willNotDraw()) { - ViewCompat.postInvalidateOnAnimation(this); + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + mIsDetachedState = false; + MaterialShapeUtils.setParentAbsoluteElevation(this); } - if (listeners != null) { - for (int i = 0, z = listeners.size(); i < z; i++) { - final BaseOnOffsetChangedListener listener = listeners.get(i); - if (listener != null) { - listener.onOffsetChanged(this, offset); - } - } + @Override + @NonNull + public SamsungCoordinatorLayout.Behavior getBehavior() { + return new SamsungAppBarLayout.Behavior(); } - } - void onImmOffsetChanged(int offset) { - if (!willNotDraw()) { - ViewCompat.postInvalidateOnAnimation(this); + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + @Override + public void setElevation(float elevation) { + super.setElevation(elevation); + + MaterialShapeUtils.setElevation(this, elevation); } - if (mImmOffsetListener != null) { - for (int i = 0, z = mImmOffsetListener.size(); i < z; i++) { - final SeslBaseOnImmOffsetChangedListener listener = mImmOffsetListener.get(i); - if (listener != null) { - listener.onOffsetChanged(this, offset); - } - } + public void setExpanded(boolean expanded) { + setExpanded(expanded, ViewCompat.isLaidOut(this)); } - } - public final int getMinimumHeightForVisibleOverlappingContent() { - final int topInset = getTopInset(); - final int minHeight = ViewCompat.getMinimumHeight(this); - if (minHeight != 0) { - return (minHeight * 2) + topInset; + public void setExpanded(boolean expanded, boolean animate) { + setExpanded(expanded, animate, true); } - final int childCount = getChildCount(); - final int lastChildMinHeight = childCount >= 1 ? ViewCompat.getMinimumHeight(getChildAt(childCount - 1)) : 0; - if (lastChildMinHeight != 0) { - return (lastChildMinHeight * 2) + topInset; + private void setExpanded(boolean expanded, boolean animate, boolean force) { + setLifted(!expanded); + pendingAction = (expanded ? PENDING_ACTION_EXPANDED : seslGetImmersiveScroll() ? PENDING_ACTION_COLLAPSED_IMM : PENDING_ACTION_COLLAPSED) | (animate ? PENDING_ACTION_ANIMATE_ENABLED : 0) | (force ? PENDING_ACTION_FORCE : 0); + requestLayout(); } - return getHeight() / 3; - } - - @Override - protected int[] onCreateDrawableState(int extraSpace) { - if (tmpStatesArray == null) { - tmpStatesArray = new int[4]; - } - final int[] extraStates = tmpStatesArray; - final int[] states = super.onCreateDrawableState(extraSpace + extraStates.length); - - extraStates[0] = liftable ? R.attr.state_liftable : -R.attr.state_liftable; - extraStates[1] = liftable && lifted ? R.attr.state_lifted : -R.attr.state_lifted; - - extraStates[2] = liftable ? R.attr.state_collapsible : -R.attr.state_collapsible; - extraStates[3] = liftable && lifted ? R.attr.state_collapsed : -R.attr.state_collapsed; - - return mergeDrawableStates(states, extraStates); - } - - public boolean setLiftable(boolean liftable) { - liftableOverride = true; - return setLiftableState(liftable); - } - - public void setLiftableOverrideEnabled(boolean enabled) { - liftableOverride = enabled; - } - - private boolean setLiftableState(boolean liftable) { - if (this.liftable != liftable) { - this.liftable = liftable; - refreshDrawableState(); - return true; - } - return false; - } - - public boolean setLifted(boolean lifted) { - return setLiftedState(lifted); - } - - public boolean isLifted() { - return lifted; - } - - boolean setLiftedState(boolean lifted) { - if (this.lifted == lifted) { - return false; + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + return p instanceof LayoutParams; } - this.lifted = lifted; - refreshDrawableState(); - if (liftOnScroll && getBackground() instanceof MaterialShapeDrawable) { - startLiftOnScrollElevationOverlayAnimation((MaterialShapeDrawable) getBackground(), lifted); + + @Override + protected LayoutParams generateDefaultLayoutParams() { + return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); } - return true; - } - private void startLiftOnScrollElevationOverlayAnimation(@NonNull final MaterialShapeDrawable background, boolean lifted) { - float appBarElevation = getResources().getDimension(R.dimen.sesl_appbar_elevation); - float fromElevation = lifted ? 0 : appBarElevation; - float toElevation = lifted ? appBarElevation : 0; - - if (elevationOverlayAnimator != null) { - elevationOverlayAnimator.cancel(); + @Override + public LayoutParams generateLayoutParams(AttributeSet attrs) { + return new LayoutParams(getContext(), attrs); } - elevationOverlayAnimator = ValueAnimator.ofFloat(fromElevation, toElevation); - elevationOverlayAnimator.setDuration(getResources().getInteger(R.integer.app_bar_elevation_anim_duration)); - elevationOverlayAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR); - elevationOverlayAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) { - float elevation = (float) valueAnimator.getAnimatedValue(); - background.setElevation(elevation); - } - }); - elevationOverlayAnimator.start(); - } + @Override + protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { + if (Build.VERSION.SDK_INT >= 19 && p instanceof LinearLayout.LayoutParams) { + return new LayoutParams((LinearLayout.LayoutParams) p); + } else if (p instanceof MarginLayoutParams) { + return new LayoutParams((MarginLayoutParams) p); + } + return new LayoutParams(p); + } - public void setLiftOnScroll(boolean liftOnScroll) { - this.liftOnScroll = liftOnScroll; - } + public void seslReserveImmersiveDetachOption(int flag) { + if (flag != 0) { + mIsReservedImmersiveDetachOption = true; + mReservedFitSystemWindow = (flag & IMMERSIVE_DETACH_OPTION_SET_FIT_SYSTEM_WINDOW) != 0; + return; + } + mIsReservedImmersiveDetachOption = false; + } - public boolean isLiftOnScroll() { - return liftOnScroll; - } - - public void setLiftOnScrollTargetViewId(@IdRes int liftOnScrollTargetViewId) { - this.liftOnScrollTargetViewId = liftOnScrollTargetViewId; - clearLiftOnScrollTargetView(); - } - - @IdRes - public int getLiftOnScrollTargetViewId() { - return liftOnScrollTargetViewId; - } - - boolean shouldLift(@Nullable View defaultScrollingView) { - View scrollingView = findLiftOnScrollTargetView(defaultScrollingView); - if (scrollingView == null) { - scrollingView = defaultScrollingView; - } - return scrollingView != null && (scrollingView.canScrollVertically(-1) || scrollingView.getScrollY() > 0); - } - - @Nullable - private View findLiftOnScrollTargetView(@Nullable View defaultScrollingView) { - if (liftOnScrollTargetView == null && liftOnScrollTargetViewId != View.NO_ID) { - View targetView = null; - if (defaultScrollingView != null) { - targetView = defaultScrollingView.findViewById(liftOnScrollTargetViewId); - } - if (targetView == null && getParent() instanceof ViewGroup) { - targetView = ((ViewGroup) getParent()).findViewById(liftOnScrollTargetViewId); - } - if (targetView != null) { - liftOnScrollTargetView = new WeakReference<>(targetView); - } - } - return liftOnScrollTargetView != null ? liftOnScrollTargetView.get() : null; - } - - private void clearLiftOnScrollTargetView() { - if (liftOnScrollTargetView != null) { - liftOnScrollTargetView.clear(); - } - liftOnScrollTargetView = null; - } - - @Deprecated - public void setTargetElevation(float elevation) { - if (Build.VERSION.SDK_INT >= 21) { - ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, elevation); - } - } - - @Deprecated - public float getTargetElevation() { - return 0; - } - - int getPendingAction() { - return pendingAction; - } - - void resetPendingAction() { - pendingAction = PENDING_ACTION_NONE; - } - - final int getTopInset() { - return lastInsets != null ? lastInsets.getSystemWindowInsetTop() : 0; - } - - private boolean shouldOffsetFirstChild() { - if (getChildCount() > 0) { - final View firstChild = getChildAt(0); - return firstChild.getVisibility() != GONE && !ViewCompat.getFitsSystemWindows(firstChild); - } - return false; - } - - WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) { - WindowInsetsCompat newInsets = null; - - if (ViewCompat.getFitsSystemWindows(this)) { - newInsets = insets; - } - - if (!ObjectsCompat.equals(lastInsets, newInsets)) { - lastInsets = newInsets; - updateWillNotDraw(); - requestLayout(); - } - - return insets; - } - - protected int getCurrentOrientation() { - return mCurrentOrientation; - } - - @Deprecated - public void seslRestoreTopAndBottom(View view) { - seslRestoreTopAndBottom(); - } + @Override + protected void onDetachedFromWindow() { + mIsDetachedState = true; + if (mIsReservedImmersiveDetachOption && getImmBehavior() != null && mReservedFitSystemWindow) { + Log.i(TAG, "fits system window Immersive detached"); + getImmBehavior().setupDecorFitsSystemWindow(true); + } - private SeslImmersiveScrollBehavior getImmBehavior() { - ViewGroup.LayoutParams lp = getLayoutParams(); - if (lp instanceof SamsungCoordinatorLayout.LayoutParams) { - SamsungCoordinatorLayout.Behavior behavior = ((SamsungCoordinatorLayout.LayoutParams) lp).getBehavior(); - if (behavior instanceof SeslImmersiveScrollBehavior) { - return (SeslImmersiveScrollBehavior) behavior; - } + super.onDetachedFromWindow(); + + clearLiftOnScrollTargetView(); + } + + boolean hasChildWithInterpolator() { + return haveChildWithInterpolator; } - return null; - } + public final int getTotalScrollRange() { + if (totalScrollRange != INVALID_SCROLL_RANGE) { + return totalScrollRange; + } - public boolean seslHaveImmersiveBehavior() { - return getImmBehavior() != null; - } + int range = 0; + for (int i = 0, z = getChildCount(); i < z; i++) { + final View child = getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + final int childHeight = child.getMeasuredHeight(); + final int flags = lp.scrollFlags; - public void seslSetWindowInsetsAnimationCallback(Object callback) { - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - if (callback == null) { - behavior.setWindowInsetsAnimationCallback(this, null); - } - if (callback instanceof WindowInsetsAnimationCompat.Callback) { - behavior.setWindowInsetsAnimationCallback(this, (WindowInsetsAnimationCompat.Callback) callback); - } + if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { + range += childHeight + lp.topMargin + lp.bottomMargin; + + if (i == 0 && ViewCompat.getFitsSystemWindows(child)) { + range -= getTopInset(); + } + if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { + if (getCanScroll()) { + range += getTopInset() + mBottomPadding + seslGetTCScrollRange(); + } else { + range -= ViewCompat.getMinimumHeight(child); + } + break; + } + } else { + break; + } + } + return totalScrollRange = Math.max(0, range); } - } - public void seslRestoreTopAndBottom() { - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - behavior.seslRestoreTopAndBottom(); + boolean hasScrollableChildren() { + return getTotalScrollRange() != 0; } - } - public void seslRestoreTopAndBottom(boolean restore) { - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - behavior.seslRestoreTopAndBottom(restore); + int getUpNestedPreScrollRange() { + return getTotalScrollRange(); } - } - public void resetAppBarAndInsets() { - seslResetAppBarAndInsets(true); - } + // kang + int getDownNestedPreScrollRange() { + int var1 = this.downPreScrollRange; + if (var1 != -1) { + return var1; + } else { + int var2 = this.getChildCount() - 1; + var1 = 0; + + int var3; + while(true) { + var3 = var1; + if (var2 < 0) { + break; + } + + View var4 = this.getChildAt(var2); + SamsungAppBarLayout.LayoutParams var5 = (SamsungAppBarLayout.LayoutParams)var4.getLayoutParams(); + int var6 = var4.getMeasuredHeight(); + var3 = var5.scrollFlags; + if ((var3 & 5) != 5) { + var3 = var1; + if (this.getCanScroll()) { + var3 = (int)((float)var1 + this.seslGetCollapsedHeight() + (float)this.seslGetTCScrollRange()); + } + break; + } + + int var7; + label36: { + var7 = var5.topMargin + var5.bottomMargin; + if ((var3 & 8) != 0) { + var3 = ViewCompat.getMinimumHeight(var4); + } else { + if ((var3 & 2) == 0) { + var3 = var7 + var6; + break label36; + } + + var3 = var6 - ViewCompat.getMinimumHeight(var4); + } + + var3 += var7; + } + + var7 = var3; + if (var2 == 0) { + var7 = var3; + if (ViewCompat.getFitsSystemWindows(var4)) { + var7 = Math.min(var3, var6 - this.getTopInset()); + } + } + + var1 += var7; + --var2; + } - public void seslResetAppBarAndInsets(boolean force) { - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - Log.i(TAG, "seslResetAppBarAndInsets() force = " + force); - behavior.seslRestoreTopAndBottom(); - behavior.showWindowInset(force); + var1 = Math.max(0, var3); + this.downPreScrollRange = var1; + return var1; + } } - } + // kang + + int getDownNestedScrollRange() { + if (downScrollRange != INVALID_SCROLL_RANGE) { + return downScrollRange; + } - public void seslCancelWindowInsetsAnimationController() { - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - Log.i(TAG, "seslCancelWindowInsetsAnimationController"); - behavior.cancelWindowInsetsAnimationController(); + int range = 0; + for (int i = 0, z = getChildCount(); i < z; i++) { + final View child = getChildAt(i); + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + int childHeight = child.getMeasuredHeight(); + childHeight += lp.topMargin + lp.bottomMargin; + + final int flags = lp.scrollFlags; + + if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { + range += childHeight; + + if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { + int newRange; + if (!mIsCanScroll || !(child instanceof SamsungCollapsingToolbarLayout)) { + newRange = ViewCompat.getMinimumHeight(child); + } else { + newRange = ((SamsungCollapsingToolbarLayout) child).seslGetMinimumHeightWithoutMargin(); + } + range -= newRange; + break; + } + } else { + break; + } + } + return downScrollRange = Math.max(0, range); } - } - public void seslImmHideStatusBarForLandscape(boolean hide) { - mImmHideStatusBar = hide; - } + void onOffsetChanged(int offset) { + currentOffset = offset; - boolean isImmHideStatusBarForLandscape() { - return mImmHideStatusBar; - } + int totalScrollRange = getTotalScrollRange(); + int height = getHeight() - ((int) seslGetCollapsedHeight()); + if (Math.abs(offset) >= totalScrollRange) { + if (getCanScroll()) { + if (mAppbarState.getState() != SESL_STATE_HIDE) { + mAppbarState.onStateChanged(SESL_STATE_HIDE); + } + } else if (mAppbarState.getState() != SESL_STATE_COLLAPSED) { + mAppbarState.onStateChanged(SESL_STATE_COLLAPSED); + } + } else if (Math.abs(offset) >= height) { + if (mAppbarState.getState() != SESL_STATE_COLLAPSED) { + mAppbarState.onStateChanged(SESL_STATE_COLLAPSED); + } + } else if (Math.abs(offset) == 0) { + if (mAppbarState.getState() != SESL_STATE_EXPANDED) { + mAppbarState.onStateChanged(SESL_STATE_EXPANDED); + } + } else if (mAppbarState.getState() != SESL_STATE_IDLE) { + mAppbarState.onStateChanged(SESL_STATE_IDLE); + } - @Deprecated - public void seslSetBottomView(View view, View bottomView) { - seslSetBottomView(bottomView); - } + if (!willNotDraw()) { + ViewCompat.postInvalidateOnAnimation(this); + } - public void seslSetBottomView(View bottomView) { - if (bottomView == null) { - Log.w(TAG, "bottomView is null"); + if (listeners != null) { + for (int i = 0, z = listeners.size(); i < z; i++) { + final BaseOnOffsetChangedListener listener = listeners.get(i); + if (listener != null) { + listener.onOffsetChanged(this, offset); + } + } + } } - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - behavior.seslSetBottomView(bottomView); + + void onImmOffsetChanged(int offset) { + if (!willNotDraw()) { + ViewCompat.postInvalidateOnAnimation(this); + } + + if (mImmOffsetListener != null) { + for (int i = 0, z = mImmOffsetListener.size(); i < z; i++) { + final SeslBaseOnImmOffsetChangedListener listener = mImmOffsetListener.get(i); + if (listener != null) { + listener.onOffsetChanged(this, offset); + } + } + } } - } - protected void internalActivateImmersiveScroll(boolean activate, boolean byUser) { - mIsActivatedImmersiveScroll = activate; - mIsActivatedByUser = byUser; + public final int getMinimumHeightForVisibleOverlappingContent() { + final int topInset = getTopInset(); + final int minHeight = ViewCompat.getMinimumHeight(this); + if (minHeight != 0) { + return (minHeight * 2) + topInset; + } + + final int childCount = getChildCount(); + final int lastChildMinHeight = childCount >= 1 ? ViewCompat.getMinimumHeight(getChildAt(childCount - 1)) : 0; + if (lastChildMinHeight != 0) { + return (lastChildMinHeight * 2) + topInset; + } - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - Log.i(TAG, "internalActivateImmersiveScroll : " + activate + " , byUser : " + byUser + " , behavior : " + behavior); - if (behavior == null) { - return; + return getHeight() / 3; } - if (!activate || behavior.isAppBarHide()) { - behavior.seslRestoreTopAndBottom(mRestoreAnim); + + @Override + protected int[] onCreateDrawableState(int extraSpace) { + if (tmpStatesArray == null) { + tmpStatesArray = new int[4]; + } + final int[] extraStates = tmpStatesArray; + final int[] states = super.onCreateDrawableState(extraSpace + extraStates.length); + + extraStates[0] = liftable ? R.attr.state_liftable : -R.attr.state_liftable; + extraStates[1] = liftable && lifted ? R.attr.state_lifted : -R.attr.state_lifted; + + extraStates[2] = liftable ? R.attr.state_collapsible : -R.attr.state_collapsible; + extraStates[3] = liftable && lifted ? R.attr.state_collapsed : -R.attr.state_collapsed; + + return mergeDrawableStates(states, extraStates); } - } - public void seslActivateImmersiveScroll(boolean activate, boolean byUser) { - if (isDexEnabled()) { - Log.i(TAG, "Dex Enabled Set false ImmersiveScroll"); - activate = false; + public boolean setLiftable(boolean liftable) { + liftableOverride = true; + return setLiftableState(liftable); } - mRestoreAnim = byUser; - internalActivateImmersiveScroll(activate, true); + public void setLiftableOverrideEnabled(boolean enabled) { + liftableOverride = enabled; + } - boolean z = true; - SeslImmersiveScrollBehavior behavior = getImmBehavior(); - if (behavior != null) { - z = behavior.dispatchImmersiveScrollEnable(); + private boolean setLiftableState(boolean liftable) { + if (this.liftable != liftable) { + this.liftable = liftable; + refreshDrawableState(); + return true; + } + return false; } - if (z || !activate) { - setCanScroll(activate); + public boolean setLifted(boolean lifted) { + return setLiftedState(lifted); } - } - public void seslSetImmersiveScroll(boolean activate, boolean byUser) { - seslActivateImmersiveScroll(activate, byUser); - } + public boolean isLifted() { + return lifted; + } - public void seslActivateImmersiveScroll(boolean activate) { - seslActivateImmersiveScroll(activate, true); - } + boolean setLiftedState(boolean lifted) { + if (this.lifted == lifted) { + return false; + } + this.lifted = lifted; + refreshDrawableState(); + if (liftOnScroll && getBackground() instanceof MaterialShapeDrawable) { + startLiftOnScrollElevationOverlayAnimation((MaterialShapeDrawable) getBackground(), lifted); + } + return true; + } - public void seslSetImmersiveScroll(boolean activate) { - seslActivateImmersiveScroll(activate); - } + private void startLiftOnScrollElevationOverlayAnimation(@NonNull final MaterialShapeDrawable background, boolean lifted) { + float appBarElevation = getResources().getDimension(R.dimen.sesl_appbar_elevation); + float fromElevation = lifted ? 0 : appBarElevation; + float toElevation = lifted ? appBarElevation : 0; - public boolean isActivatedImmsersiveScroll() { - return mIsActivatedImmersiveScroll; - } + if (elevationOverlayAnimator != null) { + elevationOverlayAnimator.cancel(); + } - public boolean seslGetImmersiveScroll() { - return isActivatedImmsersiveScroll(); - } + elevationOverlayAnimator = ValueAnimator.ofFloat(fromElevation, toElevation); + elevationOverlayAnimator.setDuration(getResources().getInteger(R.integer.app_bar_elevation_anim_duration)); + elevationOverlayAnimator.setInterpolator(AnimationUtils.LINEAR_INTERPOLATOR); + elevationOverlayAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull ValueAnimator valueAnimator) { + float elevation = (float) valueAnimator.getAnimatedValue(); + background.setElevation(elevation); + } + }); + elevationOverlayAnimator.start(); + } - protected boolean isImmersiveActivatedByUser() { - return mIsActivatedByUser; - } + public void setLiftOnScroll(boolean liftOnScroll) { + this.liftOnScroll = liftOnScroll; + } - protected void setCanScroll(boolean canScroll) { - if (mIsCanScroll != canScroll) { - mIsCanScroll = canScroll; - invalidateScrollRanges(); - requestLayout(); + public boolean isLiftOnScroll() { + return liftOnScroll; } - } - public void seslSetTCScrollRange(int range) { - mSeslTCScrollRange = range; - } + public void setLiftOnScrollTargetViewId(@IdRes int liftOnScrollTargetViewId) { + this.liftOnScrollTargetViewId = liftOnScrollTargetViewId; + clearLiftOnScrollTargetView(); + } - protected int seslGetTCScrollRange() { - return mSeslTCScrollRange; - } + @IdRes + public int getLiftOnScrollTargetViewId() { + return liftOnScrollTargetViewId; + } - protected boolean getCanScroll() { - return mIsCanScroll; - } + boolean shouldLift(@Nullable View defaultScrollingView) { + View scrollingView = findLiftOnScrollTargetView(defaultScrollingView); + if (scrollingView == null) { + scrollingView = defaultScrollingView; + } + return scrollingView != null && (scrollingView.canScrollVertically(-1) || scrollingView.getScrollY() > 0); + } - public void seslSetCollapsedHeight(float height) { - Log.i(TAG, "seslSetCollapsedHeight, height : " + height); - seslSetCollapsedHeight(height, true); - } + @Nullable + private View findLiftOnScrollTargetView(@Nullable View defaultScrollingView) { + if (liftOnScrollTargetView == null && liftOnScrollTargetViewId != View.NO_ID) { + View targetView = null; + if (defaultScrollingView != null) { + targetView = defaultScrollingView.findViewById(liftOnScrollTargetViewId); + } + if (targetView == null && getParent() instanceof ViewGroup) { + targetView = ((ViewGroup) getParent()).findViewById(liftOnScrollTargetViewId); + } + if (targetView != null) { + liftOnScrollTargetView = new WeakReference<>(targetView); + } + } + return liftOnScrollTargetView != null ? liftOnScrollTargetView.get() : null; + } - private void seslSetCollapsedHeight(float height, boolean custom) { - mUseCollapsedHeight = custom; - mCollapsedHeight = height; - } + private void clearLiftOnScrollTargetView() { + if (liftOnScrollTargetView != null) { + liftOnScrollTargetView.clear(); + } + liftOnScrollTargetView = null; + } - void internalProportion(float proportion) { - if (!mUseCustomHeight && mHeightProportion != proportion) { - mHeightProportion = proportion; - updateInternalHeight(); + @Deprecated + public void setTargetElevation(float elevation) { + if (Build.VERSION.SDK_INT >= 21) { + ViewUtilsLollipop.setDefaultAppBarLayoutStateListAnimator(this, elevation); + } } - } - void setImmersiveTopInset(int top) { - mImmersiveTopInset = top; - } + @Deprecated + public float getTargetElevation() { + return 0; + } - final int getImmersiveTopInset() { - if (mIsCanScroll) { - return mImmersiveTopInset; + int getPendingAction() { + return pendingAction; } - return 0; - } - public float seslGetCollapsedHeight() { - return mCollapsedHeight + ((float) getImmersiveTopInset()); - } + void resetPendingAction() { + pendingAction = PENDING_ACTION_NONE; + } - public float seslGetHeightProPortion() { - return mHeightProportion; - } + final int getTopInset() { + return lastInsets != null ? lastInsets.getSystemWindowInsetTop() : 0; + } + + private boolean shouldOffsetFirstChild() { + if (getChildCount() > 0) { + final View firstChild = getChildAt(0); + return firstChild.getVisibility() != GONE && !ViewCompat.getFitsSystemWindows(firstChild); + } + return false; + } + + WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) { + WindowInsetsCompat newInsets = null; - boolean useCollapsedHeight() { - return mUseCollapsedHeight; - } + if (ViewCompat.getFitsSystemWindows(this)) { + newInsets = insets; + } - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); + if (!ObjectsCompat.equals(lastInsets, newInsets)) { + lastInsets = newInsets; + updateWillNotDraw(); + requestLayout(); + } - if (mBackground != null) { - setBackgroundDrawable(mBackground == getBackground() ? mBackground : getBackground()); - } else if (getBackground() != null) { - mBackground = getBackground(); - setBackgroundDrawable(mBackground); - } else { - mBackground = null; - setBackgroundColor(mResources.getColor(R.color.sesl_action_bar_background_color)); + return insets; } - if (mCurrentScreenHeight != newConfig.screenHeightDp || mCurrentOrientation != newConfig.orientation) { - if (!mUseCustomPadding && !mUseCollapsedHeight) { - Log.i(TAG, "Update bottom padding"); - mBottomPadding = mResources.getDimensionPixelSize(R.dimen.sesl_extended_appbar_bottom_padding); - setPadding(0, 0, 0, mBottomPadding); - mCollapsedHeight = (float) (mResources.getDimensionPixelSize(mIsOneUI4 ? R.dimen.sesl4_action_bar_height_with_padding : R.dimen.sesl_action_bar_height_with_padding) + mBottomPadding); - seslSetCollapsedHeight(mCollapsedHeight, false); - } else if (mUseCustomPadding && mBottomPadding == 0 && !mUseCollapsedHeight) { - mCollapsedHeight = (float) mResources.getDimensionPixelSize(mIsOneUI4 ? R.dimen.sesl4_action_bar_height_with_padding : R.dimen.sesl_action_bar_height_with_padding); - seslSetCollapsedHeight(mCollapsedHeight, false); - } + protected int getCurrentOrientation() { + return mCurrentOrientation; } - if (!mSetCustomProportion) { - mHeightProportion = ResourcesCompat.getFloat(mResources, mIsOneUI4 ? R.dimen.sesl4_appbar_height_proportion : R.dimen.sesl_appbar_height_proportion); + @Deprecated + public void seslRestoreTopAndBottom(View view) { + seslRestoreTopAndBottom(); } - updateInternalHeight(); + private SeslImmersiveScrollBehavior getImmBehavior() { + ViewGroup.LayoutParams lp = getLayoutParams(); + if (lp instanceof SamsungCoordinatorLayout.LayoutParams) { + SamsungCoordinatorLayout.Behavior behavior = ((SamsungCoordinatorLayout.LayoutParams) lp).getBehavior(); + if (behavior instanceof SeslImmersiveScrollBehavior) { + return (SeslImmersiveScrollBehavior) behavior; + } + } - if (lifted || (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT && newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)) { - setExpanded(false, false, true); - } else { - setExpanded(true, false, true); + return null; } - mCurrentOrientation = newConfig.orientation; - mCurrentScreenHeight = newConfig.screenHeightDp; - } + public boolean seslHaveImmersiveBehavior() { + return getImmBehavior() != null; + } - @Override - public boolean dispatchGenericMotionEvent(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_SCROLL) { - if (liftOnScrollTargetView != null) { - if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) { - setExpanded(false); - } else if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) > 0.0f && !canScrollVertically(-1)) { - setExpanded(true); + public void seslSetWindowInsetsAnimationCallback(Object callback) { + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + if (callback == null) { + behavior.setWindowInsetsAnimationCallback(this, null); + } + if (callback instanceof WindowInsetsAnimationCompat.Callback) { + behavior.setWindowInsetsAnimationCallback(this, (WindowInsetsAnimationCompat.Callback) callback); + } } - } else if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) { - setExpanded(false); - } else if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) > 0.0f) { - setExpanded(true); - } } - return super.dispatchGenericMotionEvent(event); - } - - private void updateInternalHeight() { - int windowHeight = getWindowHeight(); - - float proportion; - if (mUseCustomHeight) { - if (mCustomHeightProportion != 0.0f) { - proportion = mCustomHeightProportion + (getCanScroll() ? getDifferImmHeightRatio() : 0.0f); - } else { - proportion = 0.0f; - } - } else { - proportion = mHeightProportion; + public void seslRestoreTopAndBottom() { + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + behavior.seslRestoreTopAndBottom(); + } } - float collapsedHeight = ((float) windowHeight) * proportion; - if (collapsedHeight == 0.0f) { - updateInternalCollapsedHeightOnce(); - collapsedHeight = seslGetCollapsedHeight(); + public void seslRestoreTopAndBottom(boolean restore) { + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + behavior.seslRestoreTopAndBottom(restore); + } } - SamsungCoordinatorLayout.LayoutParams lp; - try { - lp = (SamsungCoordinatorLayout.LayoutParams) getLayoutParams(); - } catch (ClassCastException e) { - Log.e(TAG, Log.getStackTraceString(e)); - lp = null; + public void resetAppBarAndInsets() { + seslResetAppBarAndInsets(true); } - String logStr = "[updateInternalHeight] orientation : " + mResources.getConfiguration().orientation + ", density : " + mResources.getConfiguration().densityDpi + ", windowHeight : " + windowHeight; - if (mUseCustomHeight) { - if (mSetCustomProportion) { - if (lp != null) { - lp.height = (int) collapsedHeight; - setLayoutParams(lp); - logStr += ", [1]updateInternalHeight: lp.height : " + lp.height + ", mCustomHeightProportion : " + mCustomHeightProportion; + public void seslResetAppBarAndInsets(boolean force) { + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + Log.i(TAG, "seslResetAppBarAndInsets() force = " + force); + behavior.seslRestoreTopAndBottom(); + behavior.showWindowInset(force); } - } else if (mSetCustomHeight && lp != null) { - lp.height = mCustomHeight + getImmersiveTopInset(); - setLayoutParams(lp); - logStr += ", [2]updateInternalHeight: CustomHeight : " + mCustomHeight + "lp.height : " + lp.height; - } - } else if (lp != null) { - lp.height = (int) collapsedHeight; - setLayoutParams(lp); - logStr += ", [3]updateInternalHeight: lp.height : " + lp.height + ", mHeightProportion : " + mHeightProportion; } - logStr += " , mIsImmersiveScroll : " + mIsActivatedImmersiveScroll + " , mIsSetByUser : " + mIsActivatedByUser; - Log.i(TAG, logStr); - } - private float getDifferImmHeightRatio() { - float windowHeight = (float) getWindowHeight(); - if (windowHeight == 0.0f) { - windowHeight = 1.0f; + public void seslCancelWindowInsetsAnimationController() { + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + Log.i(TAG, "seslCancelWindowInsetsAnimationController"); + behavior.cancelWindowInsetsAnimationController(); + } } - return getImmersiveTopInset() / windowHeight; - } - private int getWindowHeight() { - return mResources.getDisplayMetrics().heightPixels; - } + public void seslImmHideStatusBarForLandscape(boolean hide) { + mImmHideStatusBar = hide; + } - @Override - public void seslSetExpanded(boolean expanded) { - setExpanded(expanded); - } + boolean isImmHideStatusBarForLandscape() { + return mImmHideStatusBar; + } - @Override - public boolean seslIsCollapsed() { - return lifted; - } + @Deprecated + public void seslSetBottomView(View view, View bottomView) { + seslSetBottomView(bottomView); + } - @Override - public void seslSetIsMouse(boolean mouse) { - isMouse = mouse; - } + public void seslSetBottomView(View bottomView) { + if (bottomView == null) { + Log.w(TAG, "bottomView is null"); + } + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + behavior.seslSetBottomView(bottomView); + } + } - protected boolean getIsMouse() { - return isMouse; - } + protected void internalActivateImmersiveScroll(boolean activate, boolean byUser) { + mIsActivatedImmersiveScroll = activate; + mIsActivatedByUser = byUser; + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + Log.i(TAG, "internalActivateImmersiveScroll : " + activate + " , byUser : " + byUser + " , behavior : " + behavior); + if (behavior == null) { + return; + } + if (!activate || behavior.isAppBarHide()) { + behavior.seslRestoreTopAndBottom(mRestoreAnim); + } + } - public static class LayoutParams extends LinearLayout.LayoutParams { - static final int COLLAPSIBLE_FLAGS = 10; - private static final int FLAG_NO_SCROLL_HOLD = 65536; - private static final int FLAG_NO_SNAP = 4096; - static final int FLAG_QUICK_RETURN = 5; - static final int FLAG_SNAP = 17; - public static final int SCROLL_FLAG_ENTER_ALWAYS = 4; - public static final int SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED = 8; - public static final int SCROLL_FLAG_EXIT_UNTIL_COLLAPSED = 2; - public static final int SCROLL_FLAG_NO_SCROLL = 0; - public static final int SCROLL_FLAG_SCROLL = 1; - public static final int SCROLL_FLAG_SNAP = 16; - public static final int SCROLL_FLAG_SNAP_MARGINS = 32; - public static final int SESL_SCROLL_FLAG_NO_SCROLL_HOLD = 65536; - public static final int SESL_SCROLL_FLAG_NO_SNAP = 4096; - int scrollFlags = SCROLL_FLAG_SCROLL; - Interpolator scrollInterpolator; + public void seslActivateImmersiveScroll(boolean activate, boolean byUser) { + if (isDexEnabled()) { + Log.i(TAG, "Dex Enabled Set false ImmersiveScroll"); + activate = false; + } - @Retention(RetentionPolicy.SOURCE) - public @interface ScrollFlags {} + mRestoreAnim = byUser; + internalActivateImmersiveScroll(activate, true); - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.SamsungAppBarLayout_Layout); - scrollFlags = a.getInt(R.styleable.SamsungAppBarLayout_Layout_layout_scrollFlags, 0); + boolean z = true; + SeslImmersiveScrollBehavior behavior = getImmBehavior(); + if (behavior != null) { + z = behavior.dispatchImmersiveScrollEnable(); + } - if (a.hasValue(R.styleable.SamsungAppBarLayout_Layout_layout_scrollInterpolator)) { - int resId = a.getResourceId(R.styleable.SamsungAppBarLayout_Layout_layout_scrollInterpolator, 0); - scrollInterpolator = android.view.animation.AnimationUtils.loadInterpolator(c, resId); - } - a.recycle(); + if (z || !activate) { + setCanScroll(activate); + } } - public LayoutParams(int width, int height) { - super(width, height); + public void seslSetImmersiveScroll(boolean activate, boolean byUser) { + seslActivateImmersiveScroll(activate, byUser); } - public LayoutParams(int width, int height, float weight) { - super(width, height, weight); + public void seslActivateImmersiveScroll(boolean activate) { + seslActivateImmersiveScroll(activate, true); } - public LayoutParams(ViewGroup.LayoutParams p) { - super(p); + public void seslSetImmersiveScroll(boolean activate) { + seslActivateImmersiveScroll(activate); } - public LayoutParams(MarginLayoutParams source) { - super(source); + public boolean isActivatedImmsersiveScroll() { + return mIsActivatedImmersiveScroll; } - @RequiresApi(19) - public LayoutParams(LinearLayout.LayoutParams source) { - super(source); + public boolean seslGetImmersiveScroll() { + return isActivatedImmsersiveScroll(); } - @RequiresApi(19) - public LayoutParams(@NonNull LayoutParams source) { - super(source); - scrollFlags = source.scrollFlags; - scrollInterpolator = source.scrollInterpolator; + protected boolean isImmersiveActivatedByUser() { + return mIsActivatedByUser; } - public void setScrollFlags(@ScrollFlags int flags) { - scrollFlags = flags; + protected void setCanScroll(boolean canScroll) { + if (mIsCanScroll != canScroll) { + mIsCanScroll = canScroll; + invalidateScrollRanges(); + requestLayout(); + } } - @ScrollFlags - public int getScrollFlags() { - return scrollFlags; + public void seslSetTCScrollRange(int range) { + mSeslTCScrollRange = range; } - public void setScrollInterpolator(Interpolator interpolator) { - scrollInterpolator = interpolator; + protected int seslGetTCScrollRange() { + return mSeslTCScrollRange; } - public Interpolator getScrollInterpolator() { - return scrollInterpolator; + protected boolean getCanScroll() { + return mIsCanScroll; } - boolean isCollapsible() { - return (scrollFlags & SCROLL_FLAG_SCROLL) == SCROLL_FLAG_SCROLL && (scrollFlags & COLLAPSIBLE_FLAGS) != 0; + public void seslSetCollapsedHeight(float height) { + Log.i(TAG, "seslSetCollapsedHeight, height : " + height); + seslSetCollapsedHeight(height, true); } - } + private void seslSetCollapsedHeight(float height, boolean custom) { + mUseCollapsedHeight = custom; + mCollapsedHeight = height; + } - public static class Behavior extends BaseBehavior { - public abstract static class DragCallback extends BaseBehavior.BaseDragCallback {} - - public Behavior() { - super(); + void internalProportion(float proportion) { + if (!mUseCustomHeight && mHeightProportion != proportion) { + mHeightProportion = proportion; + updateInternalHeight(); + } } - public Behavior(Context context, AttributeSet attrs) { - super(context, attrs); + void setImmersiveTopInset(int top) { + mImmersiveTopInset = top; } - } - protected static class BaseBehavior extends HeaderBehavior { - private static final int INVALID_POSITION = -1; - private static final int MAX_OFFSET_ANIMATION_DURATION = 600; - @Nullable private WeakReference lastNestedScrollingChildRef; - @ViewCompat.NestedScrollType private int lastStartedType; - private float mDiffY_Touch; - private float mLastMotionY_Touch; - private boolean mLifted; - private boolean mToolisMouse; - private ValueAnimator offsetAnimator; - private int offsetDelta; - private boolean offsetToChildIndexOnLayoutIsMinHeight; - private float offsetToChildIndexOnLayoutPerc; - private BaseDragCallback onDragCallback; - private float touchX; - private float touchY; - private int offsetToChildIndexOnLayout = -1; - private boolean mIsFlingScrollDown = false; - private boolean mIsFlingScrollUp = false; - private boolean mDirectTouchAppbar = false; - private int mTouchSlop = -1; - private float mVelocity = 0.0f; - private boolean mIsSetStaticDuration = false; - private boolean mIsScrollHold = false; + final int getImmersiveTopInset() { + if (mIsCanScroll) { + return mImmersiveTopInset; + } + return 0; + } - public abstract static class BaseDragCallback { - public abstract boolean canDrag(@NonNull T appBarLayout); + public float seslGetCollapsedHeight() { + return mCollapsedHeight + ((float) getImmersiveTopInset()); } - public BaseBehavior() {} + public float seslGetHeightProPortion() { + return mHeightProportion; + } - public BaseBehavior(Context context, AttributeSet attrs) { - super(context, attrs); + boolean useCollapsedHeight() { + return mUseCollapsedHeight; } @Override - public boolean onStartNestedScroll(@NonNull SamsungCoordinatorLayout parent, @NonNull T child, @NonNull View directTargetChild, View target, int nestedScrollAxes, int type) { - final boolean started = (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 && (child.isLiftOnScroll() || canScrollChildren(parent, child, directTargetChild)); - - if (started && offsetAnimator != null) { - offsetAnimator.cancel(); - } + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + if (mBackground != null) { + setBackgroundDrawable(mBackground == getBackground() ? mBackground : getBackground()); + } else if (getBackground() != null) { + mBackground = getBackground(); + setBackgroundDrawable(mBackground); + } else { + mBackground = null; + setBackgroundColor(mResources.getColor(R.color.sesl_action_bar_background_color)); + } - if (((float) child.getBottom()) <= child.seslGetCollapsedHeight()) { - mLifted = true; - child.setLifted(true); - mDiffY_Touch = 0.0f; - } else { - mLifted = false; - child.setLifted(false); - } + if (mCurrentScreenHeight != newConfig.screenHeightDp || mCurrentOrientation != newConfig.orientation) { + if (!mUseCustomPadding && !mUseCollapsedHeight) { + Log.i(TAG, "Update bottom padding"); + mBottomPadding = mResources.getDimensionPixelSize(R.dimen.sesl_extended_appbar_bottom_padding); + setPadding(0, 0, 0, mBottomPadding); + mCollapsedHeight = (float) (mResources.getDimensionPixelSize(mIsOneUI4 ? R.dimen.sesl4_action_bar_height_with_padding : R.dimen.sesl_action_bar_height_with_padding) + mBottomPadding); + seslSetCollapsedHeight(mCollapsedHeight, false); + } else if (mUseCustomPadding && mBottomPadding == 0 && !mUseCollapsedHeight) { + mCollapsedHeight = (float) mResources.getDimensionPixelSize(mIsOneUI4 ? R.dimen.sesl4_action_bar_height_with_padding : R.dimen.sesl_action_bar_height_with_padding); + seslSetCollapsedHeight(mCollapsedHeight, false); + } + } - child.updateInternalCollapsedHeight(); + if (!mSetCustomProportion) { + mHeightProportion = ResourcesCompat.getFloat(mResources, mIsOneUI4 ? R.dimen.sesl4_appbar_height_proportion : R.dimen.sesl_appbar_height_proportion); + } - lastNestedScrollingChildRef = null; - lastStartedType = type; - mToolisMouse = child.getIsMouse(); + updateInternalHeight(); - return started; - } + if (lifted || (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT && newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)) { + setExpanded(false, false, true); + } else { + setExpanded(true, false, true); + } - private boolean canScrollChildren(@NonNull SamsungCoordinatorLayout parent, @NonNull T child, @NonNull View directTargetChild) { - return child.hasScrollableChildren() && parent.getHeight() - directTargetChild.getHeight() <= child.getHeight(); + mCurrentOrientation = newConfig.orientation; + mCurrentScreenHeight = newConfig.screenHeightDp; } @Override - public void onNestedPreScroll(SamsungCoordinatorLayout coordinatorLayout, @NonNull T child, View target, int dx, int dy, int[] consumed, int type) { - if (dy != 0) { - int min; - int max; - if (dy < 0) { - min = -child.getTotalScrollRange(); - max = min + child.getDownNestedPreScrollRange(); - - mIsFlingScrollDown = true; - mIsFlingScrollUp = false; - if (((double) child.getBottom()) >= ((double) child.getHeight()) * 0.52d) { - mIsSetStaticDuration = true; - } - if (dy < -30) { - mIsFlingScrollDown = true; - } else { - mVelocity = 0.0f; - mIsFlingScrollDown = false; - } - } else { - min = -child.getUpNestedPreScrollRange(); - max = 0; - - mIsFlingScrollDown = false; - mIsFlingScrollUp = true; - if (((double) child.getBottom()) <= ((double) child.getHeight()) * 0.43d) { - mIsSetStaticDuration = true; - } - if (dy > 30) { - mIsFlingScrollUp = true; - } else { - mVelocity = 0.0f; - mIsFlingScrollUp = false; - } - if (getTopAndBottomOffset() == min) { - mIsScrollHold = true; - } - } - if (isFlingRunnable()) { - onFlingFinished(coordinatorLayout, child); - } - if (min != max) { - consumed[1] = scroll(coordinatorLayout, child, dy, min, max); - } - } - if (child.isLiftOnScroll()) { - child.setLiftedState(child.shouldLift(target)); - } - stopNestedScrollIfNeeded(dy, child, target, type); + public boolean dispatchGenericMotionEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_SCROLL) { + if (liftOnScrollTargetView != null) { + if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) { + setExpanded(false); + } else if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) > 0.0f && !canScrollVertically(-1)) { + setExpanded(true); + } + } else if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0.0f) { + setExpanded(false); + } else if (event.getAxisValue(MotionEvent.AXIS_VSCROLL) > 0.0f) { + setExpanded(true); + } + } + + return super.dispatchGenericMotionEvent(event); } - @Override - public void onNestedScroll(SamsungCoordinatorLayout coordinatorLayout, @NonNull T child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) { - if (isScrollHoldMode(child)) { - if (dyUnconsumed >= 0 || mIsScrollHold) { - ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); + private void updateInternalHeight() { + int windowHeight = getWindowHeight(); + + float proportion; + if (mUseCustomHeight) { + if (mCustomHeightProportion != 0.0f) { + proportion = mCustomHeightProportion + (getCanScroll() ? getDifferImmHeightRatio() : 0.0f); + } else { + proportion = 0.0f; + } } else { - consumed[1] = scroll(coordinatorLayout, child, dyUnconsumed, -child.getDownNestedScrollRange(), 0); - stopNestedScrollIfNeeded(dyUnconsumed, child, target, type); + proportion = mHeightProportion; } - } else if (dyUnconsumed < 0) { - consumed[1] = scroll(coordinatorLayout, child, dyUnconsumed, -child.getDownNestedScrollRange(), 0); - stopNestedScrollIfNeeded(dyUnconsumed, child, target, type); - } - if (dyUnconsumed == 0) { - updateAccessibilityActions(coordinatorLayout, child); - } - } + float collapsedHeight = ((float) windowHeight) * proportion; + if (collapsedHeight == 0.0f) { + updateInternalCollapsedHeightOnce(); + collapsedHeight = seslGetCollapsedHeight(); + } - private void stopNestedScrollIfNeeded(int dy, @NonNull T child, View target, int type) { - if (type == ViewCompat.TYPE_NON_TOUCH) { - if ((dy < 0 && getTopBottomOffsetForScrollingSibling() == 0) || (dy > 0 && getTopBottomOffsetForScrollingSibling() == (-child.getDownNestedScrollRange()))) { - ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); + SamsungCoordinatorLayout.LayoutParams lp; + try { + lp = (SamsungCoordinatorLayout.LayoutParams) getLayoutParams(); + } catch (ClassCastException e) { + Log.e(TAG, Log.getStackTraceString(e)); + lp = null; } - } - } - @Override - public void onStopNestedScroll(SamsungCoordinatorLayout coordinatorLayout, @NonNull T abl, View target, int type) { - if (mLastTouchEvent == MotionEvent.ACTION_CANCEL || mLastTouchEvent == MotionEvent.ACTION_UP || mLastInterceptTouchEvent == MotionEvent.ACTION_CANCEL || mLastInterceptTouchEvent == MotionEvent.ACTION_UP) { - snapToChildIfNeeded(coordinatorLayout, abl); - } - if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) { - if (abl.isLiftOnScroll()) { - abl.setLiftedState(abl.shouldLift(target)); + String logStr = "[updateInternalHeight] orientation : " + mResources.getConfiguration().orientation + ", density : " + mResources.getConfiguration().densityDpi + ", windowHeight : " + windowHeight; + if (mUseCustomHeight) { + if (mSetCustomProportion) { + if (lp != null) { + lp.height = (int) collapsedHeight; + setLayoutParams(lp); + logStr += ", [1]updateInternalHeight: lp.height : " + lp.height + ", mCustomHeightProportion : " + mCustomHeightProportion; + } + } else if (mSetCustomHeight && lp != null) { + lp.height = mCustomHeight + getImmersiveTopInset(); + setLayoutParams(lp); + logStr += ", [2]updateInternalHeight: CustomHeight : " + mCustomHeight + "lp.height : " + lp.height; + } + } else if (lp != null) { + lp.height = (int) collapsedHeight; + setLayoutParams(lp); + logStr += ", [3]updateInternalHeight: lp.height : " + lp.height + ", mHeightProportion : " + mHeightProportion; } - if (mIsScrollHold) { - mIsScrollHold = false; + logStr += " , mIsImmersiveScroll : " + mIsActivatedImmersiveScroll + " , mIsSetByUser : " + mIsActivatedByUser; + Log.i(TAG, logStr); + } + + private float getDifferImmHeightRatio() { + float windowHeight = (float) getWindowHeight(); + if (windowHeight == 0.0f) { + windowHeight = 1.0f; } - } + return getImmersiveTopInset() / windowHeight; + } - lastNestedScrollingChildRef = new WeakReference<>(target); + private int getWindowHeight() { + return mResources.getDisplayMetrics().heightPixels; } - public void setDragCallback(@Nullable BaseDragCallback callback) { - onDragCallback = callback; + @Override + public void seslSetExpanded(boolean expanded) { + setExpanded(expanded); } - // kang - private void animateOffsetTo(final SamsungCoordinatorLayout coordinatorLayout, @NonNull final T child, final int offset, float velocity) { - int i = (Math.abs(this.mVelocity) > 0.0f ? 1 : (Math.abs(this.mVelocity) == 0.0f ? 0 : -1)); - int i2 = 250; - int abs = (i <= 0 || Math.abs(this.mVelocity) > 3000.0f) ? 250 : (int) (((double) (3000.0f - Math.abs(this.mVelocity))) * 0.4d); - if (abs <= 250) { - abs = 250; - } - if (this.mIsSetStaticDuration) { - this.mIsSetStaticDuration = false; - } else { - i2 = abs; - } - if (Math.abs(this.mVelocity) < 2000.0f) { - animateOffsetWithDuration(coordinatorLayout, child, offset, i2); - } - this.mVelocity = 0.0f; + @Override + public boolean seslIsCollapsed() { + return lifted; } - // kang - private void animateOffsetWithDuration(final SamsungCoordinatorLayout coordinatorLayout, final T child, final int offset, final int duration) { - final int currentOffset = getTopBottomOffsetForScrollingSibling(); - if (currentOffset == offset) { - if (offsetAnimator != null && offsetAnimator.isRunning()) { - offsetAnimator.cancel(); - } - return; - } - - if (offsetAnimator == null) { - offsetAnimator = new ValueAnimator(); - offsetAnimator.setInterpolator(SeslAnimationUtils.SINE_OUT_80); - offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(@NonNull ValueAnimator animator) { - setHeaderTopBottomOffset(coordinatorLayout, child, (int) animator.getAnimatedValue()); - } - }); - } else { - offsetAnimator.cancel(); - } + @Override + public void seslSetIsMouse(boolean mouse) { + isMouse = mouse; + } + + protected boolean getIsMouse() { + return isMouse; + } + + + public static class LayoutParams extends LinearLayout.LayoutParams { + static final int COLLAPSIBLE_FLAGS = 10; + private static final int FLAG_NO_SCROLL_HOLD = 65536; + private static final int FLAG_NO_SNAP = 4096; + static final int FLAG_QUICK_RETURN = 5; + static final int FLAG_SNAP = 17; + public static final int SCROLL_FLAG_ENTER_ALWAYS = 4; + public static final int SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED = 8; + public static final int SCROLL_FLAG_EXIT_UNTIL_COLLAPSED = 2; + public static final int SCROLL_FLAG_NO_SCROLL = 0; + public static final int SCROLL_FLAG_SCROLL = 1; + public static final int SCROLL_FLAG_SNAP = 16; + public static final int SCROLL_FLAG_SNAP_MARGINS = 32; + public static final int SESL_SCROLL_FLAG_NO_SCROLL_HOLD = 65536; + public static final int SESL_SCROLL_FLAG_NO_SNAP = 4096; + int scrollFlags = SCROLL_FLAG_SCROLL; + Interpolator scrollInterpolator; + + @Retention(RetentionPolicy.SOURCE) + public @interface ScrollFlags {} + + public LayoutParams(Context c, AttributeSet attrs) { + super(c, attrs); + TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.SamsungAppBarLayout_Layout); + scrollFlags = a.getInt(R.styleable.SamsungAppBarLayout_Layout_layout_scrollFlags, 0); + + if (a.hasValue(R.styleable.SamsungAppBarLayout_Layout_layout_scrollInterpolator)) { + int resId = a.getResourceId(R.styleable.SamsungAppBarLayout_Layout_layout_scrollInterpolator, 0); + scrollInterpolator = android.view.animation.AnimationUtils.loadInterpolator(c, resId); + } + a.recycle(); + } - offsetAnimator.setDuration(Math.min(duration, MAX_OFFSET_ANIMATION_DURATION)); - offsetAnimator.setIntValues(currentOffset, offset); - offsetAnimator.start(); - } + public LayoutParams(int width, int height) { + super(width, height); + } - private int getChildIndexOnOffset(@NonNull T abl, int offset) { - for (int i = 0, count = abl.getChildCount(); i < count; i++) { - View child = abl.getChildAt(i); - int top = child.getTop(); - int bottom = child.getBottom(); + public LayoutParams(int width, int height, float weight) { + super(width, height, weight); + } - final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - if (checkFlag(lp.getScrollFlags(), LayoutParams.SCROLL_FLAG_SNAP_MARGINS)) { - top -= lp.topMargin; - bottom += lp.bottomMargin; + public LayoutParams(ViewGroup.LayoutParams p) { + super(p); } - if (abl.seslGetTCScrollRange() != 0) { - bottom += abl.seslGetTCScrollRange(); + public LayoutParams(MarginLayoutParams source) { + super(source); } - offset += (abl.isLifted() ? abl.getPaddingBottom() : 0); + @RequiresApi(19) + public LayoutParams(LinearLayout.LayoutParams source) { + super(source); + } - if (top <= -offset && bottom >= -offset) { - return i; + @RequiresApi(19) + public LayoutParams(@NonNull LayoutParams source) { + super(source); + scrollFlags = source.scrollFlags; + scrollInterpolator = source.scrollInterpolator; } - } - return -1; - } - // kang - private void snapToChildIfNeeded(SamsungCoordinatorLayout coordinatorLayout, T t) { - int topBottomOffsetForScrollingSibling = getTopBottomOffsetForScrollingSibling(); - int childIndexOnOffset = getChildIndexOnOffset(t, topBottomOffsetForScrollingSibling); - View childAt = coordinatorLayout.getChildAt(1); - if (childIndexOnOffset >= 0) { - View childAt2 = t.getChildAt(childIndexOnOffset); - LayoutParams layoutParams = (LayoutParams) childAt2.getLayoutParams(); - int scrollFlags = layoutParams.getScrollFlags(); - if ((scrollFlags & 4096) == 4096) { - seslHasNoSnapFlag(true); - return; - } - seslHasNoSnapFlag(false); - int seslGetTCScrollRange = t.getCanScroll() ? t.seslGetTCScrollRange() : 0; - if (((float) t.getBottom()) >= t.seslGetCollapsedHeight()) { - int i = -childAt2.getTop(); - int i2 = -childAt2.getBottom(); - if (childIndexOnOffset == t.getChildCount() - 1) { - i2 += t.getTopInset(); - } - if (checkFlag(scrollFlags, 2)) { - if (t.getCanScroll()) { - i2 = (int) (((float) i2) + (t.seslGetCollapsedHeight() - ((float) t.getPaddingBottom()))); - } else { - i2 += ViewCompat.getMinimumHeight(childAt2); - } - } else if (checkFlag(scrollFlags, 5)) { - int minimumHeight = ViewCompat.getMinimumHeight(childAt2) + i2; - if (topBottomOffsetForScrollingSibling < minimumHeight) { - i = minimumHeight; - } else { - i2 = minimumHeight; - } - } - if (checkFlag(scrollFlags, 32)) { - i += layoutParams.topMargin; - i2 -= layoutParams.bottomMargin; - } - int i3 = (!this.mLifted ? ((double) topBottomOffsetForScrollingSibling) >= ((double) (i2 + i)) * 0.43d : ((double) topBottomOffsetForScrollingSibling) >= ((double) (i2 + i)) * 0.52d) ? i : i2; - if (childAt == null) { - Log.w(TAG, "coordinatorLayout.getChildAt(1) is null"); - i = i3; - } else { - if (this.mIsFlingScrollUp) { - this.mIsFlingScrollUp = false; - this.mIsFlingScrollDown = false; - } else { - i2 = i3; - } - if (!this.mIsFlingScrollDown || ((float) childAt.getTop()) <= t.seslGetCollapsedHeight()) { - i = i2; - } else { - this.mIsFlingScrollDown = false; - } - } - animateOffsetTo(coordinatorLayout, t, MathUtils.clamp(i, -t.getTotalScrollRange(), 0), 0.0f); - } else if (t.getCanScroll()) { - int seslGetCollapsedHeight = (((int) t.seslGetCollapsedHeight()) - t.getTotalScrollRange()) + seslGetTCScrollRange; - int i4 = -t.getTotalScrollRange(); - int i5 = ((double) (t.getBottom() + seslGetTCScrollRange)) >= ((double) t.seslGetCollapsedHeight()) * 0.48d ? seslGetCollapsedHeight : i4; - if (!this.mIsFlingScrollUp) { - i4 = i5; - } - if (!this.mIsFlingScrollDown) { - seslGetCollapsedHeight = i4; - } - animateOffsetTo(coordinatorLayout, t, MathUtils.clamp(seslGetCollapsedHeight, -t.getTotalScrollRange(), 0), 0.0f); - } - } - } - // kang + public void setScrollFlags(@ScrollFlags int flags) { + scrollFlags = flags; + } - private static boolean checkFlag(final int flags, final int check) { - return (flags & check) == check; - } + @ScrollFlags + public int getScrollFlags() { + return scrollFlags; + } - @Override - public boolean onMeasureChild(@NonNull SamsungCoordinatorLayout parent, @NonNull T child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { - final SamsungCoordinatorLayout.LayoutParams lp = (SamsungCoordinatorLayout.LayoutParams) child.getLayoutParams(); - if (lp.height == SamsungCoordinatorLayout.LayoutParams.WRAP_CONTENT) { - parent.onMeasureChild(child, parentWidthMeasureSpec, widthUsed, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), heightUsed); - return true; - } + public void setScrollInterpolator(Interpolator interpolator) { + scrollInterpolator = interpolator; + } - return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); - } + public Interpolator getScrollInterpolator() { + return scrollInterpolator; + } - private int getImmPendingActionOffset(SamsungAppBarLayout appBarLayout) { - Behavior behavior = (Behavior) ((SamsungCoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior(); - if (appBarLayout.getCanScroll() && (behavior instanceof SeslImmersiveScrollBehavior)) { - return ((int) appBarLayout.seslGetCollapsedHeight()) + appBarLayout.seslGetTCScrollRange(); - } - return 0; + boolean isCollapsible() { + return (scrollFlags & SCROLL_FLAG_SCROLL) == SCROLL_FLAG_SCROLL && (scrollFlags & COLLAPSIBLE_FLAGS) != 0; + } } - @Override - public boolean onLayoutChild(@NonNull SamsungCoordinatorLayout parent, @NonNull T abl, int layoutDirection) { - boolean handled = super.onLayoutChild(parent, abl, layoutDirection); - final int pendingAction = abl.getPendingAction(); - if (offsetToChildIndexOnLayout >= 0 && (pendingAction & PENDING_ACTION_FORCE) == 0) { - View childAt = abl.getChildAt(offsetToChildIndexOnLayout); + public static class Behavior extends BaseBehavior { + public abstract static class DragCallback extends BaseBehavior.BaseDragCallback {} - int i; - if (offsetToChildIndexOnLayoutIsMinHeight) { - i = ViewCompat.getMinimumHeight(childAt) + abl.getTopInset(); - } else { - i = Math.round(((float) childAt.getHeight()) * offsetToChildIndexOnLayoutPerc); - } - setHeaderTopBottomOffset(parent, abl, (-childAt.getBottom()) + i); - } else if (pendingAction != PENDING_ACTION_NONE) { - final boolean animate = (pendingAction & PENDING_ACTION_ANIMATE_ENABLED) != 0; - if ((pendingAction & PENDING_ACTION_COLLAPSED) != 0) { - int offset = ((-abl.getTotalScrollRange()) + getImmPendingActionOffset(abl)) - abl.getImmersiveTopInset(); - if (animate) { - animateOffsetTo(parent, abl, offset, 0); - } else { - setHeaderTopBottomOffset(parent, abl, offset); - } - } else if ((pendingAction & PENDING_ACTION_COLLAPSED_IMM) != 0) { - int offset = (-abl.getTotalScrollRange()) + getImmPendingActionOffset(abl); - if (parent.getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT && abl.getImmersiveTopInset() == 0 && abl.seslGetHeightProPortion() == 0.0f) { - offset = 0; - } - if (animate) { - animateOffsetTo(parent, abl, offset, 0); - } else { - setHeaderTopBottomOffset(parent, abl, offset); - } - } else if ((pendingAction & PENDING_ACTION_EXPANDED) != 0) { - if (animate) { - animateOffsetTo(parent, abl, 0, 0); - } else { - setHeaderTopBottomOffset(parent, abl, 0); - } - } - } - - abl.resetPendingAction(); - offsetToChildIndexOnLayout = -1; - - setTopAndBottomOffset(MathUtils.clamp(getTopAndBottomOffset(), -abl.getTotalScrollRange(), 0)); - - updateAppBarLayoutDrawableState(parent, abl, getTopAndBottomOffset(), 0, true); - - abl.onOffsetChanged(getTopAndBottomOffset()); - - updateAccessibilityActions(parent, abl); - return handled; - } - - private void updateAccessibilityActions(SamsungCoordinatorLayout coordinatorLayout, @NonNull T appBarLayout) { - ViewCompat.removeAccessibilityAction(coordinatorLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId()); - ViewCompat.removeAccessibilityAction(coordinatorLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId()); - View scrollingView = findFirstScrollingChild(coordinatorLayout); - - if (scrollingView == null || appBarLayout.getTotalScrollRange() == 0) { - return; - } - SamsungCoordinatorLayout.LayoutParams lp = (SamsungCoordinatorLayout.LayoutParams) scrollingView.getLayoutParams(); - if (!(lp.getBehavior() instanceof ScrollingViewBehavior)) { - return; - } - addAccessibilityScrollActions(coordinatorLayout, appBarLayout, scrollingView); - } - - private void addAccessibilityScrollActions(final SamsungCoordinatorLayout coordinatorLayout, @NonNull final T appBarLayout, @NonNull final View scrollingView) { - if (getTopBottomOffsetForScrollingSibling() != -appBarLayout.getTotalScrollRange() && scrollingView.canScrollVertically(1)) { - addActionToExpand(coordinatorLayout, appBarLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD, false); - } - if (getTopBottomOffsetForScrollingSibling() != 0) { - if (scrollingView.canScrollVertically(-1)) { - final int dy = -appBarLayout.getDownNestedPreScrollRange(); - if (dy != 0) { - ViewCompat.replaceAccessibilityAction(coordinatorLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD, null, new AccessibilityViewCommand() { - @Override - public boolean perform(@NonNull View view, @Nullable CommandArguments arguments) { - onNestedPreScroll(coordinatorLayout, appBarLayout, scrollingView, 0, dy, new int[] {0, 0}, ViewCompat.TYPE_NON_TOUCH); - return true; - } - }); - } - } else { - addActionToExpand(coordinatorLayout, appBarLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD, true); + public Behavior() { + super(); + } + + public Behavior(Context context, AttributeSet attrs) { + super(context, attrs); } - } } - private void addActionToExpand(SamsungCoordinatorLayout parent, @NonNull final T appBarLayout, @NonNull AccessibilityNodeInfoCompat.AccessibilityActionCompat action, final boolean expand) { - ViewCompat.replaceAccessibilityAction(parent, action, null, new AccessibilityViewCommand() { + protected static class BaseBehavior extends HeaderBehavior { + private static final int INVALID_POSITION = -1; + private static final int MAX_OFFSET_ANIMATION_DURATION = 600; + @Nullable private WeakReference lastNestedScrollingChildRef; + @ViewCompat.NestedScrollType private int lastStartedType; + private float mDiffY_Touch; + private float mLastMotionY_Touch; + private boolean mLifted; + private boolean mToolisMouse; + private ValueAnimator offsetAnimator; + private int offsetDelta; + private boolean offsetToChildIndexOnLayoutIsMinHeight; + private float offsetToChildIndexOnLayoutPerc; + private BaseDragCallback onDragCallback; + private float touchX; + private float touchY; + private int offsetToChildIndexOnLayout = -1; + private boolean mIsFlingScrollDown = false; + private boolean mIsFlingScrollUp = false; + private boolean mDirectTouchAppbar = false; + private int mTouchSlop = -1; + private float mVelocity = 0.0f; + private boolean mIsSetStaticDuration = false; + private boolean mIsScrollHold = false; + + public abstract static class BaseDragCallback { + public abstract boolean canDrag(@NonNull T appBarLayout); + } + + public BaseBehavior() {} + + public BaseBehavior(Context context, AttributeSet attrs) { + super(context, attrs); + } + @Override - public boolean perform(@NonNull View view, @Nullable CommandArguments arguments) { - appBarLayout.setExpanded(expand); - return true; + public boolean onStartNestedScroll(@NonNull SamsungCoordinatorLayout parent, @NonNull T child, @NonNull View directTargetChild, View target, int nestedScrollAxes, int type) { + final boolean started = (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 && (child.isLiftOnScroll() || canScrollChildren(parent, child, directTargetChild)); + + if (started && offsetAnimator != null) { + offsetAnimator.cancel(); + } + + if (((float) child.getBottom()) <= child.seslGetCollapsedHeight()) { + mLifted = true; + child.setLifted(true); + mDiffY_Touch = 0.0f; + } else { + mLifted = false; + child.setLifted(false); + } + + child.updateInternalCollapsedHeight(); + + lastNestedScrollingChildRef = null; + lastStartedType = type; + mToolisMouse = child.getIsMouse(); + + return started; } - }); - } - @Override - boolean canDragView(T view) { - if (onDragCallback != null) { - return onDragCallback.canDrag(view); - } - - if (lastNestedScrollingChildRef != null) { - final View scrollingView = lastNestedScrollingChildRef.get(); - return scrollingView != null && scrollingView.isShown() && !scrollingView.canScrollVertically(-1); - } else { - return true; - } - } + private boolean canScrollChildren(@NonNull SamsungCoordinatorLayout parent, @NonNull T child, @NonNull View directTargetChild) { + return child.hasScrollableChildren() && parent.getHeight() - directTargetChild.getHeight() <= child.getHeight(); + } - @Override - void onFlingFinished(@NonNull SamsungCoordinatorLayout parent, @NonNull T layout) { - if (scroller != null) { - scroller.forceFinished(true); - } - } + @Override + public void onNestedPreScroll(SamsungCoordinatorLayout coordinatorLayout, @NonNull T child, View target, int dx, int dy, int[] consumed, int type) { + if (dy != 0) { + int min; + int max; + if (dy < 0) { + min = -child.getTotalScrollRange(); + max = min + child.getDownNestedPreScrollRange(); + + mIsFlingScrollDown = true; + mIsFlingScrollUp = false; + if (((double) child.getBottom()) >= ((double) child.getHeight()) * 0.52d) { + mIsSetStaticDuration = true; + } + if (dy < -30) { + mIsFlingScrollDown = true; + } else { + mVelocity = 0.0f; + mIsFlingScrollDown = false; + } + } else { + min = -child.getUpNestedPreScrollRange(); + max = 0; + + mIsFlingScrollDown = false; + mIsFlingScrollUp = true; + if (((double) child.getBottom()) <= ((double) child.getHeight()) * 0.43d) { + mIsSetStaticDuration = true; + } + if (dy > 30) { + mIsFlingScrollUp = true; + } else { + mVelocity = 0.0f; + mIsFlingScrollUp = false; + } + if (getTopAndBottomOffset() == min) { + mIsScrollHold = true; + } + } + if (isFlingRunnable()) { + onFlingFinished(coordinatorLayout, child); + } + if (min != max) { + consumed[1] = scroll(coordinatorLayout, child, dy, min, max); + } + } + if (child.isLiftOnScroll()) { + child.setLiftedState(child.shouldLift(target)); + } + stopNestedScrollIfNeeded(dy, child, target, type); + } - @Override - int getMaxDragOffset(@NonNull T view) { - return -view.getDownNestedScrollRange(); - } + @Override + public void onNestedScroll(SamsungCoordinatorLayout coordinatorLayout, @NonNull T child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type, int[] consumed) { + if (isScrollHoldMode(child)) { + if (dyUnconsumed >= 0 || mIsScrollHold) { + ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); + } else { + consumed[1] = scroll(coordinatorLayout, child, dyUnconsumed, -child.getDownNestedScrollRange(), 0); + stopNestedScrollIfNeeded(dyUnconsumed, child, target, type); + } + } else if (dyUnconsumed < 0) { + consumed[1] = scroll(coordinatorLayout, child, dyUnconsumed, -child.getDownNestedScrollRange(), 0); + stopNestedScrollIfNeeded(dyUnconsumed, child, target, type); + } - @Override - int getScrollRangeForDragFling(@NonNull T view) { - return view.getTotalScrollRange(); - } + if (dyUnconsumed == 0) { + updateAccessibilityActions(coordinatorLayout, child); + } + } - @Override - int setHeaderTopBottomOffset(@NonNull SamsungCoordinatorLayout coordinatorLayout, @NonNull T appBarLayout, int newOffset, int minOffset, int maxOffset) { - final int curOffset = getTopBottomOffsetForScrollingSibling(); - int consumed = 0; + private void stopNestedScrollIfNeeded(int dy, @NonNull T child, View target, int type) { + if (type == ViewCompat.TYPE_NON_TOUCH) { + if ((dy < 0 && getTopBottomOffsetForScrollingSibling() == 0) || (dy > 0 && getTopBottomOffsetForScrollingSibling() == (-child.getDownNestedScrollRange()))) { + ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); + } + } + } - if (minOffset != 0 && curOffset >= minOffset && curOffset <= maxOffset) { - newOffset = MathUtils.clamp(newOffset, minOffset, maxOffset); - if (curOffset != newOffset) { - final int interpolatedOffset = appBarLayout.hasChildWithInterpolator() ? interpolateOffset(appBarLayout, newOffset) : newOffset; + @Override + public void onStopNestedScroll(SamsungCoordinatorLayout coordinatorLayout, @NonNull T abl, View target, int type) { + if (mLastTouchEvent == MotionEvent.ACTION_CANCEL || mLastTouchEvent == MotionEvent.ACTION_UP || mLastInterceptTouchEvent == MotionEvent.ACTION_CANCEL || mLastInterceptTouchEvent == MotionEvent.ACTION_UP) { + snapToChildIfNeeded(coordinatorLayout, abl); + } + if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) { + if (abl.isLiftOnScroll()) { + abl.setLiftedState(abl.shouldLift(target)); + } + if (mIsScrollHold) { + mIsScrollHold = false; + } + } - final boolean offsetChanged = setTopAndBottomOffset(interpolatedOffset); + lastNestedScrollingChildRef = new WeakReference<>(target); + } - consumed = curOffset - newOffset; - offsetDelta = newOffset - interpolatedOffset; + public void setDragCallback(@Nullable BaseDragCallback callback) { + onDragCallback = callback; + } - if (!offsetChanged && appBarLayout.hasChildWithInterpolator()) { - coordinatorLayout.dispatchDependentViewsChanged(appBarLayout); - } + // kang + private void animateOffsetTo(final SamsungCoordinatorLayout coordinatorLayout, @NonNull final T child, final int offset, float velocity) { + int i = (Math.abs(this.mVelocity) > 0.0f ? 1 : (Math.abs(this.mVelocity) == 0.0f ? 0 : -1)); + int i2 = 250; + int abs = (i <= 0 || Math.abs(this.mVelocity) > 3000.0f) ? 250 : (int) (((double) (3000.0f - Math.abs(this.mVelocity))) * 0.4d); + if (abs <= 250) { + abs = 250; + } + if (this.mIsSetStaticDuration) { + this.mIsSetStaticDuration = false; + } else { + i2 = abs; + } + if (Math.abs(this.mVelocity) < 2000.0f) { + animateOffsetWithDuration(coordinatorLayout, child, offset, i2); + } + this.mVelocity = 0.0f; + } + // kang + + private void animateOffsetWithDuration(final SamsungCoordinatorLayout coordinatorLayout, final T child, final int offset, final int duration) { + final int currentOffset = getTopBottomOffsetForScrollingSibling(); + if (currentOffset == offset) { + if (offsetAnimator != null && offsetAnimator.isRunning()) { + offsetAnimator.cancel(); + } + return; + } - appBarLayout.onOffsetChanged(getTopAndBottomOffset()); + if (offsetAnimator == null) { + offsetAnimator = new ValueAnimator(); + offsetAnimator.setInterpolator(SeslAnimationUtils.SINE_OUT_80); + offsetAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull ValueAnimator animator) { + setHeaderTopBottomOffset(coordinatorLayout, child, (int) animator.getAnimatedValue()); + } + }); + } else { + offsetAnimator.cancel(); + } - updateAppBarLayoutDrawableState(coordinatorLayout, appBarLayout, newOffset, newOffset < curOffset ? -1 : 1, false); + offsetAnimator.setDuration(Math.min(duration, MAX_OFFSET_ANIMATION_DURATION)); + offsetAnimator.setIntValues(currentOffset, offset); + offsetAnimator.start(); } - } else { - offsetDelta = 0; - } - updateAccessibilityActions(coordinatorLayout, appBarLayout); - return consumed; - } + private int getChildIndexOnOffset(@NonNull T abl, int offset) { + for (int i = 0, count = abl.getChildCount(); i < count; i++) { + View child = abl.getChildAt(i); + int top = child.getTop(); + int bottom = child.getBottom(); - boolean isOffsetAnimatorRunning() { - return offsetAnimator != null && offsetAnimator.isRunning(); - } + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); + if (checkFlag(lp.getScrollFlags(), LayoutParams.SCROLL_FLAG_SNAP_MARGINS)) { + top -= lp.topMargin; + bottom += lp.bottomMargin; + } - private int interpolateOffset(@NonNull T layout, final int offset) { - final int absOffset = Math.abs(offset); + if (abl.seslGetTCScrollRange() != 0) { + bottom += abl.seslGetTCScrollRange(); + } - for (int i = 0, z = layout.getChildCount(); i < z; i++) { - final View child = layout.getChildAt(i); - final SamsungAppBarLayout.LayoutParams childLp = (LayoutParams) child.getLayoutParams(); - final Interpolator interpolator = childLp.getScrollInterpolator(); + offset += (abl.isLifted() ? abl.getPaddingBottom() : 0); - if (absOffset >= child.getTop() && absOffset <= child.getBottom()) { - if (interpolator != null) { - int childScrollableHeight = 0; - final int flags = childLp.getScrollFlags(); - if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { - childScrollableHeight += child.getHeight() + childLp.topMargin + childLp.bottomMargin; + if (top <= -offset && bottom >= -offset) { + return i; + } + } + return -1; + } - if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { - childScrollableHeight -= ViewCompat.getMinimumHeight(child); - } + // kang + private void snapToChildIfNeeded(SamsungCoordinatorLayout coordinatorLayout, T t) { + int topBottomOffsetForScrollingSibling = getTopBottomOffsetForScrollingSibling(); + int childIndexOnOffset = getChildIndexOnOffset(t, topBottomOffsetForScrollingSibling); + View childAt = coordinatorLayout.getChildAt(1); + if (childIndexOnOffset >= 0) { + View childAt2 = t.getChildAt(childIndexOnOffset); + LayoutParams layoutParams = (LayoutParams) childAt2.getLayoutParams(); + int scrollFlags = layoutParams.getScrollFlags(); + if ((scrollFlags & 4096) == 4096) { + seslHasNoSnapFlag(true); + return; + } + seslHasNoSnapFlag(false); + int seslGetTCScrollRange = t.getCanScroll() ? t.seslGetTCScrollRange() : 0; + if (((float) t.getBottom()) >= t.seslGetCollapsedHeight()) { + int i = -childAt2.getTop(); + int i2 = -childAt2.getBottom(); + if (childIndexOnOffset == t.getChildCount() - 1) { + i2 += t.getTopInset(); + } + if (checkFlag(scrollFlags, 2)) { + if (t.getCanScroll()) { + i2 = (int) (((float) i2) + (t.seslGetCollapsedHeight() - ((float) t.getPaddingBottom()))); + } else { + i2 += ViewCompat.getMinimumHeight(childAt2); + } + } else if (checkFlag(scrollFlags, 5)) { + int minimumHeight = ViewCompat.getMinimumHeight(childAt2) + i2; + if (topBottomOffsetForScrollingSibling < minimumHeight) { + i = minimumHeight; + } else { + i2 = minimumHeight; + } + } + if (checkFlag(scrollFlags, 32)) { + i += layoutParams.topMargin; + i2 -= layoutParams.bottomMargin; + } + int i3 = (!this.mLifted ? ((double) topBottomOffsetForScrollingSibling) >= ((double) (i2 + i)) * 0.43d : ((double) topBottomOffsetForScrollingSibling) >= ((double) (i2 + i)) * 0.52d) ? i : i2; + if (childAt == null) { + Log.w(TAG, "coordinatorLayout.getChildAt(1) is null"); + i = i3; + } else { + if (this.mIsFlingScrollUp) { + this.mIsFlingScrollUp = false; + this.mIsFlingScrollDown = false; + } else { + i2 = i3; + } + if (!this.mIsFlingScrollDown || ((float) childAt.getTop()) <= t.seslGetCollapsedHeight()) { + i = i2; + } else { + this.mIsFlingScrollDown = false; + } + } + animateOffsetTo(coordinatorLayout, t, MathUtils.clamp(i, -t.getTotalScrollRange(), 0), 0.0f); + } else if (t.getCanScroll()) { + int seslGetCollapsedHeight = (((int) t.seslGetCollapsedHeight()) - t.getTotalScrollRange()) + seslGetTCScrollRange; + int i4 = -t.getTotalScrollRange(); + int i5 = ((double) (t.getBottom() + seslGetTCScrollRange)) >= ((double) t.seslGetCollapsedHeight()) * 0.48d ? seslGetCollapsedHeight : i4; + if (!this.mIsFlingScrollUp) { + i4 = i5; + } + if (!this.mIsFlingScrollDown) { + seslGetCollapsedHeight = i4; + } + animateOffsetTo(coordinatorLayout, t, MathUtils.clamp(seslGetCollapsedHeight, -t.getTotalScrollRange(), 0), 0.0f); + } } + } + // kang + + private static boolean checkFlag(final int flags, final int check) { + return (flags & check) == check; + } - if (ViewCompat.getFitsSystemWindows(child)) { - childScrollableHeight -= layout.getTopInset(); + @Override + public boolean onMeasureChild(@NonNull SamsungCoordinatorLayout parent, @NonNull T child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed) { + final SamsungCoordinatorLayout.LayoutParams lp = (SamsungCoordinatorLayout.LayoutParams) child.getLayoutParams(); + if (lp.height == SamsungCoordinatorLayout.LayoutParams.WRAP_CONTENT) { + parent.onMeasureChild(child, parentWidthMeasureSpec, widthUsed, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), heightUsed); + return true; } - if (childScrollableHeight > 0) { - final int offsetForView = absOffset - child.getTop(); - final int interpolatedDiff = Math.round(childScrollableHeight * interpolator.getInterpolation(offsetForView / (float) childScrollableHeight)); + return super.onMeasureChild(parent, child, parentWidthMeasureSpec, widthUsed, parentHeightMeasureSpec, heightUsed); + } + + private int getImmPendingActionOffset(SamsungAppBarLayout appBarLayout) { + Behavior behavior = (Behavior) ((SamsungCoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).getBehavior(); + if (appBarLayout.getCanScroll() && (behavior instanceof SeslImmersiveScrollBehavior)) { + return ((int) appBarLayout.seslGetCollapsedHeight()) + appBarLayout.seslGetTCScrollRange(); + } + return 0; + } - return Integer.signum(offset) * (child.getTop() + interpolatedDiff); + @Override + public boolean onLayoutChild(@NonNull SamsungCoordinatorLayout parent, @NonNull T abl, int layoutDirection) { + boolean handled = super.onLayoutChild(parent, abl, layoutDirection); + + final int pendingAction = abl.getPendingAction(); + if (offsetToChildIndexOnLayout >= 0 && (pendingAction & PENDING_ACTION_FORCE) == 0) { + View childAt = abl.getChildAt(offsetToChildIndexOnLayout); + + int i; + if (offsetToChildIndexOnLayoutIsMinHeight) { + i = ViewCompat.getMinimumHeight(childAt) + abl.getTopInset(); + } else { + i = Math.round(((float) childAt.getHeight()) * offsetToChildIndexOnLayoutPerc); + } + setHeaderTopBottomOffset(parent, abl, (-childAt.getBottom()) + i); + } else if (pendingAction != PENDING_ACTION_NONE) { + final boolean animate = (pendingAction & PENDING_ACTION_ANIMATE_ENABLED) != 0; + if ((pendingAction & PENDING_ACTION_COLLAPSED) != 0) { + int offset = ((-abl.getTotalScrollRange()) + getImmPendingActionOffset(abl)) - abl.getImmersiveTopInset(); + if (animate) { + animateOffsetTo(parent, abl, offset, 0); + } else { + setHeaderTopBottomOffset(parent, abl, offset); + } + } else if ((pendingAction & PENDING_ACTION_COLLAPSED_IMM) != 0) { + int offset = (-abl.getTotalScrollRange()) + getImmPendingActionOffset(abl); + if (parent.getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT && abl.getImmersiveTopInset() == 0 && abl.seslGetHeightProPortion() == 0.0f) { + offset = 0; + } + if (animate) { + animateOffsetTo(parent, abl, offset, 0); + } else { + setHeaderTopBottomOffset(parent, abl, offset); + } + } else if ((pendingAction & PENDING_ACTION_EXPANDED) != 0) { + if (animate) { + animateOffsetTo(parent, abl, 0, 0); + } else { + setHeaderTopBottomOffset(parent, abl, 0); + } + } } - } - break; + abl.resetPendingAction(); + offsetToChildIndexOnLayout = -1; + + setTopAndBottomOffset(MathUtils.clamp(getTopAndBottomOffset(), -abl.getTotalScrollRange(), 0)); + + updateAppBarLayoutDrawableState(parent, abl, getTopAndBottomOffset(), 0, true); + + abl.onOffsetChanged(getTopAndBottomOffset()); + + updateAccessibilityActions(parent, abl); + return handled; } - } - return offset; - } + private void updateAccessibilityActions(SamsungCoordinatorLayout coordinatorLayout, @NonNull T appBarLayout) { + ViewCompat.removeAccessibilityAction(coordinatorLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId()); + ViewCompat.removeAccessibilityAction(coordinatorLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId()); + View scrollingView = findFirstScrollingChild(coordinatorLayout); - private void updateAppBarLayoutDrawableState(@NonNull final SamsungCoordinatorLayout parent, @NonNull final T layout, final int offset, final int direction, final boolean forceJump) { - final View child = getAppBarChildOnOffset(layout, offset); - boolean lifted = false; - if (child != null) { - final SamsungAppBarLayout.LayoutParams childLp = (LayoutParams) child.getLayoutParams(); - final int flags = childLp.getScrollFlags(); + if (scrollingView == null || appBarLayout.getTotalScrollRange() == 0) { + return; + } + SamsungCoordinatorLayout.LayoutParams lp = (SamsungCoordinatorLayout.LayoutParams) scrollingView.getLayoutParams(); + if (!(lp.getBehavior() instanceof ScrollingViewBehavior)) { + return; + } + addAccessibilityScrollActions(coordinatorLayout, appBarLayout, scrollingView); + } - if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { - final int minHeight = ViewCompat.getMinimumHeight(child); + private void addAccessibilityScrollActions(final SamsungCoordinatorLayout coordinatorLayout, @NonNull final T appBarLayout, @NonNull final View scrollingView) { + if (getTopBottomOffsetForScrollingSibling() != -appBarLayout.getTotalScrollRange() && scrollingView.canScrollVertically(1)) { + addActionToExpand(coordinatorLayout, appBarLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD, false); + } + if (getTopBottomOffsetForScrollingSibling() != 0) { + if (scrollingView.canScrollVertically(-1)) { + final int dy = -appBarLayout.getDownNestedPreScrollRange(); + if (dy != 0) { + ViewCompat.replaceAccessibilityAction(coordinatorLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD, null, new AccessibilityViewCommand() { + @Override + public boolean perform(@NonNull View view, @Nullable CommandArguments arguments) { + onNestedPreScroll(coordinatorLayout, appBarLayout, scrollingView, 0, dy, new int[] {0, 0}, ViewCompat.TYPE_NON_TOUCH); + return true; + } + }); + } + } else { + addActionToExpand(coordinatorLayout, appBarLayout, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD, true); + } + } + } - if (direction > 0 && (flags & (LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED)) != 0) { - lifted = -offset >= child.getBottom() - minHeight - layout.getTopInset() - layout.getImmersiveTopInset(); - } else if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { - lifted = -offset >= child.getBottom() - minHeight - layout.getTopInset() - layout.getImmersiveTopInset(); - } + private void addActionToExpand(SamsungCoordinatorLayout parent, @NonNull final T appBarLayout, @NonNull AccessibilityNodeInfoCompat.AccessibilityActionCompat action, final boolean expand) { + ViewCompat.replaceAccessibilityAction(parent, action, null, new AccessibilityViewCommand() { + @Override + public boolean perform(@NonNull View view, @Nullable CommandArguments arguments) { + appBarLayout.setExpanded(expand); + return true; + } + }); + } + + @Override + boolean canDragView(T view) { + if (onDragCallback != null) { + return onDragCallback.canDrag(view); + } + + if (lastNestedScrollingChildRef != null) { + final View scrollingView = lastNestedScrollingChildRef.get(); + return scrollingView != null && scrollingView.isShown() && !scrollingView.canScrollVertically(-1); + } else { + return true; + } } - if (layout.isLiftOnScroll()) { - lifted = layout.shouldLift(findFirstScrollingChild(parent)); + @Override + void onFlingFinished(@NonNull SamsungCoordinatorLayout parent, @NonNull T layout) { + if (scroller != null) { + scroller.forceFinished(true); + } } - final boolean changed = layout.setLiftedState(lifted); + @Override + int getMaxDragOffset(@NonNull T view) { + return -view.getDownNestedScrollRange(); + } - if (forceJump || (changed && shouldJumpElevationState(parent, layout))) { - layout.jumpDrawablesToCurrentState(); + @Override + int getScrollRangeForDragFling(@NonNull T view) { + return view.getTotalScrollRange(); } - } - } - private boolean shouldJumpElevationState(@NonNull SamsungCoordinatorLayout parent, @NonNull T layout) { - final List dependencies = parent.getDependents(layout); - for (int i = 0, size = dependencies.size(); i < size; i++) { - final View dependency = dependencies.get(i); - final SamsungCoordinatorLayout.LayoutParams lp = (SamsungCoordinatorLayout.LayoutParams) dependency.getLayoutParams(); - final SamsungCoordinatorLayout.Behavior behavior = lp.getBehavior(); + @Override + int setHeaderTopBottomOffset(@NonNull SamsungCoordinatorLayout coordinatorLayout, @NonNull T appBarLayout, int newOffset, int minOffset, int maxOffset) { + final int curOffset = getTopBottomOffsetForScrollingSibling(); + int consumed = 0; + + if (minOffset != 0 && curOffset >= minOffset && curOffset <= maxOffset) { + newOffset = MathUtils.clamp(newOffset, minOffset, maxOffset); + if (curOffset != newOffset) { + final int interpolatedOffset = appBarLayout.hasChildWithInterpolator() ? interpolateOffset(appBarLayout, newOffset) : newOffset; + + final boolean offsetChanged = setTopAndBottomOffset(interpolatedOffset); + + consumed = curOffset - newOffset; + offsetDelta = newOffset - interpolatedOffset; + + if (!offsetChanged && appBarLayout.hasChildWithInterpolator()) { + coordinatorLayout.dispatchDependentViewsChanged(appBarLayout); + } + + appBarLayout.onOffsetChanged(getTopAndBottomOffset()); + + updateAppBarLayoutDrawableState(coordinatorLayout, appBarLayout, newOffset, newOffset < curOffset ? -1 : 1, false); + } + } else { + offsetDelta = 0; + } - if (behavior instanceof ScrollingViewBehavior) { - return ((ScrollingViewBehavior) behavior).getOverlayTop() != 0; + updateAccessibilityActions(coordinatorLayout, appBarLayout); + return consumed; } - } - return false; - } - @Nullable - private static View getAppBarChildOnOffset(@NonNull final SamsungAppBarLayout layout, final int offset) { - final int absOffset = Math.abs(offset); - for (int i = 0, z = layout.getChildCount(); i < z; i++) { - final View child = layout.getChildAt(i); - if (absOffset >= child.getTop() && absOffset <= child.getBottom()) { - return child; + boolean isOffsetAnimatorRunning() { + return offsetAnimator != null && offsetAnimator.isRunning(); } - } - return null; - } - @Nullable - private View findFirstScrollingChild(@NonNull SamsungCoordinatorLayout parent) { - for (int i = 0, z = parent.getChildCount(); i < z; i++) { - final View child = parent.getChildAt(i); - if (child instanceof NestedScrollingChild || child instanceof ListView || child instanceof ScrollView) { - return child; + private int interpolateOffset(@NonNull T layout, final int offset) { + final int absOffset = Math.abs(offset); + + for (int i = 0, z = layout.getChildCount(); i < z; i++) { + final View child = layout.getChildAt(i); + final SamsungAppBarLayout.LayoutParams childLp = (LayoutParams) child.getLayoutParams(); + final Interpolator interpolator = childLp.getScrollInterpolator(); + + if (absOffset >= child.getTop() && absOffset <= child.getBottom()) { + if (interpolator != null) { + int childScrollableHeight = 0; + final int flags = childLp.getScrollFlags(); + if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { + childScrollableHeight += child.getHeight() + childLp.topMargin + childLp.bottomMargin; + + if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { + childScrollableHeight -= ViewCompat.getMinimumHeight(child); + } + } + + if (ViewCompat.getFitsSystemWindows(child)) { + childScrollableHeight -= layout.getTopInset(); + } + + if (childScrollableHeight > 0) { + final int offsetForView = absOffset - child.getTop(); + final int interpolatedDiff = Math.round(childScrollableHeight * interpolator.getInterpolation(offsetForView / (float) childScrollableHeight)); + + return Integer.signum(offset) * (child.getTop() + interpolatedDiff); + } + } + + break; + } + } + + return offset; } - } - return null; - } - @Override - int getTopBottomOffsetForScrollingSibling() { - return getTopAndBottomOffset() + offsetDelta; - } + private void updateAppBarLayoutDrawableState(@NonNull final SamsungCoordinatorLayout parent, @NonNull final T layout, final int offset, final int direction, final boolean forceJump) { + final View child = getAppBarChildOnOffset(layout, offset); + boolean lifted = false; + if (child != null) { + final SamsungAppBarLayout.LayoutParams childLp = (LayoutParams) child.getLayoutParams(); + final int flags = childLp.getScrollFlags(); - @Override - public Parcelable onSaveInstanceState(@NonNull SamsungCoordinatorLayout parent, @NonNull T abl) { - Parcelable superState = super.onSaveInstanceState(parent, abl); + if ((flags & LayoutParams.SCROLL_FLAG_SCROLL) != 0) { + final int minHeight = ViewCompat.getMinimumHeight(child); + + if (direction > 0 && (flags & (LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED)) != 0) { + lifted = -offset >= child.getBottom() - minHeight - layout.getTopInset() - layout.getImmersiveTopInset(); + } else if ((flags & LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED) != 0) { + lifted = -offset >= child.getBottom() - minHeight - layout.getTopInset() - layout.getImmersiveTopInset(); + } + } - for (int i = 0; i < abl.getChildCount(); i++) { - View child = abl.getChildAt(i); - int bottom = child.getBottom() + getTopAndBottomOffset(); + if (layout.isLiftOnScroll()) { + lifted = layout.shouldLift(findFirstScrollingChild(parent)); + } - if (child.getTop() + getTopAndBottomOffset() <= 0 && bottom >= 0) { - SavedState savedState = new SavedState(superState); - savedState.firstVisibleChildIndex = i; - savedState.firstVisibleChildAtMinimumHeight = bottom == ViewCompat.getMinimumHeight(child) + abl.getTopInset(); - savedState.firstVisibleChildPercentageShown = ((float) bottom) / ((float) child.getHeight()); - return savedState; + final boolean changed = layout.setLiftedState(lifted); + + if (forceJump || (changed && shouldJumpElevationState(parent, layout))) { + layout.jumpDrawablesToCurrentState(); + } + } } - } - return superState; - } + private boolean shouldJumpElevationState(@NonNull SamsungCoordinatorLayout parent, @NonNull T layout) { + final List dependencies = parent.getDependents(layout); + for (int i = 0, size = dependencies.size(); i < size; i++) { + final View dependency = dependencies.get(i); + final SamsungCoordinatorLayout.LayoutParams lp = (SamsungCoordinatorLayout.LayoutParams) dependency.getLayoutParams(); + final SamsungCoordinatorLayout.Behavior behavior = lp.getBehavior(); - @Override - public void onRestoreInstanceState(@NonNull SamsungCoordinatorLayout parent, @NonNull T appBarLayout, Parcelable state) { - if (state instanceof SavedState) { - SavedState savedState = (SavedState) state; - super.onRestoreInstanceState(parent, appBarLayout, savedState.getSuperState()); - offsetToChildIndexOnLayout = savedState.firstVisibleChildIndex; - offsetToChildIndexOnLayoutPerc = savedState.firstVisibleChildPercentageShown; - offsetToChildIndexOnLayoutIsMinHeight = savedState.firstVisibleChildAtMinimumHeight; - } else { - super.onRestoreInstanceState(parent, appBarLayout, state); - offsetToChildIndexOnLayout = -1; - } - } - - protected static class SavedState extends AbsSavedState { - boolean firstVisibleChildAtMinimumHeight; - int firstVisibleChildIndex; - float firstVisibleChildPercentageShown; - - public SavedState(@NonNull Parcel source, ClassLoader loader) { - super(source, loader); - firstVisibleChildIndex = source.readInt(); - firstVisibleChildPercentageShown = source.readFloat(); - firstVisibleChildAtMinimumHeight = source.readByte() != 0; - } - - public SavedState(Parcelable superState) { - super(superState); - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - super.writeToParcel(dest, flags); - dest.writeInt(firstVisibleChildIndex); - dest.writeFloat(firstVisibleChildPercentageShown); - dest.writeByte((byte) (firstVisibleChildAtMinimumHeight ? 1 : 0)); - } - - public static final Creator CREATOR = new ClassLoaderCreator() { - @NonNull - @Override - public SavedState createFromParcel(@NonNull Parcel source, ClassLoader loader) { - return new SavedState(source, loader); + if (behavior instanceof ScrollingViewBehavior) { + return ((ScrollingViewBehavior) behavior).getOverlayTop() != 0; + } + } + return false; } @Nullable - @Override - public SavedState createFromParcel(@NonNull Parcel source) { - return new SavedState(source, null); + private static View getAppBarChildOnOffset(@NonNull final SamsungAppBarLayout layout, final int offset) { + final int absOffset = Math.abs(offset); + for (int i = 0, z = layout.getChildCount(); i < z; i++) { + final View child = layout.getChildAt(i); + if (absOffset >= child.getTop() && absOffset <= child.getBottom()) { + return child; + } + } + return null; + } + + @Nullable + private View findFirstScrollingChild(@NonNull SamsungCoordinatorLayout parent) { + for (int i = 0, z = parent.getChildCount(); i < z; i++) { + final View child = parent.getChildAt(i); + if (child instanceof NestedScrollingChild || child instanceof ListView || child instanceof ScrollView) { + return child; + } + } + return null; } - @NonNull @Override - public SavedState[] newArray(int size) { - return new SavedState[size]; + int getTopBottomOffsetForScrollingSibling() { + return getTopAndBottomOffset() + offsetDelta; } - }; - } - // kang - private boolean isScrollHoldMode(T appBarLayout) { - if (mToolisMouse) { - return false; - } - int childIndexOnOffset = getChildIndexOnOffset(appBarLayout, getTopBottomOffsetForScrollingSibling()); - return childIndexOnOffset < 0 || (((LayoutParams) appBarLayout.getChildAt(childIndexOnOffset).getLayoutParams()).getScrollFlags() & 65536) != 65536; - } + @Override + public Parcelable onSaveInstanceState(@NonNull SamsungCoordinatorLayout parent, @NonNull T abl) { + Parcelable superState = super.onSaveInstanceState(parent, abl); + + for (int i = 0; i < abl.getChildCount(); i++) { + View child = abl.getChildAt(i); + int bottom = child.getBottom() + getTopAndBottomOffset(); + + if (child.getTop() + getTopAndBottomOffset() <= 0 && bottom >= 0) { + SavedState savedState = new SavedState(superState); + savedState.firstVisibleChildIndex = i; + savedState.firstVisibleChildAtMinimumHeight = bottom == ViewCompat.getMinimumHeight(child) + abl.getTopInset(); + savedState.firstVisibleChildPercentageShown = ((float) bottom) / ((float) child.getHeight()); + return savedState; + } + } - @Override - public boolean onNestedPreFling(SamsungCoordinatorLayout coordinatorLayout, T t, View view, float f, float f2) { - this.mVelocity = f2; - if (f2 < -300.0f) { - this.mIsFlingScrollDown = true; - this.mIsFlingScrollUp = false; - } else if (f2 > 300.0f) { - this.mIsFlingScrollDown = false; - this.mIsFlingScrollUp = true; - } else { - this.mVelocity = 0.0f; - this.mIsFlingScrollDown = false; - this.mIsFlingScrollUp = false; - return true; - } - return super.onNestedPreFling(coordinatorLayout, t, view, f, f2); - } + return superState; + } - @Override - public boolean onTouchEvent(SamsungCoordinatorLayout var1, T var2, MotionEvent var3) { - if (this.mTouchSlop < 0) { - this.mTouchSlop = ViewConfiguration.get(var1.getContext()).getScaledTouchSlop(); - } + @Override + public void onRestoreInstanceState(@NonNull SamsungCoordinatorLayout parent, @NonNull T appBarLayout, Parcelable state) { + if (state instanceof SavedState) { + SavedState savedState = (SavedState) state; + super.onRestoreInstanceState(parent, appBarLayout, savedState.getSuperState()); + offsetToChildIndexOnLayout = savedState.firstVisibleChildIndex; + offsetToChildIndexOnLayoutPerc = savedState.firstVisibleChildPercentageShown; + offsetToChildIndexOnLayoutIsMinHeight = savedState.firstVisibleChildAtMinimumHeight; + } else { + super.onRestoreInstanceState(parent, appBarLayout, state); + offsetToChildIndexOnLayout = -1; + } + } + + protected static class SavedState extends AbsSavedState { + boolean firstVisibleChildAtMinimumHeight; + int firstVisibleChildIndex; + float firstVisibleChildPercentageShown; - int var4 = var3.getAction(); - this.mToolisMouse = var2.getIsMouse(); - float var6; - if (var4 != 0) { - if (var4 != 1) { - if (var4 == 2) { - this.mDirectTouchAppbar = true; - float var5 = var3.getY(); - var6 = this.mLastMotionY_Touch; - if (var5 - var6 != 0.0F) { - this.mDiffY_Touch = var5 - var6; + public SavedState(@NonNull Parcel source, ClassLoader loader) { + super(source, loader); + firstVisibleChildIndex = source.readInt(); + firstVisibleChildPercentageShown = source.readFloat(); + firstVisibleChildAtMinimumHeight = source.readByte() != 0; } - if (Math.abs(this.mDiffY_Touch) > (float)this.mTouchSlop) { - this.mLastMotionY_Touch = var5; + public SavedState(Parcelable superState) { + super(superState); } - return super.onTouchEvent(var1, var2, var3); - } + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeInt(firstVisibleChildIndex); + dest.writeFloat(firstVisibleChildPercentageShown); + dest.writeByte((byte) (firstVisibleChildAtMinimumHeight ? 1 : 0)); + } - if (var4 != 3) { - return super.onTouchEvent(var1, var2, var3); - } - } - - if (Math.abs(this.mDiffY_Touch) > 21.0F) { - var6 = this.mDiffY_Touch; - if (var6 < 0.0F) { - this.mIsFlingScrollUp = true; - this.mIsFlingScrollDown = false; - } else if (var6 > 0.0F) { - this.mIsFlingScrollUp = false; - this.mIsFlingScrollDown = true; - } - } else { - this.touchX = 0.0F; - this.touchY = 0.0F; - this.mIsFlingScrollUp = false; - this.mIsFlingScrollDown = false; - this.mLastMotionY_Touch = 0.0F; + public static final Creator CREATOR = new ClassLoaderCreator() { + @NonNull + @Override + public SavedState createFromParcel(@NonNull Parcel source, ClassLoader loader) { + return new SavedState(source, loader); + } + + @Nullable + @Override + public SavedState createFromParcel(@NonNull Parcel source) { + return new SavedState(source, null); + } + + @NonNull + @Override + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; } - if (this.mDirectTouchAppbar) { - this.mDirectTouchAppbar = false; - this.snapToChildIfNeeded(var1, var2); + // kang + private boolean isScrollHoldMode(T appBarLayout) { + if (mToolisMouse) { + return false; + } + int childIndexOnOffset = getChildIndexOnOffset(appBarLayout, getTopBottomOffsetForScrollingSibling()); + return childIndexOnOffset < 0 || (((LayoutParams) appBarLayout.getChildAt(childIndexOnOffset).getLayoutParams()).getScrollFlags() & 65536) != 65536; } - } else { - this.mDirectTouchAppbar = true; - this.touchX = var3.getX(); - var6 = var3.getY(); - this.touchY = var6; - this.mLastMotionY_Touch = var6; - this.mDiffY_Touch = 0.0F; - } - return super.onTouchEvent(var1, var2, var3); - } - // kang - } + @Override + public boolean onNestedPreFling(SamsungCoordinatorLayout coordinatorLayout, T t, View view, float f, float f2) { + this.mVelocity = f2; + if (f2 < -300.0f) { + this.mIsFlingScrollDown = true; + this.mIsFlingScrollUp = false; + } else if (f2 > 300.0f) { + this.mIsFlingScrollDown = false; + this.mIsFlingScrollUp = true; + } else { + this.mVelocity = 0.0f; + this.mIsFlingScrollDown = false; + this.mIsFlingScrollUp = false; + return true; + } + return super.onNestedPreFling(coordinatorLayout, t, view, f, f2); + } - public static class ScrollingViewBehavior extends HeaderScrollingViewBehavior { - public ScrollingViewBehavior() {} + @Override + public boolean onTouchEvent(SamsungCoordinatorLayout var1, T var2, MotionEvent var3) { + if (this.mTouchSlop < 0) { + this.mTouchSlop = ViewConfiguration.get(var1.getContext()).getScaledTouchSlop(); + } - public ScrollingViewBehavior(Context context, AttributeSet attrs) { - super(context, attrs); + int var4 = var3.getAction(); + this.mToolisMouse = var2.getIsMouse(); + float var6; + if (var4 != 0) { + if (var4 != 1) { + if (var4 == 2) { + this.mDirectTouchAppbar = true; + float var5 = var3.getY(); + var6 = this.mLastMotionY_Touch; + if (var5 - var6 != 0.0F) { + this.mDiffY_Touch = var5 - var6; + } + + if (Math.abs(this.mDiffY_Touch) > (float)this.mTouchSlop) { + this.mLastMotionY_Touch = var5; + } + + return super.onTouchEvent(var1, var2, var3); + } + + if (var4 != 3) { + return super.onTouchEvent(var1, var2, var3); + } + } + + if (Math.abs(this.mDiffY_Touch) > 21.0F) { + var6 = this.mDiffY_Touch; + if (var6 < 0.0F) { + this.mIsFlingScrollUp = true; + this.mIsFlingScrollDown = false; + } else if (var6 > 0.0F) { + this.mIsFlingScrollUp = false; + this.mIsFlingScrollDown = true; + } + } else { + this.touchX = 0.0F; + this.touchY = 0.0F; + this.mIsFlingScrollUp = false; + this.mIsFlingScrollDown = false; + this.mLastMotionY_Touch = 0.0F; + } + + if (this.mDirectTouchAppbar) { + this.mDirectTouchAppbar = false; + this.snapToChildIfNeeded(var1, var2); + } + } else { + this.mDirectTouchAppbar = true; + this.touchX = var3.getX(); + var6 = var3.getY(); + this.touchY = var6; + this.mLastMotionY_Touch = var6; + this.mDiffY_Touch = 0.0F; + } - final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScrollingViewBehavior_Layout); - setOverlayTop(a.getDimensionPixelSize(R.styleable.ScrollingViewBehavior_Layout_behavior_overlapTop, 0)); - a.recycle(); + return super.onTouchEvent(var1, var2, var3); + } + // kang } - @Override - public boolean layoutDependsOn(SamsungCoordinatorLayout parent, View child, View dependency) { - return dependency instanceof SamsungAppBarLayout; - } + public static class ScrollingViewBehavior extends HeaderScrollingViewBehavior { + public ScrollingViewBehavior() {} - @Override - public boolean onDependentViewChanged(@NonNull SamsungCoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { - offsetChildAsNeeded(child, dependency); - updateLiftedStateIfNeeded(child, dependency); - return false; - } + public ScrollingViewBehavior(Context context, AttributeSet attrs) { + super(context, attrs); - @Override - public void onDependentViewRemoved(@NonNull SamsungCoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { - if (dependency instanceof SamsungAppBarLayout) { - ViewCompat.removeAccessibilityAction(parent, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId()); - ViewCompat.removeAccessibilityAction(parent, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId()); - } - } + final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ScrollingViewBehavior_Layout); + setOverlayTop(a.getDimensionPixelSize(R.styleable.ScrollingViewBehavior_Layout_behavior_overlapTop, 0)); + a.recycle(); + } - @Override - public boolean onRequestChildRectangleOnScreen(@NonNull SamsungCoordinatorLayout parent, @NonNull View child, @NonNull Rect rectangle, boolean immediate) { - final SamsungAppBarLayout header = findFirstDependency(parent.getDependencies(child)); - if (header != null) { - rectangle.offset(child.getLeft(), child.getTop()); + @Override + public boolean layoutDependsOn(SamsungCoordinatorLayout parent, View child, View dependency) { + return dependency instanceof SamsungAppBarLayout; + } - final Rect parentRect = tempRect1; - parentRect.set(0, 0, parent.getWidth(), parent.getHeight()); + @Override + public boolean onDependentViewChanged(@NonNull SamsungCoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { + offsetChildAsNeeded(child, dependency); + updateLiftedStateIfNeeded(child, dependency); + return false; + } + + @Override + public void onDependentViewRemoved(@NonNull SamsungCoordinatorLayout parent, @NonNull View child, @NonNull View dependency) { + if (dependency instanceof SamsungAppBarLayout) { + ViewCompat.removeAccessibilityAction(parent, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_FORWARD.getId()); + ViewCompat.removeAccessibilityAction(parent, AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_SCROLL_BACKWARD.getId()); + } + } - if (!parentRect.contains(rectangle)) { - header.setExpanded(false, !immediate); - return true; + @Override + public boolean onRequestChildRectangleOnScreen(@NonNull SamsungCoordinatorLayout parent, @NonNull View child, @NonNull Rect rectangle, boolean immediate) { + final SamsungAppBarLayout header = findFirstDependency(parent.getDependencies(child)); + if (header != null) { + rectangle.offset(child.getLeft(), child.getTop()); + + final Rect parentRect = tempRect1; + parentRect.set(0, 0, parent.getWidth(), parent.getHeight()); + + if (!parentRect.contains(rectangle)) { + header.setExpanded(false, !immediate); + return true; + } + } + return false; } - } - return false; - } - private void offsetChildAsNeeded(@NonNull View child, @NonNull View dependency) { - final SamsungCoordinatorLayout.Behavior behavior = ((SamsungCoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior(); - if (behavior instanceof BaseBehavior) { - final BaseBehavior ablBehavior = (BaseBehavior) behavior; - ViewCompat.offsetTopAndBottom(child, (dependency.getBottom() - child.getTop()) + ablBehavior.offsetDelta + getVerticalLayoutGap() - getOverlapPixelsForOffset(dependency)); - } - } + private void offsetChildAsNeeded(@NonNull View child, @NonNull View dependency) { + final SamsungCoordinatorLayout.Behavior behavior = ((SamsungCoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior(); + if (behavior instanceof BaseBehavior) { + final BaseBehavior ablBehavior = (BaseBehavior) behavior; + ViewCompat.offsetTopAndBottom(child, (dependency.getBottom() - child.getTop()) + ablBehavior.offsetDelta + getVerticalLayoutGap() - getOverlapPixelsForOffset(dependency)); + } + } - @Override - float getOverlapRatioForOffset(final View header) { - if (header instanceof SamsungAppBarLayout) { - final SamsungAppBarLayout abl = (SamsungAppBarLayout) header; - final int totalScrollRange = abl.getTotalScrollRange(); - final int preScrollDown = abl.getDownNestedPreScrollRange(); - final int offset = getAppBarLayoutOffset(abl); - - if (preScrollDown != 0 && (totalScrollRange + offset) <= preScrollDown) { - return 0; - } else { - final int availScrollRange = totalScrollRange - preScrollDown; - if (availScrollRange != 0) { - return 1f + (offset / (float) availScrollRange); - } + @Override + float getOverlapRatioForOffset(final View header) { + if (header instanceof SamsungAppBarLayout) { + final SamsungAppBarLayout abl = (SamsungAppBarLayout) header; + final int totalScrollRange = abl.getTotalScrollRange(); + final int preScrollDown = abl.getDownNestedPreScrollRange(); + final int offset = getAppBarLayoutOffset(abl); + + if (preScrollDown != 0 && (totalScrollRange + offset) <= preScrollDown) { + return 0; + } else { + final int availScrollRange = totalScrollRange - preScrollDown; + if (availScrollRange != 0) { + return 1f + (offset / (float) availScrollRange); + } + } + } + return 0f; } - } - return 0f; - } - private static int getAppBarLayoutOffset(@NonNull SamsungAppBarLayout abl) { - final SamsungCoordinatorLayout.Behavior behavior = ((SamsungCoordinatorLayout.LayoutParams) abl.getLayoutParams()).getBehavior(); - if (behavior instanceof BaseBehavior) { - return ((BaseBehavior) behavior).getTopBottomOffsetForScrollingSibling(); - } - return 0; - } + private static int getAppBarLayoutOffset(@NonNull SamsungAppBarLayout abl) { + final SamsungCoordinatorLayout.Behavior behavior = ((SamsungCoordinatorLayout.LayoutParams) abl.getLayoutParams()).getBehavior(); + if (behavior instanceof BaseBehavior) { + return ((BaseBehavior) behavior).getTopBottomOffsetForScrollingSibling(); + } + return 0; + } - @Nullable - @Override - SamsungAppBarLayout findFirstDependency(@NonNull List views) { - for (int i = 0, z = views.size(); i < z; i++) { - View view = views.get(i); - if (view instanceof SamsungAppBarLayout) { - return (SamsungAppBarLayout) view; + @Nullable + @Override + SamsungAppBarLayout findFirstDependency(@NonNull List views) { + for (int i = 0, z = views.size(); i < z; i++) { + View view = views.get(i); + if (view instanceof SamsungAppBarLayout) { + return (SamsungAppBarLayout) view; + } + } + return null; } - } - return null; - } - @Override - int getScrollRange(View v) { - if (v instanceof SamsungAppBarLayout) { - return ((SamsungAppBarLayout) v).getTotalScrollRange(); - } else { - return super.getScrollRange(v); - } - } + @Override + int getScrollRange(View v) { + if (v instanceof SamsungAppBarLayout) { + return ((SamsungAppBarLayout) v).getTotalScrollRange(); + } else { + return super.getScrollRange(v); + } + } - private void updateLiftedStateIfNeeded(View child, View dependency) { - if (dependency instanceof SamsungAppBarLayout) { - SamsungAppBarLayout appBarLayout = (SamsungAppBarLayout) dependency; - if (appBarLayout.isLiftOnScroll()) { - appBarLayout.setLiftedState(appBarLayout.shouldLift(child)); + private void updateLiftedStateIfNeeded(View child, View dependency) { + if (dependency instanceof SamsungAppBarLayout) { + SamsungAppBarLayout appBarLayout = (SamsungAppBarLayout) dependency; + if (appBarLayout.isLiftOnScroll()) { + appBarLayout.setLiftedState(appBarLayout.shouldLift(child)); + } + } } - } } - } - private boolean isDexEnabled() { - if (getContext() == null) { - return false; + private boolean isDexEnabled() { + if (getContext() == null) { + return false; + } + return SeslConfigurationReflector.isDexEnabled(getContext().getResources().getConfiguration()); } - return SeslConfigurationReflector.isDexEnabled(getContext().getResources().getConfiguration()); - } - protected boolean isDetachedState() { - return mIsDetachedState; - } + protected boolean isDetachedState() { + return mIsDetachedState; + } } diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/colorpicker/detailed/SeslColorPicker.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/colorpicker/detailed/SeslColorPicker.java index 02902fb0..09d83fb9 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/colorpicker/detailed/SeslColorPicker.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/colorpicker/detailed/SeslColorPicker.java @@ -196,7 +196,7 @@ private void initCurrentColorView() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mColorPickerTabSwatchesText.setTextAppearance(R.style.TabTextSelected); } - mColorPickerTabSwatchesText.setTextColor(getResources().getColor(R.color.sesl_dialog_body_text_color)); + mColorPickerTabSwatchesText.setTextColor(getResources().getColor(R.color.sesl4_tablayout_subtab_background_stroke_color)); mColorPickerTabSpectrumText.setTextColor(getResources().getColor(R.color.sesl_secondary_text_color)); mColorPickerOpacityEditText.setTag(1); mFlagVar = true; @@ -254,7 +254,7 @@ public void onClick(View v) { mColorPickerTabSwatchesText.setBackgroundResource(mIsOneUI4 ? R.drawable.sesl4_color_picker_tab_selector_bg : R.drawable.sesl_color_picker_tab_selector_bg); mColorPickerTabSpectrumText.setSelected(false); mColorPickerTabSpectrumText.setBackgroundResource(0); - mColorPickerTabSwatchesText.setTextColor(getResources().getColor(R.color.sesl_dialog_body_text_color)); + mColorPickerTabSwatchesText.setTextColor(getResources().getColor(R.color.sesl4_tablayout_subtab_background_stroke_color)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mColorPickerTabSwatchesText.setTextAppearance(R.style.TabTextSelected); } @@ -275,7 +275,7 @@ public void onClick(View v) { mColorPickerTabSpectrumText.setBackgroundResource(mIsOneUI4 ? R.drawable.sesl4_color_picker_tab_selector_bg : R.drawable.sesl_color_picker_tab_selector_bg); mColorPickerTabSwatchesText.setBackgroundResource(0); initColorSpectrumView(); - mColorPickerTabSpectrumText.setTextColor(getResources().getColor(R.color.sesl_dialog_body_text_color)); + mColorPickerTabSpectrumText.setTextColor(getResources().getColor(R.color.sesl4_tablayout_subtab_background_stroke_color)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { mColorPickerTabSpectrumText.setTextAppearance(R.style.TabTextSelected); } diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/ElasticTabIndicatorInterpolator.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/ElasticTabIndicatorInterpolator.java new file mode 100644 index 00000000..ff4ea242 --- /dev/null +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/ElasticTabIndicatorInterpolator.java @@ -0,0 +1,40 @@ +package de.dlyt.yanndroid.oneui.sesl.tabs; + +import static com.google.android.material.animation.AnimationUtils.lerp; + +import android.annotation.SuppressLint; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.view.View; +import androidx.annotation.FloatRange; +import androidx.annotation.NonNull; + +class ElasticTabIndicatorInterpolator extends TabIndicatorInterpolator { + private static float decInterp(@FloatRange(from = 0.0, to = 1.0) float fraction) { + return (float) Math.sin((fraction * Math.PI) / 2.0); + } + + private static float accInterp(@FloatRange(from = 0.0, to = 1.0) float fraction) { + return (float) (1.0 - Math.cos((fraction * Math.PI) / 2.0)); + } + + @SuppressLint("RestrictedApi") + @Override + void setIndicatorBoundsForOffset(SamsungTabLayout tabLayout, View startTitle, View endTitle, float offset, @NonNull Drawable indicator) { + RectF startIndicator = calculateIndicatorWidthForTab(tabLayout, startTitle); + RectF endIndicator = calculateIndicatorWidthForTab(tabLayout, endTitle); + + float leftFraction; + float rightFraction; + + final boolean isMovingRight = startIndicator.left < endIndicator.left; + if (isMovingRight) { + leftFraction = accInterp(offset); + rightFraction = decInterp(offset); + } else { + leftFraction = decInterp(offset); + rightFraction = accInterp(offset); + } + indicator.setBounds(lerp((int) startIndicator.left, (int) endIndicator.left, leftFraction), indicator.getBounds().top, lerp((int) startIndicator.right, (int) endIndicator.right, rightFraction), indicator.getBounds().bottom); + } +} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungBaseTabLayout.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungBaseTabLayout.java deleted file mode 100644 index 57b590d5..00000000 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungBaseTabLayout.java +++ /dev/null @@ -1,2706 +0,0 @@ -package de.dlyt.yanndroid.oneui.sesl.tabs; - -import android.animation.Animator; -import android.animation.ValueAnimator; -import android.annotation.SuppressLint; -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.database.DataSetObserver; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.RectF; -import android.graphics.Typeface; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.os.Build; -import android.text.Layout; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityNodeInfo; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.view.animation.AnimationSet; -import android.view.animation.ScaleAnimation; -import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.appcompat.animation.SeslAnimationUtils; -import androidx.appcompat.content.res.AppCompatResources; -import androidx.appcompat.widget.TooltipCompat; -import androidx.core.content.ContextCompat; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.core.util.Pools; -import androidx.core.view.AccessibilityDelegateCompat; -import androidx.core.view.MarginLayoutParamsCompat; -import androidx.core.view.PointerIconCompat; -import androidx.core.view.ViewCompat; -import androidx.core.widget.TextViewCompat; -import androidx.viewpager.widget.PagerAdapter; -import androidx.viewpager.widget.SeslViewPager; - -import com.google.android.material.animation.AnimationUtils; -import com.google.android.material.badge.BadgeDrawable; -import com.google.android.material.badge.BadgeUtils; -import com.google.android.material.internal.ViewUtils; -import com.google.android.material.resources.MaterialResources; -import com.google.android.material.shape.MaterialShapeDrawable; -import com.google.android.material.shape.MaterialShapeUtils; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Iterator; - -import de.dlyt.yanndroid.oneui.R; - -@SeslViewPager.DecorView -public class SamsungBaseTabLayout extends HorizontalScrollView { - private boolean mIsOneUI4; - public static final Pools.Pool tabPool = new Pools.SynchronizedPool(16); - public final int requestedTabMaxWidth; - public final int requestedTabMinWidth; - public final int scrollableTabMinWidth; - public final ArrayList selectedListeners; - public final SlidingTabIndicator slidingTabIndicator; - public final int tabBackgroundResId; - public final RectF tabViewContentBounds; - public final Pools.Pool tabViewPool; - public final ArrayList tabs; - public AdapterChangeListener adapterChangeListener; - public int contentInsetStart; - public BaseOnTabSelectedListener currentVpSelectedListener; - public boolean inlineLabel; - public int mBadgeColor; - public int mBadgeTextColor; - public Typeface mBoldTypeface; - public int mDepthStyle; - public int mIconTextGap; - public boolean mIsScaledTextSizeType; - public Typeface mNormalTypeface; - public int mRequestedTabWidth; - public int mSubTabIndicatorHeight; - public int mSubTabSelectedIndicatorColor; - public int mTabSelectedIndicatorColor; - public int mode; - public TabLayoutOnPageChangeListener pageChangeListener; - public PagerAdapter pagerAdapter; - public DataSetObserver pagerAdapterObserver; - public ValueAnimator scrollAnimator; - public BaseOnTabSelectedListener selectedListener; - public Tab selectedTab; - public boolean setupViewPagerImplicitly; - public int tabGravity; - public ColorStateList tabIconTint; - public PorterDuff.Mode tabIconTintMode; - public int tabIndicatorAnimationDuration; - public boolean tabIndicatorFullWidth; - public int tabIndicatorGravity; - public int tabMaxWidth; - public int tabPaddingBottom; - public int tabPaddingEnd; - public int tabPaddingStart; - public int tabPaddingTop; - public ColorStateList tabRippleColorStateList; - public Drawable tabSelectedIndicator; - public int tabTextAppearance; - public ColorStateList tabTextColors; - public float tabTextMultiLineSize; - public float tabTextSize; - public boolean unboundedRipple; - public SeslViewPager viewPager; - - public SamsungBaseTabLayout(Context var1) { - this(var1, (AttributeSet) null); - } - - public SamsungBaseTabLayout(Context var1, AttributeSet var2) { - this(var1, var2, R.attr.tabStyle); - } - - @SuppressLint({"RestrictedApi", "WrongConstant"}) - public SamsungBaseTabLayout(Context var1, AttributeSet var2, int var3) { - super(var1, var2, var3); - this.tabs = new ArrayList(); - this.tabViewContentBounds = new RectF(); - this.tabMaxWidth = 2147483647; - this.selectedListeners = new ArrayList(); - this.tabViewPool = new Pools.SimplePool(12); - this.mIconTextGap = -1; - this.mDepthStyle = 1; - this.mBadgeColor = -1; - this.mBadgeTextColor = -1; - this.mRequestedTabWidth = -1; - this.mSubTabSelectedIndicatorColor = -1; - this.mSubTabIndicatorHeight = 1; - this.mIsScaledTextSizeType = false; - - mIsOneUI4 = var1.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); - - this.setHorizontalScrollBarEnabled(false); - this.slidingTabIndicator = new SlidingTabIndicator(var1); - super.addView(this.slidingTabIndicator, 0, new LayoutParams(-2, -1)); - int[] var4 = R.styleable.SamsungTabLayout; - int var5 = R.style.BaseTabLayoutStyle; - - TypedArray var9 = var1.obtainStyledAttributes(var2, var4, var3, var5); - if (this.getBackground() instanceof ColorDrawable) { - ColorDrawable var6 = (ColorDrawable) this.getBackground(); - MaterialShapeDrawable var10 = new MaterialShapeDrawable(); - var10.setFillColor(ColorStateList.valueOf(var6.getColor())); - var10.initializeElevationOverlay(var1); - var10.setElevation(ViewCompat.getElevation(this)); - ViewCompat.setBackground(this, var10); - } - - this.slidingTabIndicator.setSelectedIndicatorHeight(var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabIndicatorHeight, -1)); - this.mTabSelectedIndicatorColor = var9.getColor(R.styleable.SamsungTabLayout_tabIndicatorColor, 0); - this.slidingTabIndicator.setSelectedIndicatorColor(this.mTabSelectedIndicatorColor); - this.slidingTabIndicator.setSelectedIndicatorColor(this.mTabSelectedIndicatorColor); - this.setSelectedTabIndicator(MaterialResources.getDrawable(var1, var9, R.styleable.SamsungTabLayout_tabIndicator)); - this.setSelectedTabIndicatorGravity(var9.getInt(R.styleable.SamsungTabLayout_tabIndicatorGravity, 0)); - this.setTabIndicatorFullWidth(var9.getBoolean(R.styleable.SamsungTabLayout_tabIndicatorFullWidth, true)); - var3 = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPadding, 0); - this.tabPaddingBottom = var3; - this.tabPaddingEnd = var3; - this.tabPaddingTop = var3; - this.tabPaddingStart = var3; - this.tabPaddingStart = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingStart, this.tabPaddingStart); - this.tabPaddingTop = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingTop, this.tabPaddingTop); - this.tabPaddingEnd = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingEnd, this.tabPaddingEnd); - this.tabPaddingBottom = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingBottom, this.tabPaddingBottom); - this.tabTextAppearance = var9.getResourceId(R.styleable.SamsungTabLayout_tabTextAppearance, R.style.TabLayoutTextStyle); - TypedArray var11 = var1.obtainStyledAttributes(this.tabTextAppearance, androidx.appcompat.R.styleable.TextAppearance); - - try { - this.tabTextSize = (float) var11.getDimensionPixelSize(androidx.appcompat.R.styleable.TextAppearance_android_textSize, 0); - this.mIsScaledTextSizeType = var11.getText(androidx.appcompat.R.styleable.TextAppearance_android_textSize).toString().contains("sp"); - this.tabTextColors = MaterialResources.getColorStateList(var1, var11, androidx.appcompat.R.styleable.TextAppearance_android_textColor); - } finally { - var11.recycle(); - } - - Resources var12 = this.getResources(); - String var13 = var12.getString(R.string.sesl_font_family_regular); - this.mBoldTypeface = Typeface.create(var13, 1); - this.mNormalTypeface = Typeface.create(var13, 0); - this.mSubTabIndicatorHeight = var12.getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_indicator_height); - if (var9.hasValue(R.styleable.SamsungTabLayout_tabTextColor)) { - this.tabTextColors = MaterialResources.getColorStateList(var1, var9, R.styleable.SamsungTabLayout_tabTextColor); - } - - if (var9.hasValue(R.styleable.SamsungTabLayout_tabSelectedTextColor)) { - var3 = var9.getColor(R.styleable.SamsungTabLayout_tabSelectedTextColor, 0); - this.tabTextColors = createColorStateList(this.tabTextColors.getDefaultColor(), var3); - } - - this.tabIconTint = MaterialResources.getColorStateList(var1, var9, R.styleable.SamsungTabLayout_tabIconTint); - this.tabIconTintMode = ViewUtils.parseTintMode(var9.getInt(R.styleable.SamsungTabLayout_tabIconTintMode, -1), (PorterDuff.Mode) null); - this.tabRippleColorStateList = MaterialResources.getColorStateList(var1, var9, R.styleable.SamsungTabLayout_tabRippleColor); - this.tabIndicatorAnimationDuration = var9.getInt(R.styleable.SamsungTabLayout_tabIndicatorAnimationDuration, 300); - this.requestedTabMinWidth = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabMinWidth, -1); - this.requestedTabMaxWidth = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabMaxWidth, -1); - this.tabBackgroundResId = var9.getResourceId(R.styleable.SamsungTabLayout_tabBackground, 0); - this.contentInsetStart = var9.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabContentStart, 0); - this.mode = var9.getInt(R.styleable.SamsungTabLayout_tabMode, 1); - this.tabGravity = var9.getInt(R.styleable.SamsungTabLayout_tabGravity, 0); - this.inlineLabel = var9.getBoolean(R.styleable.SamsungTabLayout_tabInlineLabel, false); - this.unboundedRipple = var9.getBoolean(R.styleable.SamsungTabLayout_tabUnboundedRipple, false); - var9.recycle(); - this.tabTextMultiLineSize = (float) var12.getDimensionPixelSize(R.dimen.sesl_tab_text_size_2line); - this.scrollableTabMinWidth = var12.getDimensionPixelSize(R.dimen.sesl_tab_scrollable_min_width); - this.applyModeAndGravity(); - } - - public static ColorStateList createColorStateList(int var0, int var1) { - return new ColorStateList(new int[][]{HorizontalScrollView.SELECTED_STATE_SET, HorizontalScrollView.EMPTY_STATE_SET}, new int[]{var1, var0}); - } - - private int getDefaultHeight() { - int var1 = this.tabs.size(); - boolean var2 = false; - int var3 = 0; - - boolean var4; - while (true) { - var4 = var2; - if (var3 >= var1) { - break; - } - - Tab var5 = (Tab) this.tabs.get(var3); - if (var5 != null && var5.getIcon() != null && !TextUtils.isEmpty(var5.getText())) { - var4 = true; - break; - } - - ++var3; - } - - byte var6; - if (var4 && !this.inlineLabel) { - var6 = 72; - } else { - var6 = 48; - } - - return var6; - } - - private int getSelectedTabTextColor() { - ColorStateList var1 = this.tabTextColors; - if (var1 != null) { - int var2 = var1.getDefaultColor(); - return var1.getColorForState(new int[]{16842913, 16842910}, var2); - } else { - return -1; - } - } - - private int getTabMinWidth() { - int var1 = this.requestedTabMinWidth; - return var1 != -1 ? var1 : 0; - } - - private int getTabScrollRange() { - return Math.max(0, this.slidingTabIndicator.getWidth() - this.getWidth() - this.getPaddingLeft() - this.getPaddingRight()); - } - - public void addOnTabSelectedListener(OnTabSelectedListener var1) { - addOnTabSelectedListener((BaseOnTabSelectedListener) var1); - } - - @Deprecated - public void addOnTabSelectedListener(BaseOnTabSelectedListener var1) { - if (!this.selectedListeners.contains(var1)) { - this.selectedListeners.add(var1); - } - } - - public void addTab(Tab var1) { - this.addTab(var1, this.tabs.isEmpty()); - } - - public void addTab(Tab var1, int var2, boolean var3) { - if (var1.parent == this) { - this.configureTab(var1, var2); - this.addTabView(var1); - if (var3) { - var1.select(); - } - - } else { - throw new IllegalArgumentException("Tab belongs to a different TabLayout."); - } - } - - public void addTab(Tab var1, boolean var2) { - this.addTab(var1, this.tabs.size(), var2); - } - - public final void addTabFromItemView(TabItem var1) { - Tab var2 = this.newTab(); - CharSequence var3 = var1.text; - if (var3 != null) { - var2.setText(var3); - } - - Drawable var5 = var1.icon; - if (var5 != null) { - var2.setIcon(var5); - } - - int var4 = var1.customLayout; - if (var4 != 0) { - var2.setCustomView(var4); - } - - if (!TextUtils.isEmpty(var1.getContentDescription())) { - var2.setContentDescription(var1.getContentDescription()); - } - - this.addTab(var2); - } - - public final void addTabView(Tab var1) { - TabView var2 = var1.view; - var2.setSelected(false); - var2.setActivated(false); - this.slidingTabIndicator.addView(var2, var1.getPosition(), this.createLayoutParamsForTabs()); - } - - public void addView(View var1) { - this.addViewInternal(var1); - } - - public void addView(View var1, int var2) { - this.addViewInternal(var1); - } - - public void addView(View var1, int var2, ViewGroup.LayoutParams var3) { - this.addViewInternal(var1); - } - - public void addView(View var1, ViewGroup.LayoutParams var2) { - this.addViewInternal(var1); - } - - public final void addViewInternal(View var1) { - if (var1 instanceof TabItem) { - this.addTabFromItemView((TabItem) var1); - } else { - throw new IllegalArgumentException("Only TabItem instances can be added to TabLayout"); - } - } - - public final void animateToTab(int var1) { - if (var1 != -1) { - if (this.getWindowToken() != null && ViewCompat.isLaidOut(this) && !this.slidingTabIndicator.childrenNeedLayout()) { - int var2 = this.getScrollX(); - int var3 = this.calculateScrollXForTab(var1, 0.0F); - if (var2 != var3) { - this.ensureScrollAnimator(); - this.scrollAnimator.setIntValues(new int[]{var2, var3}); - this.scrollAnimator.start(); - } - - this.slidingTabIndicator.animateIndicatorToPosition(var1, this.tabIndicatorAnimationDuration); - } else { - this.setScrollPosition(var1, 0.0F, true); - } - } - } - - public final void applyModeAndGravity() { - ViewCompat.setPaddingRelative(this.slidingTabIndicator, 0, 0, 0, 0); - int var1 = this.mode; - if (var1 != 0) { - if (var1 == 1 || var1 == 2) { - this.slidingTabIndicator.setGravity(1); - } - } else { - this.slidingTabIndicator.setGravity(8388611); - } - - this.updateTabViews(true); - } - - @SuppressLint("WrongConstant") - public final int calculateScrollXForTab(int var1, float var2) { - int var3 = this.mode; - int var4 = 0; - if (var3 != 0 && var3 != 2) { - return 0; - } else { - View var5 = this.slidingTabIndicator.getChildAt(var1); - ++var1; - View var6; - if (var1 < this.slidingTabIndicator.getChildCount()) { - var6 = this.slidingTabIndicator.getChildAt(var1); - } else { - var6 = null; - } - - if (var5 != null) { - var1 = var5.getWidth(); - } else { - var1 = 0; - } - - if (var6 != null) { - var4 = var6.getWidth(); - } - - var3 = var5.getLeft() + var1 / 2 - this.getWidth() / 2; - var1 = (int) ((float) (var1 + var4) * 0.5F * var2); - if (ViewCompat.getLayoutDirection(this) == 0) { - var1 += var3; - } else { - var1 = var3 - var1; - } - - return var1; - } - } - - public final void checkMaxFontScale(TextView var1, int var2) { - float var3 = this.getResources().getConfiguration().fontScale; - if (var1 != null && this.mIsScaledTextSizeType && var3 > 1.3F) { - var1.setTextSize(0, (float) var2 / var3 * 1.3F); - } - - } - - public final void configureTab(Tab var1, int var2) { - var1.setPosition(var2); - this.tabs.add(var2, var1); - int var3 = this.tabs.size(); - - while (true) { - ++var2; - if (var2 >= var3) { - return; - } - - ((Tab) this.tabs.get(var2)).setPosition(var2); - } - } - - public final LinearLayout.LayoutParams createLayoutParamsForTabs() { - LinearLayout.LayoutParams var1 = new LinearLayout.LayoutParams(-2, -1); - this.updateTabViewLayoutParams(var1); - return var1; - } - - public Tab createTabFromPool() { - Tab var1 = (Tab) tabPool.acquire(); - Tab var2 = var1; - if (var1 == null) { - var2 = new Tab(); - } - - return var2; - } - - public final TabView createTabView(Tab var1) { - Pools.Pool var2 = this.tabViewPool; - TabView var4; - if (var2 != null) { - var4 = (TabView) var2.acquire(); - } else { - var4 = null; - } - - TabView var3 = var4; - if (var4 == null) { - var3 = new TabView(this.getContext()); - } - - if (var3.mMainTabTouchBackground != null) { - var3.mMainTabTouchBackground.setAlpha(0.0F); - } - - var3.setTab(var1); - var3.setFocusable(true); - var3.setMinimumWidth(this.getTabMinWidth()); - if (TextUtils.isEmpty(var1.contentDesc)) { - var3.setContentDescription(var1.text); - } else { - var3.setContentDescription(var1.contentDesc); - } - - return var3; - } - - public final void dispatchTabReselected(Tab var1) { - for (int var2 = this.selectedListeners.size() - 1; var2 >= 0; --var2) { - ((BaseOnTabSelectedListener) this.selectedListeners.get(var2)).onTabReselected(var1); - } - - } - - public final void dispatchTabSelected(Tab var1) { - for (int var2 = this.selectedListeners.size() - 1; var2 >= 0; --var2) { - ((BaseOnTabSelectedListener) this.selectedListeners.get(var2)).onTabSelected(var1); - } - - } - - public final void dispatchTabUnselected(Tab var1) { - for (int var2 = this.selectedListeners.size() - 1; var2 >= 0; --var2) { - ((BaseOnTabSelectedListener) this.selectedListeners.get(var2)).onTabUnselected(var1); - } - - } - - public final void ensureScrollAnimator() { - if (this.scrollAnimator == null) { - this.scrollAnimator = new ValueAnimator(); - this.scrollAnimator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR); - this.scrollAnimator.setDuration((long) this.tabIndicatorAnimationDuration); - this.scrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - public void onAnimationUpdate(ValueAnimator var1) { - SamsungBaseTabLayout.this.scrollTo((Integer) var1.getAnimatedValue(), 0); - } - }); - } - - } - - public LayoutParams generateLayoutParams(AttributeSet var1) { - return this.generateDefaultLayoutParams(); - } - - public int getSelectedTabPosition() { - Tab var1 = this.selectedTab; - int var2; - if (var1 != null) { - var2 = var1.getPosition(); - } else { - var2 = -1; - } - - return var2; - } - - public Tab getTabAt(int var1) { - Tab var2; - if (var1 >= 0 && var1 < this.getTabCount()) { - var2 = (Tab) this.tabs.get(var1); - } else { - var2 = null; - } - - return var2; - } - - public int getTabCount() { - return this.tabs.size(); - } - - public int getTabGravity() { - return this.tabGravity; - } - - public void setTabGravity(int var1) { - if (this.tabGravity != var1) { - this.tabGravity = var1; - this.applyModeAndGravity(); - } - - } - - public ColorStateList getTabIconTint() { - return this.tabIconTint; - } - - public void setTabIconTint(ColorStateList var1) { - if (this.tabIconTint != var1) { - this.tabIconTint = var1; - this.updateAllTabs(); - } - - } - - public int getTabIndicatorGravity() { - return this.tabIndicatorGravity; - } - - public int getTabMaxWidth() { - return this.tabMaxWidth; - } - - public int getTabMode() { - return this.mode; - } - - public void setTabMode(int var1) { - if (var1 != this.mode) { - this.mode = var1; - this.applyModeAndGravity(); - } - - } - - public ColorStateList getTabRippleColor() { - return this.tabRippleColorStateList; - } - - public void setTabRippleColor(ColorStateList var1) { - if (this.tabRippleColorStateList != var1) { - this.tabRippleColorStateList = var1; - - for (int var2 = 0; var2 < this.slidingTabIndicator.getChildCount(); ++var2) { - View var3 = this.slidingTabIndicator.getChildAt(var2); - if (var3 instanceof TabView) { - ((TabView) var3).updateBackgroundDrawable(this.getContext()); - } - } - } - - } - - public Drawable getTabSelectedIndicator() { - return this.tabSelectedIndicator; - } - - public ColorStateList getTabTextColors() { - return this.tabTextColors; - } - - public void setTabTextColors(ColorStateList var1) { - if (this.tabTextColors != var1) { - this.tabTextColors = var1; - this.updateAllTabs(); - } - - } - - public Tab newTab() { - Tab var1 = this.createTabFromPool(); - var1.parent = this; - var1.view = this.createTabView(var1); - return var1; - } - - public void onAttachedToWindow() { - TabView tabView; - super.onAttachedToWindow(); - for (int i = 0; i < getTabCount(); i++) { - Tab tabAt = getTabAt(i); - if (!(tabAt == null || (tabView = tabAt.view) == null)) { - if (tabView.mMainTabTouchBackground != null) { - tabAt.view.mMainTabTouchBackground.setAlpha(0.0f); - } - if (tabAt.view.mIndicatorView != null) { - if (getSelectedTabPosition() == i) { - tabAt.view.mIndicatorView.setShow(); - } else { - tabAt.view.mIndicatorView.setHide(); - } - } - } - } - MaterialShapeUtils.setParentAbsoluteElevation(this); - if (this.viewPager == null) { - ViewParent parent = getParent(); - if (parent instanceof SeslViewPager) { - setupWithViewPager((SeslViewPager) parent, true, true); - } - } - } - - public void onConfigurationChanged(Configuration var1) { - super.onConfigurationChanged(var1); - - for (int var2 = 0; var2 < this.getTabCount(); ++var2) { - Tab var3 = this.getTabAt(var2); - if (var3 != null) { - TabView var4 = var3.view; - if (var4 != null && var4.mMainTabTouchBackground != null) { - var3.view.mMainTabTouchBackground.setAlpha(0.0F); - } - } - } - - this.updateBadgePosition(); - } - - public void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (this.setupViewPagerImplicitly) { - setupWithViewPager((SeslViewPager) null); - this.setupViewPagerImplicitly = false; - } - } - - public void onDraw(Canvas var1) { - for (int var2 = 0; var2 < this.slidingTabIndicator.getChildCount(); ++var2) { - View var3 = this.slidingTabIndicator.getChildAt(var2); - if (var3 instanceof TabView) { - ((TabView) var3).drawBackground(var1); - } - } - - super.onDraw(var1); - } - - public void onLayout(boolean var1, int var2, int var3, int var4, int var5) { - super.onLayout(var1, var2, var3, var4, var5); - if (var1) { - this.updateBadgePosition(); - } - - } - - @SuppressLint({"RestrictedApi", "WrongConstant"}) - public void onMeasure(int var1, int var2) { - int var3 = (int) ViewUtils.dpToPx(this.getContext(), this.getDefaultHeight()); - int var4 = MeasureSpec.getMode(var2); - boolean var5 = false; - if (var4 != -2147483648) { - if (var4 != 0) { - var4 = var2; - } else { - var4 = MeasureSpec.makeMeasureSpec(var3 + this.getPaddingTop() + this.getPaddingBottom(), 1073741824); - } - } else { - var4 = var2; - if (this.getChildCount() == 1) { - var4 = var2; - if (MeasureSpec.getSize(var2) >= var3) { - this.getChildAt(0).setMinimumHeight(var3); - var4 = var2; - } - } - } - - var3 = MeasureSpec.getSize(var1); - if (MeasureSpec.getMode(var1) != 0) { - var2 = this.requestedTabMaxWidth; - if (var2 <= 0) { - var2 = (int) ((float) var3 - ViewUtils.dpToPx(this.getContext(), 56)); - } - - this.tabMaxWidth = var2; - } - - super.onMeasure(var1, var4); - if (this.getChildCount() == 1) { - View var6; - boolean var7; - label46: - { - label45: - { - var6 = this.getChildAt(0); - var1 = this.mode; - if (var1 != 0) { - if (var1 == 1) { - var7 = var5; - if (var6.getMeasuredWidth() == this.getMeasuredWidth()) { - break label46; - } - break label45; - } - - if (var1 != 2) { - var7 = var5; - break label46; - } - } - - var7 = var5; - if (var6.getMeasuredWidth() >= this.getMeasuredWidth()) { - break label46; - } - } - - var7 = true; - } - - if (var7) { - var1 = HorizontalScrollView.getChildMeasureSpec(var4, this.getPaddingTop() + this.getPaddingBottom(), var6.getLayoutParams().height); - var6.measure(MeasureSpec.makeMeasureSpec(this.getMeasuredWidth(), 1073741824), var1); - } - } - - } - - public void onVisibilityChanged(View var1, int var2) { - super.onVisibilityChanged(var1, var2); - - for (var2 = 0; var2 < this.getTabCount(); ++var2) { - Tab var4 = this.getTabAt(var2); - if (var4 != null) { - TabView var3 = var4.view; - if (var3 != null && var3.mMainTabTouchBackground != null) { - var4.view.mMainTabTouchBackground.setAlpha(0.0F); - } - } - } - - } - - public void populateFromPagerAdapter() { - int currentItem; - removeAllTabs(); - PagerAdapter pagerAdapter2 = this.pagerAdapter; - if (pagerAdapter2 != null) { - int count = pagerAdapter2.getCount(); - for (int i = 0; i < count; i++) { - Tab newTab = newTab(); - newTab.setText(this.pagerAdapter.getPageTitle(i)); - addTab(newTab, false); - } - SeslViewPager viewPager2 = this.viewPager; - if (viewPager2 != null && count > 0 && (currentItem = viewPager2.getCurrentItem()) != getSelectedTabPosition() && currentItem < getTabCount()) { - selectTab(getTabAt(currentItem), true, true); - } - } - } - - public boolean releaseFromTabPool(Tab var1) { - return tabPool.release(var1); - } - - public void removeAllTabs() { - for (int var1 = this.slidingTabIndicator.getChildCount() - 1; var1 >= 0; --var1) { - this.removeTabViewAt(var1); - } - - Iterator var2 = this.tabs.iterator(); - - while (var2.hasNext()) { - Tab var3 = (Tab) var2.next(); - var2.remove(); - var3.reset(); - this.releaseFromTabPool(var3); - } - - this.selectedTab = null; - } - - public void removeOnTabSelectedListener(OnTabSelectedListener var1) { - removeOnTabSelectedListener((BaseOnTabSelectedListener) var1); - } - - @Deprecated - public void removeOnTabSelectedListener(BaseOnTabSelectedListener var1) { - this.selectedListeners.remove(var1); - } - - public final void removeTabViewAt(int var1) { - TabView var2 = (TabView) this.slidingTabIndicator.getChildAt(var1); - this.slidingTabIndicator.removeViewAt(var1); - if (var2 != null) { - var2.reset(); - this.tabViewPool.release(var2); - } - - this.requestLayout(); - } - - public void selectTab(Tab var1) { - this.selectTab(var1, true); - } - - public void selectTab(Tab var1, boolean var2) { - this.selectTab(var1, var2, true); - } - - public final void selectTab(Tab var1, boolean var2, boolean var3) { - SeslViewPager viewPager2; - if (var1 == null || var1.view.isEnabled() || (viewPager2 = this.viewPager) == null) { - Tab tab2 = this.selectedTab; - if (tab2 != var1) { - int position = var1 != null ? var1.getPosition() : -1; - if (var2) { - if ((tab2 == null || tab2.getPosition() == -1) && position != -1) { - setScrollPosition(position, 0.0f, true); - } else { - animateToTab(position); - } - if (position != -1) { - setSelectedTabView(position, var3); - } - } - this.selectedTab = var1; - if (tab2 != null) { - dispatchTabUnselected(tab2); - } - if (var1 != null) { - dispatchTabSelected(var1); - } - } else if (tab2 != null) { - dispatchTabReselected(var1); - animateToTab(var1.getPosition()); - } - } else { - viewPager2.setCurrentItem(getSelectedTabPosition()); - } - } - - public void setElevation(float var1) { - super.setElevation(var1); - MaterialShapeUtils.setElevation(this, var1); - } - - public void setInlineLabel(boolean var1) { - if (this.inlineLabel != var1) { - this.inlineLabel = var1; - - for (int var2 = 0; var2 < this.slidingTabIndicator.getChildCount(); ++var2) { - View var3 = this.slidingTabIndicator.getChildAt(var2); - if (var3 instanceof TabView) { - ((TabView) var3).updateOrientation(); - } - } - - this.applyModeAndGravity(); - } - - } - - public void setInlineLabelResource(int var1) { - this.setInlineLabel(this.getResources().getBoolean(var1)); - } - - @Deprecated - public void setOnTabSelectedListener(BaseOnTabSelectedListener var1) { - BaseOnTabSelectedListener var2 = this.selectedListener; - if (var2 != null) { - this.removeOnTabSelectedListener(var2); - } - - this.selectedListener = var1; - if (var1 != null) { - this.addOnTabSelectedListener(var1); - } - - } - - @Deprecated - public void setOnTabSelectedListener(OnTabSelectedListener var1) { - this.setOnTabSelectedListener((BaseOnTabSelectedListener) var1); - } - - public void setPagerAdapter(PagerAdapter var1, boolean var2) { - PagerAdapter var3 = this.pagerAdapter; - if (var3 != null) { - DataSetObserver var4 = this.pagerAdapterObserver; - if (var4 != null) { - var3.unregisterDataSetObserver(var4); - } - } - - this.pagerAdapter = var1; - if (var2 && var1 != null) { - if (this.pagerAdapterObserver == null) { - this.pagerAdapterObserver = new PagerAdapterObserver(); - } - - var1.registerDataSetObserver(this.pagerAdapterObserver); - } - - this.populateFromPagerAdapter(); - } - - public void setScrollAnimatorListener(Animator.AnimatorListener var1) { - this.ensureScrollAnimator(); - this.scrollAnimator.addListener(var1); - } - - public void setScrollPosition(int var1, float var2, boolean var3) { - this.setScrollPosition(var1, var2, var3, true); - } - - public void setScrollPosition(int var1, float var2, boolean var3, boolean var4) { - if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) - var1 -= 1; - int var5 = Math.round((float) var1 + var2); - if (var5 >= 0 && var5 < this.slidingTabIndicator.getChildCount()) { - if (var4) { - this.slidingTabIndicator.setIndicatorPositionFromTabPosition(var1, var2); - } - - ValueAnimator var6 = this.scrollAnimator; - if (var6 != null && var6.isRunning()) { - this.scrollAnimator.cancel(); - } - - this.scrollTo(this.calculateScrollXForTab(var1, var2), 0); - if (var3) { - this.setSelectedTabView(var5, true); - } - } - - } - - public void setSelectedTabIndicator(int var1) { - if (var1 != 0) { - this.setSelectedTabIndicator(AppCompatResources.getDrawable(this.getContext(), var1)); - } else { - this.setSelectedTabIndicator((Drawable) null); - } - - } - - public void setSelectedTabIndicator(Drawable var1) { - if (this.tabSelectedIndicator != var1) { - this.tabSelectedIndicator = var1; - ViewCompat.postInvalidateOnAnimation(this.slidingTabIndicator); - } - - } - - public void setSelectedTabIndicatorColor(int var1) { - this.mTabSelectedIndicatorColor = var1; - Iterator var2 = this.tabs.iterator(); - - while (true) { - AbsIndicatorView var3; - do { - if (!var2.hasNext()) { - return; - } - - var3 = ((Tab) var2.next()).view.mIndicatorView; - } while (var3 == null); - - label21: - { - if (this.mDepthStyle == 2) { - int var4 = this.mSubTabSelectedIndicatorColor; - if (var4 != -1) { - var3.setSelectedIndicatorColor(var4); - break label21; - } - } - - var3.setSelectedIndicatorColor(var1); - } - - var3.invalidate(); - } - } - - public void setSelectedTabIndicatorGravity(int var1) { - if (this.tabIndicatorGravity != var1) { - this.tabIndicatorGravity = var1; - ViewCompat.postInvalidateOnAnimation(this.slidingTabIndicator); - } - - } - - @Deprecated - public void setSelectedTabIndicatorHeight(int var1) { - this.slidingTabIndicator.setSelectedIndicatorHeight(var1); - } - - public final void setSelectedTabView(int var1, boolean var2) { - int var3 = this.slidingTabIndicator.getChildCount(); - if (var1 < var3) { - int var4 = 0; - - while (true) { - boolean var5 = true; - if (var4 >= var3) { - ((Tab) this.tabs.get(var1)).view.setSelected(true); - - for (var4 = 0; var4 < this.getTabCount(); ++var4) { - TabView var8 = ((Tab) this.tabs.get(var4)).view; - if (var4 == var1) { - if (var8.textView != null) { - this.startTextColorChangeAnimation(var8.textView, this.getSelectedTabTextColor()); - var8.textView.setTypeface(this.mBoldTypeface); - var8.textView.setSelected(true); - } - - if (var8.mIndicatorView != null) { - if (var2) { - if (var8.mIndicatorView.getAlpha() != 1.0F) { - var8.mIndicatorView.setShow(); - } - } else { - ((Tab) this.tabs.get(var4)).view.mIndicatorView.setReleased(); - } - } - } else { - if (var8.mIndicatorView != null) { - var8.mIndicatorView.setHide(); - } - - if (var8.textView != null) { - var8.textView.setTypeface(this.mNormalTypeface); - this.startTextColorChangeAnimation(var8.textView, this.tabTextColors.getDefaultColor()); - var8.textView.setSelected(false); - } - } - } - break; - } - - View var6 = this.slidingTabIndicator.getChildAt(var4); - boolean var7; - if (var4 == var1) { - var7 = true; - } else { - var7 = false; - } - - var6.setSelected(var7); - if (var4 == var1) { - var7 = var5; - } else { - var7 = false; - } - - var6.setActivated(var7); - ++var4; - } - } - - } - - public void setTabIconTintResource(int var1) { - this.setTabIconTint(AppCompatResources.getColorStateList(this.getContext(), var1)); - } - - public void setTabIndicatorFullWidth(boolean var1) { - this.tabIndicatorFullWidth = var1; - ViewCompat.postInvalidateOnAnimation(this.slidingTabIndicator); - } - - public void setTabRippleColorResource(int var1) { - this.setTabRippleColor(AppCompatResources.getColorStateList(this.getContext(), var1)); - } - - @Deprecated - public void setTabsFromPagerAdapter(PagerAdapter var1) { - this.setPagerAdapter(var1, false); - } - - public void setUnboundedRipple(boolean var1) { - if (this.unboundedRipple != var1) { - this.unboundedRipple = var1; - - for (int var2 = 0; var2 < this.slidingTabIndicator.getChildCount(); ++var2) { - View var3 = this.slidingTabIndicator.getChildAt(var2); - if (var3 instanceof TabView) { - ((TabView) var3).updateBackgroundDrawable(this.getContext()); - } - } - } - - } - - public void setUnboundedRippleResource(int var1) { - this.setUnboundedRipple(this.getResources().getBoolean(var1)); - } - - public void setupWithViewPager(SeslViewPager var1) { - this.setupWithViewPager(var1, true); - } - - public void setupWithViewPager(SeslViewPager var1, boolean var2) { - this.setupWithViewPager(var1, var2, false); - } - - public final void setupWithViewPager(SeslViewPager var1, boolean var2, boolean var3) { - SeslViewPager var4 = this.viewPager; - if (var4 != null) { - TabLayoutOnPageChangeListener var5 = this.pageChangeListener; - if (var5 != null) { - var4.removeOnPageChangeListener(var5); - } - - AdapterChangeListener var7 = this.adapterChangeListener; - if (var7 != null) { - this.viewPager.removeOnAdapterChangeListener(var7); - } - } - - BaseOnTabSelectedListener var8 = this.currentVpSelectedListener; - if (var8 != null) { - this.removeOnTabSelectedListener(var8); - this.currentVpSelectedListener = null; - } - - if (var1 != null) { - this.viewPager = var1; - if (this.pageChangeListener == null) { - this.pageChangeListener = new TabLayoutOnPageChangeListener(this); - } - - this.pageChangeListener.reset(); - var1.addOnPageChangeListener(this.pageChangeListener); - this.currentVpSelectedListener = new ViewPagerOnTabSelectedListener(var1); - this.addOnTabSelectedListener(this.currentVpSelectedListener); - PagerAdapter var6 = var1.getAdapter(); - if (var6 != null) { - this.setPagerAdapter(var6, var2); - } - - if (this.adapterChangeListener == null) { - this.adapterChangeListener = new AdapterChangeListener(); - } - - this.adapterChangeListener.setAutoRefresh(var2); - var1.addOnAdapterChangeListener(this.adapterChangeListener); - this.setScrollPosition(var1.getCurrentItem(), 0.0F, true); - } else { - this.viewPager = null; - this.setPagerAdapter((PagerAdapter) null, false); - } - - this.setupViewPagerImplicitly = var3; - } - - public boolean shouldDelayChildPressedState() { - boolean var1; - if (this.getTabScrollRange() > 0) { - var1 = true; - } else { - var1 = false; - } - - return var1; - } - - public final void startTextColorChangeAnimation(TextView var1, int var2) { - if (var1 != null) { - var1.setTextColor(var2); - } - - } - - public final void updateAllTabs() { - int var1 = this.tabs.size(); - - for (int var2 = 0; var2 < var1; ++var2) { - ((Tab) this.tabs.get(var2)).updateView(); - } - - } - - @SuppressLint("WrongConstant") - public final void updateBadgePosition() { - ArrayList var1 = this.tabs; - if (var1 != null && var1.size() != 0) { - for (int var2 = 0; var2 < this.tabs.size(); ++var2) { - Tab var10 = (Tab) this.tabs.get(var2); - TabView var3 = ((Tab) this.tabs.get(var2)).view; - if (var10 != null && var3 != null) { - TextView var4 = var3.textView; - if (var3.getWidth() > 0 && var4 != null && var4.getWidth() > 0) { - TextView var11 = null; - int var5; - int var6; - if (var3.mNBadgeView != null && var3.mNBadgeView.getVisibility() == 0) { - var11 = var3.mNBadgeView; - var5 = ((RelativeLayout.LayoutParams) var11.getLayoutParams()).getMarginStart(); - var6 = this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_n_badge_xoffset); - } else if (var3.mDotBadgeView != null && var3.mDotBadgeView.getVisibility() == 0) { - var11 = var3.mDotBadgeView; - var5 = ((RelativeLayout.LayoutParams) var11.getLayoutParams()).getMarginStart(); - var6 = this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_dot_badge_offset_x); - } else { - var6 = this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_n_badge_xoffset); - var5 = 0; - } - - if (var11 != null && var11.getVisibility() == 0) { - int var7; - int var8; - int var9; - label56: - { - var11.measure(0, 0); - var7 = var11.getMeasuredWidth(); - var8 = var3.getWidth(); - if (var5 != 0) { - var9 = var5; - if (var5 >= var4.getRight()) { - break label56; - } - } - - var9 = var4.getRight() + var6; - } - - if (var9 > var8) { - var5 = var8 - var7; - } else { - var6 = var9 + var7; - var5 = var9; - if (var6 > var8) { - var5 = var9 - (var6 - var8); - } - } - - var5 = Math.max(0, var5); - RelativeLayout.LayoutParams var12 = (RelativeLayout.LayoutParams) var11.getLayoutParams(); - var12.setMarginStart(var5); - var12.width = var7; - var11.setLayoutParams(var12); - } - } - } - } - } - - } - - public final void updateTabViewLayoutParams(LinearLayout.LayoutParams var1) { - if (this.mode == 1 && this.tabGravity == 0) { - var1.width = 0; - var1.weight = 1.0F; - } else { - var1.width = -2; - var1.weight = 0.0F; - } - - } - - public void updateTabViews(boolean var1) { - for (int var2 = 0; var2 < this.slidingTabIndicator.getChildCount(); ++var2) { - View var3 = this.slidingTabIndicator.getChildAt(var2); - var3.setMinimumWidth(this.getTabMinWidth()); - this.updateTabViewLayoutParams((LinearLayout.LayoutParams) var3.getLayoutParams()); - if (var1) { - var3.requestLayout(); - } - } - - this.updateBadgePosition(); - } - - @Deprecated - public interface BaseOnTabSelectedListener { - void onTabReselected(T var1); - - void onTabSelected(T var1); - - void onTabUnselected(T var1); - } - - public interface OnTabSelectedListener extends BaseOnTabSelectedListener { - } - - public static class Tab { - public boolean isCustomButton; - public CharSequence contentDesc; - public View customView; - public Drawable icon; - public int labelVisibilityMode = 1; - public SamsungBaseTabLayout parent; - public int position = -1; - public Object tag; - public CharSequence text; - public TabView view; - - public Tab() { - } - - public View getCustomView() { - return this.customView; - } - - public Tab setCustomView(int var1) { - this.setCustomView(LayoutInflater.from(this.view.getContext()).inflate(var1, this.view, false)); - return this; - } - - public Tab setCustomView(View var1) { - if (this.view.textView != null) { - this.view.removeAllViews(); - } - - this.customView = var1; - this.updateView(); - return this; - } - - public Drawable getIcon() { - return this.icon; - } - - public Tab setIcon(Drawable var1) { - this.icon = var1; - SamsungBaseTabLayout var2 = this.parent; - if (var2.tabGravity == 1 || var2.mode == 2) { - this.parent.updateTabViews(true); - } - - this.updateView(); - if (BadgeUtils.USE_COMPAT_PARENT && this.view.hasBadgeDrawable() && this.view.badgeDrawable.isVisible()) { - this.view.invalidate(); - } - - return this; - } - - public int getPosition() { - return this.position; - } - - public void setPosition(int var1) { - this.position = var1; - } - - public int getTabLabelVisibility() { - return this.labelVisibilityMode; - } - - public CharSequence getText() { - return this.text; - } - - public Tab setText(CharSequence var1) { - if (TextUtils.isEmpty(this.contentDesc) && !TextUtils.isEmpty(var1)) { - this.view.setContentDescription(var1); - } - - this.text = var1; - this.updateView(); - return this; - } - - public boolean isSelected() { - SamsungBaseTabLayout var1 = this.parent; - if (var1 != null) { - boolean var2; - if (var1.getSelectedTabPosition() == this.position) { - var2 = true; - } else { - var2 = false; - } - - return var2; - } else { - throw new IllegalArgumentException("Tab not attached to a TabLayout"); - } - } - - public void reset() { - this.parent = null; - this.view = null; - this.tag = null; - this.icon = null; - this.text = null; - this.contentDesc = null; - this.position = -1; - this.customView = null; - } - - public void select() { - SamsungBaseTabLayout var1 = this.parent; - if (var1 != null) { - var1.selectTab(this); - } else { - throw new IllegalArgumentException("Tab not attached to a TabLayout"); - } - } - - public TextView seslGetTextView() { - TextView var2; - if (this.customView == null) { - TabView var1 = this.view; - if (var1 != null) { - var2 = var1.textView; - return var2; - } - } - - var2 = null; - return var2; - } - - public Tab setContentDescription(CharSequence var1) { - this.contentDesc = var1; - this.updateView(); - return this; - } - - public void updateView() { - TabView var1 = this.view; - if (var1 != null) { - var1.update(); - } - - } - - public boolean getIsCustomButtonView() { - return isCustomButton; - } - - public Tab setIsCustomButtonView(boolean z) { - isCustomButton = z; - return this; - } - } - - public static class TabLayoutOnPageChangeListener implements SeslViewPager.OnPageChangeListener { - public final WeakReference tabLayoutRef; - public int previousScrollState; - public int scrollState; - - public TabLayoutOnPageChangeListener(SamsungBaseTabLayout var1) { - this.tabLayoutRef = new WeakReference(var1); - } - - public void onPageScrollStateChanged(int var1) { - this.previousScrollState = this.scrollState; - this.scrollState = var1; - } - - public void onPageScrolled(int var1, float var2, int var3) { - SamsungBaseTabLayout var4 = (SamsungBaseTabLayout) this.tabLayoutRef.get(); - if (var4 != null) { - var3 = this.scrollState; - boolean var5 = false; - boolean var6; - if (var3 == 2 && this.previousScrollState != 1) { - var6 = false; - } else { - var6 = true; - } - - if (this.scrollState != 2 || this.previousScrollState != 0) { - var5 = true; - } - - var4.setScrollPosition(var1, var2, var6, var5); - } - - } - - public void onPageSelected(int var1) { - SamsungBaseTabLayout var2 = (SamsungBaseTabLayout) this.tabLayoutRef.get(); - if (var2 != null && var2.getSelectedTabPosition() != var1 && var1 < var2.getTabCount()) { - int var3 = this.scrollState; - boolean var4; - if (var3 == 0 || var3 == 2 && this.previousScrollState == 0) { - var4 = true; - } else { - var4 = false; - } - - var2.selectTab(var2.getTabAt(var1), var4); - } - - } - - public void reset() { - this.scrollState = 0; - this.previousScrollState = 0; - } - } - - public static class ViewPagerOnTabSelectedListener implements OnTabSelectedListener { - public final SeslViewPager viewPager; - - public ViewPagerOnTabSelectedListener(SeslViewPager var1) { - this.viewPager = var1; - } - - public void onTabReselected(Tab var1) { - } - - public void onTabSelected(Tab var1) { - this.viewPager.setCurrentItem(var1.getPosition()); - } - - public void onTabUnselected(Tab var1) { - } - } - - private class AdapterChangeListener implements SeslViewPager.OnAdapterChangeListener { - public boolean autoRefresh; - - public AdapterChangeListener() { - } - - public void onAdapterChanged(SeslViewPager var1, PagerAdapter var2, PagerAdapter var3) { - SamsungBaseTabLayout var4 = SamsungBaseTabLayout.this; - if (var4.viewPager == var1) { - var4.setPagerAdapter(var3, this.autoRefresh); - } - - } - - public void setAutoRefresh(boolean var1) { - this.autoRefresh = var1; - } - } - - private class PagerAdapterObserver extends DataSetObserver { - public PagerAdapterObserver() { - } - - public void onChanged() { - SamsungBaseTabLayout.this.populateFromPagerAdapter(); - } - - public void onInvalidated() { - SamsungBaseTabLayout.this.populateFromPagerAdapter(); - } - } - - private class SlidingTabIndicator extends LinearLayout { - public final GradientDrawable defaultSelectionIndicator; - public final Paint selectedIndicatorPaint; - public ValueAnimator indicatorAnimator; - public int indicatorLeft = -1; - public int indicatorRight = -1; - public int layoutDirection = -1; - public int selectedIndicatorHeight; - public int selectedPosition = -1; - public float selectionOffset; - - public SlidingTabIndicator(Context var2) { - super(var2); - this.setWillNotDraw(false); - this.selectedIndicatorPaint = new Paint(); - this.defaultSelectionIndicator = new GradientDrawable(); - } - - public void animateIndicatorToPosition(int var1, int var2) { - } - - public boolean childrenNeedLayout() { - int var1 = this.getChildCount(); - - for (int var2 = 0; var2 < var1; ++var2) { - if (this.getChildAt(var2).getWidth() <= 0) { - return true; - } - } - - return false; - } - - public void draw(Canvas var1) { - super.draw(var1); - } - - public void onLayout(boolean var1, int var2, int var3, int var4, int var5) { - super.onLayout(var1, var2, var3, var4, var5); - ValueAnimator var6 = this.indicatorAnimator; - if (var6 != null && var6.isRunning()) { - this.indicatorAnimator.cancel(); - long var7 = this.indicatorAnimator.getDuration(); - this.animateIndicatorToPosition(this.selectedPosition, Math.round((1.0F - this.indicatorAnimator.getAnimatedFraction()) * (float) var7)); - } else { - this.updateIndicatorPosition(); - } - - } - - @SuppressLint({"RestrictedApi", "WrongConstant"}) - public void onMeasure(int var1, int var2) { - super.onMeasure(var1, var2); - if (MeasureSpec.getMode(var1) == 1073741824) { - SamsungBaseTabLayout var3 = SamsungBaseTabLayout.this; - if (var3.tabGravity == 1 || var3.mode == 2) { - int var4 = this.getChildCount(); - byte var5 = 0; - int var6 = 0; - - int var7; - int var8; - for (var7 = var6; var6 < var4; var7 = var8) { - View var9 = this.getChildAt(var6); - var8 = var7; - if (var9.getVisibility() == 0) { - var8 = Math.max(var7, var9.getMeasuredWidth()); - } - - ++var6; - } - - if (var7 <= 0) { - return; - } - - var6 = (int) ViewUtils.dpToPx(this.getContext(), 16); - boolean var11; - if (var7 * var4 > this.getMeasuredWidth() - var6 * 2) { - var3 = SamsungBaseTabLayout.this; - var3.tabGravity = 0; - var3.updateTabViews(false); - var11 = true; - } else { - boolean var12 = false; - var8 = var5; - - while (true) { - var11 = var12; - if (var8 >= var4) { - break; - } - - LayoutParams var10 = (LayoutParams) this.getChildAt(var8).getLayoutParams(); - if (var10.width != var7 || var10.weight != 0.0F) { - var10.width = var7; - var10.weight = 0.0F; - var12 = true; - } - - ++var8; - } - } - - if (var11) { - super.onMeasure(var1, var2); - } - } - - } - } - - public void onRtlPropertiesChanged(int var1) { - super.onRtlPropertiesChanged(var1); - if (Build.VERSION.SDK_INT < 23 && this.layoutDirection != var1) { - this.requestLayout(); - this.layoutDirection = var1; - } - - } - - public void setIndicatorPositionFromTabPosition(int var1, float var2) { - ValueAnimator var3 = this.indicatorAnimator; - if (var3 != null && var3.isRunning()) { - this.indicatorAnimator.cancel(); - } - - this.selectedPosition = var1; - this.selectionOffset = var2; - this.updateIndicatorPosition(); - } - - public void setSelectedIndicatorColor(int var1) { - if (this.selectedIndicatorPaint.getColor() != var1) { - this.selectedIndicatorPaint.setColor(var1); - ViewCompat.postInvalidateOnAnimation(this); - } - - } - - public void setSelectedIndicatorHeight(int var1) { - if (this.selectedIndicatorHeight != var1) { - this.selectedIndicatorHeight = var1; - ViewCompat.postInvalidateOnAnimation(this); - } - - } - - public final void updateIndicatorPosition() { - } - } - - public final class TabView extends LinearLayout { - public View badgeAnchorView; - public BadgeDrawable badgeDrawable; - public Drawable baseBackgroundDrawable; - public ImageView customIconView; - public TextView customTextView; - public View customView; - public int defaultMaxLines = 2; - public ImageView iconView; - public TextView mDotBadgeView; - public int mIconSize; - public AbsIndicatorView mIndicatorView; - public boolean mIsCallPerformClick; - public View mMainTabTouchBackground; - public TextView mNBadgeView; - public OnKeyListener mTabViewKeyListener = new OnKeyListener() { - public boolean onKey(View var1, int var2, KeyEvent var3) { - return false; - } - }; - public RelativeLayout mTextParentView; - public Tab tab; - public TextView textView; - - public TabView(Context var2) { - super(var2); - this.updateBackgroundDrawable(var2); - this.setGravity(17); - this.setOrientation(SamsungBaseTabLayout.this.inlineLabel ? HORIZONTAL : VERTICAL); - this.setClickable(true); - ViewCompat.setPointerIcon(this, PointerIconCompat.getSystemIcon(this.getContext(), 1002)); - ViewCompat.setAccessibilityDelegate(this, (AccessibilityDelegateCompat) null); - this.setOnKeyListener(this.mTabViewKeyListener); - if (SamsungBaseTabLayout.this.mDepthStyle == 1) { - ViewCompat.setPaddingRelative(this, 0, SamsungBaseTabLayout.this.tabPaddingTop, 0, SamsungBaseTabLayout.this.tabPaddingBottom); - } - - this.mIconSize = this.getResources().getDimensionPixelOffset(R.dimen.sesl_tab_icon_size); - } - - private BadgeDrawable getBadge() { - return this.badgeDrawable; - } - - @SuppressLint("WrongConstant") - private int getContentWidth() { - View[] var1 = new View[3]; - TextView var2 = this.textView; - int var3 = 0; - var1[0] = var2; - var1[1] = this.iconView; - var1[2] = this.customView; - int var4 = var1.length; - int var5 = 0; - int var6 = var5; - - int var10; - for (int var7 = var5; var3 < var4; var7 = var10) { - View var11 = var1[var3]; - int var8 = var5; - int var9 = var6; - var10 = var7; - if (var11 != null) { - var8 = var5; - var9 = var6; - var10 = var7; - if (var11.getVisibility() == 0) { - if (var7 != 0) { - var6 = Math.min(var6, var11.getLeft()); - } else { - var6 = var11.getLeft(); - } - - if (var7 != 0) { - var7 = Math.max(var5, var11.getRight()); - } else { - var7 = var11.getRight(); - } - - var10 = 1; - var9 = var6; - var8 = var7; - } - } - - ++var3; - var5 = var8; - var6 = var9; - } - - return var5 - var6; - } - - private BadgeDrawable getOrCreateBadge() { - if (this.badgeDrawable == null) { - this.badgeDrawable = BadgeDrawable.create(this.getContext()); - } - - this.tryUpdateBadgeAnchor(); - BadgeDrawable var1 = this.badgeDrawable; - if (var1 != null) { - return var1; - } else { - throw new IllegalStateException("Unable to create badge"); - } - } - - public final void addOnLayoutChangeListener(final View var1) { - if (var1 != null) { - var1.addOnLayoutChangeListener(new OnLayoutChangeListener() { - @SuppressLint("WrongConstant") - public void onLayoutChange(View var1x, int var2, int var3, int var4, int var5, int var6, int var7, int var8, int var9) { - if (var1.getVisibility() == 0) { - TabView.this.tryUpdateBadgeDrawableBounds(var1); - } - - } - }); - } - } - - public final float approximateLineWidth(Layout var1, int var2, float var3) { - return var1.getLineWidth(var2) * (var3 / var1.getPaint().getTextSize()); - } - - public final void drawBackground(Canvas var1) { - Drawable var2 = this.baseBackgroundDrawable; - if (var2 != null) { - var2.setBounds(this.getLeft(), this.getTop(), this.getRight(), this.getBottom()); - this.baseBackgroundDrawable.draw(var1); - } - - } - - public void drawableStateChanged() { - super.drawableStateChanged(); - int[] var1 = this.getDrawableState(); - Drawable var2 = this.baseBackgroundDrawable; - if (var2 != null && var2.isStateful()) { - this.baseBackgroundDrawable.setState(var1); - } - - } - - public final FrameLayout getCustomParentForBadge(View var1) { - ImageView var2 = this.iconView; - FrameLayout var3 = null; - if (var1 != var2 && var1 != this.textView) { - return null; - } else { - if (BadgeUtils.USE_COMPAT_PARENT) { - var3 = (FrameLayout) var1.getParent(); - } - - return var3; - } - } - - public Tab getTab() { - return this.tab; - } - - public void setTab(Tab var1) { - if (var1 != this.tab) { - this.tab = var1; - this.update(); - } - - } - - public final boolean hasBadgeDrawable() { - boolean var1; - if (this.badgeDrawable != null) { - var1 = true; - } else { - var1 = false; - } - - return var1; - } - - public void onConfigurationChanged(Configuration var1) { - super.onConfigurationChanged(var1); - this.mIconSize = this.getResources().getDimensionPixelOffset(R.dimen.sesl_tab_icon_size); - } - - public void onInitializeAccessibilityEvent(AccessibilityEvent var1) { - super.onInitializeAccessibilityEvent(var1); - var1.setClassName(androidx.appcompat.app.ActionBar.Tab.class.getName()); - } - - @SuppressLint("WrongConstant") - @TargetApi(14) - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo var1) { - super.onInitializeAccessibilityNodeInfo(var1); - var1.setClassName(androidx.appcompat.app.ActionBar.Tab.class.getName()); - BadgeDrawable var2 = this.badgeDrawable; - StringBuilder var4; - if (var2 != null && var2.isVisible()) { - CharSequence var3 = this.getContentDescription(); - var4 = new StringBuilder(); - var4.append(var3); - var4.append(", "); - var4.append(this.badgeDrawable.getContentDescription()); - var1.setContentDescription(var4.toString()); - } - - TextView var5 = this.mNBadgeView; - if (var5 != null && var5.getVisibility() == 0 && this.mNBadgeView.getContentDescription() != null) { - var4 = new StringBuilder(); - var4.append(this.getContentDescription()); - var4.append(", "); - var4.append(this.mNBadgeView.getContentDescription()); - var1.setContentDescription(var4.toString()); - } - - } - - @SuppressLint("RestrictedApi") - public void onLayout(boolean var1, int var2, int var3, int var4, int var5) { - super.onLayout(var1, var2, var3, var4, var5); - View var6 = this.mMainTabTouchBackground; - if (var6 != null) { - var6.setLeft(0); - View var7 = this.mMainTabTouchBackground; - RelativeLayout var8 = this.mTextParentView; - if (var8 != null) { - var2 = var8.getWidth(); - } else { - var2 = var4 - var2; - } - - var7.setRight(var2); - if (this.mMainTabTouchBackground.getAnimation() != null && this.mMainTabTouchBackground.getAnimation().hasEnded()) { - this.mMainTabTouchBackground.setAlpha(0.0F); - } - } - - if (this.iconView != null && this.tab.icon != null) { - TextView var9 = this.textView; - if (var9 != null && this.mIndicatorView != null && this.mTextParentView != null) { - var3 = this.mIconSize + var9.getMeasuredWidth(); - var2 = var3; - if (SamsungBaseTabLayout.this.mIconTextGap != -1) { - var2 = var3 + SamsungBaseTabLayout.this.mIconTextGap; - } - - var2 = Math.abs((this.getWidth() - var2) / 2); - if (ViewUtils.isLayoutRtl(this)) { - var2 = -var2; - if (this.iconView.getRight() == this.mTextParentView.getRight()) { - this.textView.offsetLeftAndRight(var2); - this.iconView.offsetLeftAndRight(var2); - this.mIndicatorView.offsetLeftAndRight(var2); - } - } else if (this.iconView.getLeft() == this.mTextParentView.getLeft()) { - this.textView.offsetLeftAndRight(var2); - this.iconView.offsetLeftAndRight(var2); - this.mIndicatorView.offsetLeftAndRight(var2); - } - } - } - - } - - @SuppressLint("WrongConstant") - public void onMeasure(int var1, int var2) { - int var3 = MeasureSpec.getSize(var1); - int var4 = MeasureSpec.getMode(var1); - int var5 = SamsungBaseTabLayout.this.getTabMaxWidth(); - int var6; - if (SamsungBaseTabLayout.this.mRequestedTabWidth != -1) { - var6 = MeasureSpec.makeMeasureSpec(SamsungBaseTabLayout.this.mRequestedTabWidth, 1073741824); - } else { - var6 = var1; - if (var5 > 0) { - label80: - { - if (var4 != 0) { - var6 = var1; - if (var3 <= var5) { - break label80; - } - } - - var6 = MeasureSpec.makeMeasureSpec(SamsungBaseTabLayout.this.tabMaxWidth, -2147483648); - } - } - } - - super.onMeasure(var6, var2); - TextView var7 = this.textView; - if (var7 != null && this.customView == null) { - SamsungBaseTabLayout var8 = SamsungBaseTabLayout.this; - float var9 = var8.tabTextSize; - var8.checkMaxFontScale(var7, (int) var9); - var4 = this.defaultMaxLines; - ImageView var15 = this.iconView; - boolean var13 = true; - float var10; - if (var15 != null && var15.getVisibility() == 0) { - var1 = 1; - var10 = var9; - } else { - var7 = this.textView; - var1 = var4; - var10 = var9; - if (var7 != null) { - var1 = var4; - var10 = var9; - if (var7.getLineCount() > 1) { - var10 = SamsungBaseTabLayout.this.tabTextMultiLineSize; - var1 = var4; - } - } - } - - var9 = this.textView.getTextSize(); - int var11 = this.textView.getLineCount(); - var4 = TextViewCompat.getMaxLines(this.textView); - float var19; - int var12 = (var19 = var10 - var9) == 0.0F ? 0 : (var19 < 0.0F ? -1 : 1); - if (var12 != 0 || var4 >= 0 && var1 != var4) { - boolean var14 = var13; - if (SamsungBaseTabLayout.this.mode == 1) { - var14 = var13; - if (var12 > 0) { - var14 = var13; - if (var11 == 1) { - label89: - { - Layout var16 = this.textView.getLayout(); - if (var16 != null) { - var14 = var13; - if (this.approximateLineWidth(var16, 0, var10) <= (float) (this.getMeasuredWidth() - this.getPaddingLeft() - this.getPaddingRight())) { - break label89; - } - } - - var14 = false; - } - } - } - } - - if (var14) { - this.textView.setTextSize(0, var10); - SamsungBaseTabLayout.this.checkMaxFontScale(this.textView, (int) var10); - this.textView.setMaxLines(var1); - super.onMeasure(var6, var2); - } - } - } - - if (this.customTextView == null && this.mTextParentView != null && this.textView != null && this.tab != null) { - SamsungBaseTabLayout var17 = SamsungBaseTabLayout.this; - if (var17.mode == 0 && var17.mDepthStyle == 2) { - if (var5 > 0) { - this.textView.measure(var5, 0); - } else { - this.textView.measure(0, 0); - } - - var1 = this.textView.getMeasuredWidth(); - ViewGroup.LayoutParams var18 = this.mTextParentView.getLayoutParams(); - var18.width = var1 + this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_side_space) * 2; - this.mTextParentView.setLayoutParams(var18); - super.onMeasure(MeasureSpec.makeMeasureSpec(var18.width, -2147483648), var2); - } - } - - } - - public boolean onTouchEvent(MotionEvent var1) { - if (this.isEnabled()) { - return this.tab.getCustomView() != null ? super.onTouchEvent(var1) : this.startTabTouchAnimation(var1, (KeyEvent) null); - } else { - return super.onTouchEvent(var1); - } - } - - public boolean performClick() { - if (this.mIsCallPerformClick) { - this.mIsCallPerformClick = false; - return true; - } else { - boolean var1 = super.performClick(); - if (this.tab != null) { - if (!var1) { - this.playSoundEffect(0); - } - - this.tab.select(); - return true; - } else { - return var1; - } - } - } - - public void reset() { - this.setTab((Tab) null); - this.setSelected(false); - } - - public void setEnabled(boolean var1) { - super.setEnabled(var1); - View var2 = this.mMainTabTouchBackground; - if (var2 != null) { - byte var3; - if (var1) { - var3 = 0; - } else { - var3 = 8; - } - - var2.setVisibility(var3); - } - - } - - public void setSelected(boolean var1) { - if (this.isEnabled()) { - boolean var2; - if (this.isSelected() != var1) { - var2 = true; - } else { - var2 = false; - } - - super.setSelected(var1); - - TextView var3 = this.textView; - if (var3 != null) { - var3.setSelected(var1); - } - - ImageView var4 = this.iconView; - if (var4 != null) { - var4.setSelected(var1); - } - - View var5 = this.customView; - if (var5 != null) { - var5.setSelected(var1); - } - - AbsIndicatorView var6 = this.mIndicatorView; - if (var6 != null) { - var6.setSelected(var1); - } - - } - } - - public final void showMainTabTouchBackground(int var1) { - if (this.mMainTabTouchBackground != null && SamsungBaseTabLayout.this.mDepthStyle == 1 && SamsungBaseTabLayout.this.tabBackgroundResId == 0) { - this.mMainTabTouchBackground.setAlpha(1.0F); - AnimationSet var2 = new AnimationSet(true); - var2.setFillAfter(true); - AlphaAnimation var3; - if (var1 != 0) { - if ((var1 == 1 || var1 == 3) && this.mMainTabTouchBackground.getAnimation() != null) { - if (this.mMainTabTouchBackground.getAnimation().hasEnded()) { - var3 = new AlphaAnimation(1.0F, 0.0F); - var3.setDuration(400L); - var3.setFillAfter(true); - var2.addAnimation(var3); - this.mMainTabTouchBackground.startAnimation(var2); - } else { - this.mMainTabTouchBackground.getAnimation().setAnimationListener(new Animation.AnimationListener() { - public void onAnimationEnd(Animation var1) { - AnimationSet var2 = new AnimationSet(true); - var2.setFillAfter(true); - AlphaAnimation var3 = new AlphaAnimation(1.0F, 0.0F); - var3.setDuration(400L); - var3.setFillAfter(true); - var2.addAnimation(var3); - TabView.this.mMainTabTouchBackground.startAnimation(var3); - } - - public void onAnimationRepeat(Animation var1) { - } - - public void onAnimationStart(Animation var1) { - } - }); - } - } - } else { - var3 = new AlphaAnimation(0.0F, 1.0F); - var3.setDuration(100L); - var3.setFillAfter(true); - var2.addAnimation(var3); - ScaleAnimation var4 = new ScaleAnimation(0.95F, 1.0F, 0.95F, 1.0F, 1, 0.5F, 1, 0.5F); - var4.setDuration(350L); - var4.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); - var4.setFillAfter(true); - var2.addAnimation(var4); - this.mMainTabTouchBackground.startAnimation(var2); - } - } - - } - - public final boolean startTabTouchAnimation(MotionEvent var1, KeyEvent var2) { - if (var1 != null && this.tab.getCustomView() == null && this.textView != null && (var1 != null || var2 != null) && (var1 == null || var2 == null)) { - int var3 = var1.getAction() & 255; - TextView var4; - SamsungBaseTabLayout var5; - AbsIndicatorView var6; - Tab var7; - SamsungBaseTabLayout var8; - if (var3 != 0) { - if (var3 != 1) { - if (var3 == 3) { - this.textView.setTypeface(SamsungBaseTabLayout.this.mNormalTypeface); - var5 = SamsungBaseTabLayout.this; - var5.startTextColorChangeAnimation(this.textView, var5.tabTextColors.getDefaultColor()); - var6 = this.mIndicatorView; - if (var6 != null && !var6.isSelected()) { - this.mIndicatorView.setHide(); - } - - var5 = SamsungBaseTabLayout.this; - var7 = var5.getTabAt(var5.getSelectedTabPosition()); - if (var7 != null) { - var4 = var7.view.textView; - if (var4 != null) { - var4.setTypeface(SamsungBaseTabLayout.this.mBoldTypeface); - var8 = SamsungBaseTabLayout.this; - var8.startTextColorChangeAnimation(var7.view.textView, var8.getSelectedTabTextColor()); - } - - var6 = var7.view.mIndicatorView; - if (var6 != null) { - var6.setShow(); - } - } - - if (SamsungBaseTabLayout.this.mDepthStyle == 1) { - this.showMainTabTouchBackground(3); - } else { - var6 = this.mIndicatorView; - if (var6 != null && var6.isSelected()) { - this.mIndicatorView.setReleased(); - } - } - } - } else { - this.showMainTabTouchBackground(1); - var6 = this.mIndicatorView; - if (var6 != null) { - var6.setReleased(); - this.mIndicatorView.onTouchEvent(var1); - } - - this.performClick(); - this.mIsCallPerformClick = true; - } - } else { - label73: - { - this.mIsCallPerformClick = false; - if (this.tab.position != SamsungBaseTabLayout.this.getSelectedTabPosition()) { - TextView var9 = this.textView; - if (var9 != null) { - var9.setTypeface(SamsungBaseTabLayout.this.mBoldTypeface); - var5 = SamsungBaseTabLayout.this; - var5.startTextColorChangeAnimation(this.textView, var5.getSelectedTabTextColor()); - var6 = this.mIndicatorView; - if (var6 != null) { - var6.setPressed(); - } - - var5 = SamsungBaseTabLayout.this; - var7 = var5.getTabAt(var5.getSelectedTabPosition()); - if (var7 != null) { - var4 = var7.view.textView; - if (var4 != null) { - var4.setTypeface(SamsungBaseTabLayout.this.mNormalTypeface); - var8 = SamsungBaseTabLayout.this; - var8.startTextColorChangeAnimation(var7.view.textView, var8.tabTextColors.getDefaultColor()); - } - - var6 = var7.view.mIndicatorView; - if (var6 != null) { - var6.setHide(); - } - } - break label73; - } - } - - if (this.tab.position == SamsungBaseTabLayout.this.getSelectedTabPosition()) { - var6 = this.mIndicatorView; - if (var6 != null) { - var6.setPressed(); - } - } - } - - this.showMainTabTouchBackground(0); - } - - return super.onTouchEvent(var1); - } else { - return false; - } - } - - @SuppressLint({"RestrictedApi", "UnsafeExperimentalUsageError"}) - public final void tryAttachBadgeToAnchor(View var1) { - if (this.hasBadgeDrawable()) { - if (var1 != null) { - this.setClipChildren(false); - this.setClipToPadding(false); - BadgeUtils.attachBadgeDrawable(this.badgeDrawable, var1, this.getCustomParentForBadge(var1)); - this.badgeAnchorView = var1; - } - - } - } - - @SuppressLint({"RestrictedApi", "UnsafeExperimentalUsageError"}) - public final void tryRemoveBadgeFromAnchor() { - if (this.hasBadgeDrawable()) { - if (this.badgeAnchorView != null) { - this.setClipChildren(true); - this.setClipToPadding(true); - BadgeDrawable var1 = this.badgeDrawable; - View var2 = this.badgeAnchorView; - var2.getOverlay().remove(var1); - this.badgeAnchorView = null; - } - - } - } - - public final void tryUpdateBadgeAnchor() { - if (this.hasBadgeDrawable()) { - if (this.customView != null) { - this.tryRemoveBadgeFromAnchor(); - } else { - Tab var1; - View var3; - if (this.iconView != null) { - var1 = this.tab; - if (var1 != null && var1.getIcon() != null) { - var3 = this.badgeAnchorView; - ImageView var4 = this.iconView; - if (var3 != var4) { - this.tryRemoveBadgeFromAnchor(); - this.tryAttachBadgeToAnchor(this.iconView); - } else { - this.tryUpdateBadgeDrawableBounds(var4); - } - - return; - } - } - - if (this.textView != null) { - var1 = this.tab; - if (var1 != null && var1.getTabLabelVisibility() == 1) { - var3 = this.badgeAnchorView; - TextView var2 = this.textView; - if (var3 != var2) { - this.tryRemoveBadgeFromAnchor(); - this.tryAttachBadgeToAnchor(this.textView); - } else { - this.tryUpdateBadgeDrawableBounds(var2); - } - - return; - } - } - - this.tryRemoveBadgeFromAnchor(); - } - - } - } - - @SuppressLint({"RestrictedApi", "UnsafeExperimentalUsageError"}) - public final void tryUpdateBadgeDrawableBounds(View var1) { - if (this.hasBadgeDrawable() && var1 == this.badgeAnchorView) { - BadgeUtils.setBadgeDrawableBounds(this.badgeDrawable, var1, this.getCustomParentForBadge(var1)); - } - - } - - @SuppressLint("WrongConstant") - public final void update() { - RelativeLayout relativeLayout; - int i; - RelativeLayout relativeLayout2; - Tab tab2 = this.tab; - Drawable drawable = null; - View customView2 = tab2 != null ? tab2.getCustomView() : null; - if (customView2 != null) { - ViewParent parent = customView2.getParent(); - if (parent != this) { - if (parent != null) { - ((ViewGroup) parent).removeView(customView2); - } - addView(customView2); - } - this.customView = customView2; - TextView textView2 = this.textView; - if (textView2 != null) { - textView2.setVisibility(8); - } - ImageView imageView = this.iconView; - if (imageView != null) { - imageView.setVisibility(8); - this.iconView.setImageDrawable((Drawable) null); - } - this.customTextView = (TextView) customView2.findViewById(android.R.id.text1); - TextView textView3 = this.customTextView; - if (textView3 != null) { - this.defaultMaxLines = TextViewCompat.getMaxLines(textView3); - } - this.customIconView = (ImageView) customView2.findViewById(android.R.id.icon); - } else { - View view = this.customView; - if (view != null) { - removeView(view); - this.customView = null; - } - this.customTextView = null; - this.customIconView = null; - } - boolean z = false; - if (this.customView == null) { - if (this.textView == null) { - Context context = getContext(); - int i2 = -2; - if (SamsungBaseTabLayout.this.mDepthStyle == 2) { - relativeLayout2 = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.sesl_tabs_sub_tab_layout, this, false); - if (SamsungBaseTabLayout.this.mode != 0) { - i2 = -1; - } - i = SamsungBaseTabLayout.this.mSubTabIndicatorHeight; - this.mIndicatorView = (AbsIndicatorView) relativeLayout2.findViewById(R.id.indicator); - if (!(this.mIndicatorView == null || SamsungBaseTabLayout.this.mSubTabSelectedIndicatorColor == -1)) { - this.mIndicatorView.setSelectedIndicatorColor(SamsungBaseTabLayout.this.mSubTabSelectedIndicatorColor); - } - } else { - RelativeLayout relativeLayout3 = (RelativeLayout) LayoutInflater.from(context).inflate(R.layout.sesl_tabs_main_tab_layout, this, false); - if (this.tab.icon == null) { - i2 = -1; - } - this.mIndicatorView = (AbsIndicatorView) relativeLayout3.findViewById(R.id.indicator); - AbsIndicatorView AbsIndicatorView = this.mIndicatorView; - if (AbsIndicatorView != null) { - if (mIsOneUI4) { - ViewGroup.LayoutParams lp = mIndicatorView.getLayoutParams(); - lp.height = getContext().getResources().getDimensionPixelSize(R.dimen.sesl4_tab_line_height); - mIndicatorView.setLayoutParams(lp); - } - AbsIndicatorView.setSelectedIndicatorColor(SamsungBaseTabLayout.this.mTabSelectedIndicatorColor); - } - this.mMainTabTouchBackground = relativeLayout3.findViewById(R.id.main_tab_touch_background); - if (this.mMainTabTouchBackground != null && this.tab.icon == null) { - ViewCompat.setBackground(this.mMainTabTouchBackground, ContextCompat.getDrawable(context, R.drawable.sesl_tablayout_maintab_touch_background)); - this.mMainTabTouchBackground.setAlpha(0.0f); - } - relativeLayout2 = relativeLayout3; - i = -1; - } - relativeLayout2.getLayoutParams().width = i2; - addView(relativeLayout2, i2, i); - this.textView = (TextView) relativeLayout2.findViewById(R.id.title); - this.mTextParentView = relativeLayout2; - this.defaultMaxLines = TextViewCompat.getMaxLines(this.textView); - } - if (this.iconView == null && (relativeLayout = this.mTextParentView) != null) { - this.iconView = (ImageView) relativeLayout.findViewById(R.id.icon); - } - if (!(tab2 == null || tab2.getIcon() == null)) { - drawable = DrawableCompat.wrap(tab2.getIcon()).mutate(); - } - if (drawable != null) { - DrawableCompat.setTintList(drawable, SamsungBaseTabLayout.this.tabIconTint); - PorterDuff.Mode mode = SamsungBaseTabLayout.this.tabIconTintMode; - if (mode != null) { - DrawableCompat.setTintMode(drawable, mode); - } - } - TextViewCompat.setTextAppearance(this.textView, SamsungBaseTabLayout.this.tabTextAppearance); - SamsungBaseTabLayout tabLayout = SamsungBaseTabLayout.this; - tabLayout.checkMaxFontScale(this.textView, (int) tabLayout.tabTextSize); - ColorStateList colorStateList = SamsungBaseTabLayout.this.tabTextColors; - if (colorStateList != null) { - this.textView.setTextColor(colorStateList); - } - updateTextAndIcon(this.textView, this.iconView); - tryUpdateBadgeAnchor(); - addOnLayoutChangeListener(this.iconView); - addOnLayoutChangeListener(this.textView); - } else if (!(this.customTextView == null && this.customIconView == null)) { - updateTextAndIcon(this.customTextView, this.customIconView); - } - if (tab2 != null && !TextUtils.isEmpty(tab2.contentDesc)) { - setContentDescription(tab2.contentDesc); - } - if (tab2 != null && tab2.isSelected()) { - z = true; - } - setSelected(z); - } - - public final void updateBackgroundDrawable(Context var1) { - SamsungBaseTabLayout var2 = SamsungBaseTabLayout.this; - if (var2.tabBackgroundResId != 0 && var2.mDepthStyle != 2) { - this.baseBackgroundDrawable = AppCompatResources.getDrawable(var1, SamsungBaseTabLayout.this.tabBackgroundResId); - Drawable var3 = this.baseBackgroundDrawable; - if (var3 != null && var3.isStateful()) { - this.baseBackgroundDrawable.setState(this.getDrawableState()); - } - - ViewCompat.setBackground(this, this.baseBackgroundDrawable); - } else { - this.baseBackgroundDrawable = null; - } - - } - - public final void updateOrientation() { - this.setOrientation(SamsungBaseTabLayout.this.inlineLabel ? HORIZONTAL : VERTICAL); - if (this.customTextView == null && this.customIconView == null) { - this.updateTextAndIcon(this.textView, this.iconView); - } else { - this.updateTextAndIcon(this.customTextView, this.customIconView); - } - - } - - @SuppressLint({"RestrictedApi", "WrongConstant"}) - public final void updateTextAndIcon(TextView var1, ImageView var2) { - Tab var3 = this.tab; - Drawable var10; - if (var3 != null && var3.getIcon() != null) { - var10 = DrawableCompat.wrap(this.tab.getIcon()).mutate(); - } else { - var10 = null; - } - - Tab var4 = this.tab; - CharSequence var11; - if (var4 != null) { - var11 = var4.getText(); - } else { - var11 = null; - } - - if (var2 != null) { - if (var10 != null) { - var2.setImageDrawable(var10); - var2.setVisibility(0); - this.setVisibility(0); - } else { - var2.setVisibility(8); - var2.setImageDrawable((Drawable) null); - } - } - - boolean var5 = !TextUtils.isEmpty(var11); - if (var1 != null) { - if (var5) { - var1.setText(var11); - if (this.tab.labelVisibilityMode == 1) { - var1.setVisibility(0); - } else { - var1.setVisibility(8); - } - - this.setVisibility(0); - } else { - var1.setVisibility(8); - var1.setText((CharSequence) null); - } - } - - if (var2 != null) { - MarginLayoutParams var12 = (MarginLayoutParams) var2.getLayoutParams(); - int var6; - if (var5 && var2.getVisibility() == 0) { - if (SamsungBaseTabLayout.this.mIconTextGap != -1) { - var6 = SamsungBaseTabLayout.this.mIconTextGap; - } else { - var6 = (int) ViewUtils.dpToPx(this.getContext(), 8); - } - } else { - var6 = 0; - } - - if (var6 != MarginLayoutParamsCompat.getMarginEnd(var12)) { - MarginLayoutParamsCompat.setMarginEnd(var12, var6); - var12.bottomMargin = 0; - var2.setLayoutParams(var12); - var2.requestLayout(); - if (var1 != null) { - RelativeLayout.LayoutParams var9 = (RelativeLayout.LayoutParams) var1.getLayoutParams(); - var9.addRule(13, 0); - var9.addRule(15, 1); - var9.addRule(17, R.id.icon); - var1.setLayoutParams(var9); - } - } - } - - Tab var7 = this.tab; - CharSequence var8; - if (var7 != null) { - var8 = var7.contentDesc; - } else { - var8 = null; - } - - if (var5) { - var8 = null; - } - - TooltipCompat.setTooltipText(this, var8); - } - } -} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungTabLayout.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungTabLayout.java new file mode 100644 index 00000000..8cd0fcb2 --- /dev/null +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SamsungTabLayout.java @@ -0,0 +1,3098 @@ +package de.dlyt.yanndroid.oneui.sesl.tabs; + +import static androidx.viewpager.widget.SeslViewPager.SCROLL_STATE_DRAGGING; +import static androidx.viewpager.widget.SeslViewPager.SCROLL_STATE_IDLE; +import static androidx.viewpager.widget.SeslViewPager.SCROLL_STATE_SETTLING; + +import android.animation.ValueAnimator; +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.database.DataSetObserver; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.os.Build; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.text.Layout; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.SoundEffectConstants; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewParent; +import android.view.accessibility.AccessibilityEvent; +import android.view.accessibility.AccessibilityNodeInfo; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationSet; +import android.view.animation.ScaleAnimation; +import android.widget.FrameLayout; +import android.widget.HorizontalScrollView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.BoolRes; +import androidx.annotation.ColorInt; +import androidx.annotation.ColorRes; +import androidx.annotation.Dimension; +import androidx.annotation.DrawableRes; +import androidx.annotation.IntDef; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.annotation.StringRes; +import androidx.appcompat.animation.SeslAnimationUtils; +import androidx.core.content.ContextCompat; +import androidx.core.content.res.ResourcesCompat; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.core.util.Pools; +import androidx.core.view.GravityCompat; +import androidx.core.view.MarginLayoutParamsCompat; +import androidx.core.view.ViewCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat; +import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat; +import androidx.core.widget.TextViewCompat; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.viewpager.widget.PagerAdapter; +import androidx.viewpager.widget.SeslViewPager; + +import com.google.android.material.animation.AnimationUtils; +import com.google.android.material.badge.BadgeDrawable; +import com.google.android.material.badge.BadgeUtils; +import com.google.android.material.internal.ThemeEnforcement; +import com.google.android.material.internal.ViewUtils; +import com.google.android.material.resources.MaterialResources; +import com.google.android.material.shape.MaterialShapeDrawable; +import com.google.android.material.shape.MaterialShapeUtils; +import com.google.android.material.theme.overlay.MaterialThemeOverlay; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Iterator; + +import de.dlyt.yanndroid.oneui.R; +import de.dlyt.yanndroid.oneui.view.Tooltip; + +@SeslViewPager.DecorView +public class SamsungTabLayout extends HorizontalScrollView { + private boolean mIsOneUI4; + private static final int ANIMATION_DURATION = 300; + private static final int ANIM_HIDE_DURATION = 400; + private static final float ANIM_RIPPLE_MINOR_SCALE = 0.95f; + private static final int ANIM_SHOW_DURATION = 350; + private static final int BADGE_N_TEXT_SIZE = 11; + private static final int BADGE_TYPE_DOT = 2; + private static final int BADGE_TYPE_N = 1; + private static final int BADGE_TYPE_UNKNOWN = -1; + @Dimension(unit = Dimension.DP) + static final int DEFAULT_GAP_TEXT_ICON = 8; + @Dimension(unit = Dimension.DP) + private static final int DEFAULT_HEIGHT = 48; + @Dimension(unit = Dimension.DP) + private static final int DEFAULT_HEIGHT_WITH_TEXT_ICON = 72; + private static final int DEPTH_TYPE_MAIN = 1; + private static final int DEPTH_TYPE_SUB = 2; + @Dimension(unit = Dimension.DP) + static final int FIXED_WRAP_GUTTER_MIN = 16; + public static final int GRAVITY_FILL = 0; + public static final int GRAVITY_CENTER = 1; + public static final int GRAVITY_START = 2; + @IntDef(flag = true, value = {GRAVITY_FILL, GRAVITY_CENTER, GRAVITY_START}) + @Retention(RetentionPolicy.SOURCE) + public @interface TabGravity {} + public static final int INDICATOR_ANIMATION_MODE_LINEAR = 0; + public static final int INDICATOR_ANIMATION_MODE_ELASTIC = 1; + @IntDef(value = {INDICATOR_ANIMATION_MODE_LINEAR, INDICATOR_ANIMATION_MODE_ELASTIC}) + @Retention(RetentionPolicy.SOURCE) + public @interface TabIndicatorAnimationMode {} + public static final int INDICATOR_GRAVITY_BOTTOM = 0; + public static final int INDICATOR_GRAVITY_CENTER = 1; + public static final int INDICATOR_GRAVITY_TOP = 2; + public static final int INDICATOR_GRAVITY_STRETCH = 3; + @IntDef(value = {INDICATOR_GRAVITY_BOTTOM, INDICATOR_GRAVITY_CENTER, INDICATOR_GRAVITY_TOP, INDICATOR_GRAVITY_STRETCH}) + @Retention(RetentionPolicy.SOURCE) + public @interface TabIndicatorGravity {} + private static final int INVALID_WIDTH = -1; + private static final String LOG_TAG = "TabLayout"; + public static final int MODE_SCROLLABLE = 0; + public static final int MODE_FIXED = 1; + public static final int MODE_AUTO = 2; + public static final int SESL_MODE_FIXED_AUTO = 11; + public static final int SESL_MODE_WEIGHT_AUTO = 12; + @IntDef(value = {MODE_SCROLLABLE, MODE_FIXED, MODE_AUTO, SESL_MODE_FIXED_AUTO, SESL_MODE_WEIGHT_AUTO}) + @Retention(RetentionPolicy.SOURCE) + public @interface Mode {} + @Dimension(unit = Dimension.DP) + private static final int SESL_DEFAULT_HEIGHT = 60; + @Dimension(unit = Dimension.DP) + private static final int SESL_SUB_DEPTH_DEFAULT_HEIGHT = 56; + public static final int TAB_LABEL_VISIBILITY_UNLABELED = 0; + public static final int TAB_LABEL_VISIBILITY_LABELED = 1; + @IntDef(value = {TAB_LABEL_VISIBILITY_UNLABELED, TAB_LABEL_VISIBILITY_LABELED}) + public @interface LabelVisibility {} + @Dimension(unit = Dimension.DP) + private static final int TAB_MIN_WIDTH_MARGIN = 56; + private AdapterChangeListener adapterChangeListener; + private int contentInsetStart; + @Nullable private BaseOnTabSelectedListener currentVpSelectedListener; + boolean inlineLabel; + private int mBadgeColor = Color.WHITE; + private int mBadgeTextColor = Color.WHITE; + private Typeface mBoldTypeface; + protected int mDepthStyle = DEPTH_TYPE_MAIN; + private int mFirstTabGravity; + private int mIconTextGap = -1; + private boolean mIsChangedGravityByLocal; + private boolean mIsOverScreen = false; + private boolean mIsScaledTextSizeType = false; + private Typeface mNormalTypeface; + private int mOverScreenMaxWidth = -1; + private int mRequestedTabWidth = -1; + private int mSubTabIndicator2ndHeight = 1; + private int mSubTabIndicatorHeight = 1; + private int mSubTabSelectedIndicatorColor = Color.WHITE; + int mSubTabSubTextAppearance; + ColorStateList mSubTabSubTextColors; + int mSubTabTextSize; + private int mTabMinSideSpace; + private int mTabSelectedIndicatorColor; + @Mode int mode; + private TabLayoutOnPageChangeListener pageChangeListener; + @Nullable private PagerAdapter pagerAdapter; + private DataSetObserver pagerAdapterObserver; + private final int requestedTabMaxWidth; + private final int requestedTabMinWidth; + private ValueAnimator scrollAnimator; + private final int scrollableTabMinWidth; + private BaseOnTabSelectedListener selectedListener; + @Nullable private final ArrayList selectedListeners = new ArrayList<>(); + @Nullable private Tab selectedTab; + private boolean setupViewPagerImplicitly; + @NonNull final SlidingTabIndicator slidingTabIndicator; + final int tabBackgroundResId; + @TabGravity int tabGravity; + ColorStateList tabIconTint; + PorterDuff.Mode tabIconTintMode; + int tabIndicatorAnimationDuration; + @TabIndicatorAnimationMode int tabIndicatorAnimationMode; + boolean tabIndicatorFullWidth; + @TabIndicatorGravity int tabIndicatorGravity; + private TabIndicatorInterpolator tabIndicatorInterpolator; + int tabMaxWidth = Integer.MAX_VALUE; + int tabPaddingBottom; + int tabPaddingEnd; + int tabPaddingStart; + int tabPaddingTop; + ColorStateList tabRippleColorStateList; + @NonNull Drawable tabSelectedIndicator = new GradientDrawable(); + private int tabSelectedIndicatorColor = Color.TRANSPARENT; + int tabTextAppearance; + ColorStateList tabTextColors; + float tabTextMultiLineSize; + float tabTextSize; + private final Pools.Pool tabViewPool = new Pools.SimplePool(12); + private final ArrayList tabs = new ArrayList<>(); + boolean unboundedRipple; + @Nullable SeslViewPager viewPager; + private static final int DEF_STYLE_RES = R.style.TabLayoutStyle; + private static final Pools.Pool tabPool = new Pools.SynchronizedPool(16); + + public interface OnTabSelectedListener extends BaseOnTabSelectedListener {} + + @Deprecated + public interface BaseOnTabSelectedListener { + public void onTabSelected(T tab); + + public void onTabUnselected(T tab); + + public void onTabReselected(T tab); + } + + public SamsungTabLayout(@NonNull Context context) { + this(context, null); + } + + public SamsungTabLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, R.attr.tabStyle); + } + + @SuppressLint("RestrictedApi") + public SamsungTabLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { + super(MaterialThemeOverlay.wrap(context, attrs, defStyleAttr, DEF_STYLE_RES), attrs, defStyleAttr); + context = getContext(); + mIsOneUI4 = context.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); + + setHorizontalScrollBarEnabled(false); + + slidingTabIndicator = new SlidingTabIndicator(context); + super.addView(slidingTabIndicator, 0, new HorizontalScrollView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT)); + + TypedArray a = ThemeEnforcement.obtainStyledAttributes(context, attrs, R.styleable.SamsungTabLayout, defStyleAttr, DEF_STYLE_RES, R.styleable.SamsungTabLayout_tabTextAppearance); + + if (getBackground() instanceof ColorDrawable) { + ColorDrawable background = (ColorDrawable) getBackground(); + MaterialShapeDrawable materialShapeDrawable = new MaterialShapeDrawable(); + materialShapeDrawable.setFillColor(ColorStateList.valueOf(background.getColor())); + materialShapeDrawable.initializeElevationOverlay(context); + materialShapeDrawable.setElevation(ViewCompat.getElevation(this)); + ViewCompat.setBackground(this, materialShapeDrawable); + } + + setSelectedTabIndicator(MaterialResources.getDrawable(context, a, R.styleable.SamsungTabLayout_tabIndicator)); + setSelectedTabIndicatorColor(a.getColor(R.styleable.SamsungTabLayout_tabIndicatorColor, Color.TRANSPARENT)); + slidingTabIndicator.setSelectedIndicatorHeight(a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabIndicatorHeight, -1)); + mTabSelectedIndicatorColor = a.getColor(R.styleable.SamsungTabLayout_tabIndicatorColor, Color.TRANSPARENT); + setSelectedTabIndicatorGravity(a.getInt(R.styleable.SamsungTabLayout_tabIndicatorGravity, INDICATOR_GRAVITY_BOTTOM)); + setTabIndicatorFullWidth(a.getBoolean(R.styleable.SamsungTabLayout_tabIndicatorFullWidth, true)); + setTabIndicatorAnimationMode(a.getInt(R.styleable.SamsungTabLayout_tabIndicatorAnimationMode, INDICATOR_ANIMATION_MODE_LINEAR)); + + tabPaddingStart = tabPaddingTop = tabPaddingEnd = tabPaddingBottom = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPadding, 0); + tabPaddingStart = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingStart, tabPaddingStart); + tabPaddingTop = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingTop, tabPaddingTop); + tabPaddingEnd = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingEnd, tabPaddingEnd); + tabPaddingBottom = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabPaddingBottom, tabPaddingBottom); + + tabTextAppearance = a.getResourceId(R.styleable.SamsungTabLayout_tabTextAppearance, R.style.TabLayoutTextStyle); + + final TypedArray ta = context.obtainStyledAttributes(tabTextAppearance, R.styleable.TextAppearance); + tabTextSize = ta.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, 0); + mIsScaledTextSizeType = ta.getText(R.styleable.TextAppearance_android_textSize).toString().contains("sp"); + tabTextColors = MaterialResources.getColorStateList(context, ta, R.styleable.TextAppearance_android_textColor); + if (VERSION.SDK_INT >= 31) { + mBoldTypeface = Typeface.create(getResources().getString(R.string.sesl_font_family_medium), Typeface.BOLD); + mNormalTypeface = Typeface.create(getResources().getString(R.string.sesl_font_family_regular), Typeface.NORMAL); + } else { + mBoldTypeface = Typeface.create(getResources().getString(R.string.sesl_font_family_regular), Typeface.BOLD); + mNormalTypeface = Typeface.create(getResources().getString(R.string.sesl_font_family_regular), Typeface.NORMAL); + } + + mSubTabIndicatorHeight = getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_indicator_height); + mSubTabIndicator2ndHeight = getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_indicator_2nd_height); + mTabMinSideSpace = getResources().getDimensionPixelSize(R.dimen.sesl_tab_min_side_space); + mSubTabSubTextAppearance = a.getResourceId(R.styleable.SamsungTabLayout_seslTabSubTextAppearance, R.style.TabLayoutSubTextStyle); + + final TypedArray ta2 = context.obtainStyledAttributes(mSubTabSubTextAppearance, R.styleable.TextAppearance); + try { + mSubTabSubTextColors = MaterialResources.getColorStateList(context, ta2, R.styleable.TextAppearance_android_textColor); + mSubTabTextSize = ta2.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, 0); + } finally { + ta.recycle(); + ta2.recycle(); + } + + if (a.hasValue(R.styleable.SamsungTabLayout_seslTabSubTextColor)) { + mSubTabSubTextColors = MaterialResources.getColorStateList(context, a, R.styleable.SamsungTabLayout_seslTabSubTextColor); + } + + if (a.hasValue(R.styleable.SamsungTabLayout_seslTabSelectedSubTextColor)) { + final int selected = a.getColor(R.styleable.SamsungTabLayout_seslTabSelectedSubTextColor, 0); + mSubTabSubTextColors = createColorStateList(mSubTabSubTextColors.getDefaultColor(), selected); + } + + if (a.hasValue(R.styleable.SamsungTabLayout_tabTextColor)) { + tabTextColors = MaterialResources.getColorStateList(context, a, R.styleable.SamsungTabLayout_tabTextColor); + } + + if (a.hasValue(R.styleable.SamsungTabLayout_tabSelectedTextColor)) { + final int selected = a.getColor(R.styleable.SamsungTabLayout_tabSelectedTextColor, 0); + tabTextColors = createColorStateList(tabTextColors.getDefaultColor(), selected); + } + + tabIconTint = MaterialResources.getColorStateList(context, a, R.styleable.SamsungTabLayout_tabIconTint); + tabIconTintMode = ViewUtils.parseTintMode(a.getInt(R.styleable.SamsungTabLayout_tabIconTintMode, -1), null); + + tabRippleColorStateList = MaterialResources.getColorStateList(context, a, R.styleable.SamsungTabLayout_tabRippleColor); + + tabIndicatorAnimationDuration = a.getInt(R.styleable.SamsungTabLayout_tabIndicatorAnimationDuration, ANIMATION_DURATION); + + requestedTabMinWidth = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabMinWidth, INVALID_WIDTH); + requestedTabMaxWidth = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabMaxWidth, INVALID_WIDTH); + tabBackgroundResId = a.getResourceId(R.styleable.SamsungTabLayout_tabBackground, 0); + contentInsetStart = a.getDimensionPixelSize(R.styleable.SamsungTabLayout_tabContentStart, 0); + mode = a.getInt(R.styleable.SamsungTabLayout_tabMode, MODE_FIXED); + tabGravity = a.getInt(R.styleable.SamsungTabLayout_tabGravity, GRAVITY_FILL); + mFirstTabGravity = tabGravity; + inlineLabel = a.getBoolean(R.styleable.SamsungTabLayout_tabInlineLabel, false); + unboundedRipple = a.getBoolean(R.styleable.SamsungTabLayout_tabUnboundedRipple, false); + a.recycle(); + + final Resources res = getResources(); + tabTextMultiLineSize = res.getDimensionPixelSize(R.dimen.sesl_tab_text_size_2line); + scrollableTabMinWidth = res.getDimensionPixelSize(R.dimen.sesl_tab_scrollable_min_width); + + applyModeAndGravity(); + } + + public void setSelectedTabIndicatorColor(@ColorInt int color) { + mTabSelectedIndicatorColor = color; + for (Tab tab : tabs) { + final SeslAbsIndicatorView indicatorView = tab.view.mIndicatorView; + if (indicatorView != null) { + if (mDepthStyle == DEPTH_TYPE_SUB && mSubTabSelectedIndicatorColor != -1) { + indicatorView.setSelectedIndicatorColor(mSubTabSelectedIndicatorColor); + } else { + indicatorView.setSelectedIndicatorColor(color); + } + indicatorView.invalidate(); + } + } + } + + @Deprecated + public void setSelectedTabIndicatorHeight(int height) { + slidingTabIndicator.setSelectedIndicatorHeight(height); + } + + public void setScrollPosition(int position, float positionOffset, boolean updateSelectedText) { + setScrollPosition(position, positionOffset, updateSelectedText, true); + } + + public void setScrollPosition(int position, float positionOffset, boolean updateSelectedText, boolean updateIndicatorPosition) { + final int roundedPosition = Math.round(position + positionOffset); + if (roundedPosition < 0 || roundedPosition >= slidingTabIndicator.getChildCount()) { + return; + } + + if (updateIndicatorPosition) { + slidingTabIndicator.setIndicatorPositionFromTabPosition(position, positionOffset); + } + + if (scrollAnimator != null && scrollAnimator.isRunning()) { + scrollAnimator.cancel(); + } + scrollTo(calculateScrollXForTab(position, positionOffset), 0); + + if (updateSelectedText) { + setSelectedTabView(roundedPosition, true); + } + } + + public void addTab(@NonNull Tab tab) { + addTab(tab, tabs.isEmpty()); + } + + public void addTab(@NonNull Tab tab, int position) { + addTab(tab, position, tabs.isEmpty()); + } + + public void addTab(@NonNull Tab tab, boolean setSelected) { + addTab(tab, tabs.size(), setSelected); + } + + public void addTab(@NonNull Tab tab, int position, boolean setSelected) { + if (tab.parent != this) { + throw new IllegalArgumentException("Tab belongs to a different TabLayout."); + } + configureTab(tab, position); + addTabView(tab); + + if (setSelected) { + tab.select(); + } + } + + private void addTabFromItemView(@NonNull TabItem item) { + final Tab tab = newTab(); + if (item.text != null) { + tab.setText(item.text); + } + if (item.icon != null) { + tab.setIcon(item.icon); + } + if (item.customLayout != 0) { + tab.setCustomView(item.customLayout); + } + if (!TextUtils.isEmpty(item.getContentDescription())) { + tab.setContentDescription(item.getContentDescription()); + } + if (item.mSubText != null) { + tab.seslSetSubText(item.mSubText); + } + addTab(tab); + } + + @Deprecated + public void setOnTabSelectedListener(@Nullable OnTabSelectedListener listener) { + setOnTabSelectedListener((BaseOnTabSelectedListener) listener); + } + + @Deprecated + public void setOnTabSelectedListener(@Nullable BaseOnTabSelectedListener listener) { + if (selectedListener != null) { + removeOnTabSelectedListener(selectedListener); + } + selectedListener = listener; + if (listener != null) { + addOnTabSelectedListener(listener); + } + } + + public void addOnTabSelectedListener(@NonNull OnTabSelectedListener listener) { + addOnTabSelectedListener((BaseOnTabSelectedListener) listener); + } + + @Deprecated + public void addOnTabSelectedListener(@Nullable BaseOnTabSelectedListener listener) { + if (!selectedListeners.contains(listener)) { + selectedListeners.add(listener); + } + } + + public void removeOnTabSelectedListener(@NonNull OnTabSelectedListener listener) { + removeOnTabSelectedListener((BaseOnTabSelectedListener) listener); + } + + @Deprecated + public void removeOnTabSelectedListener(@Nullable BaseOnTabSelectedListener listener) { + selectedListeners.remove(listener); + } + + public void clearOnTabSelectedListeners() { + selectedListeners.clear(); + } + + @NonNull + public Tab newTab() { + Tab tab = createTabFromPool(); + tab.parent = this; + tab.view = createTabView(tab); + if (tab.id != NO_ID) { + tab.view.setId(tab.id); + } + + return tab; + } + + protected Tab createTabFromPool() { + Tab tab = tabPool.acquire(); + if (tab == null) { + tab = new Tab(); + } + return tab; + } + + protected boolean releaseFromTabPool(Tab tab) { + return tabPool.release(tab); + } + + public int getTabCount() { + return tabs.size(); + } + + @Nullable + public Tab getTabAt(int index) { + return (index < 0 || index >= getTabCount()) ? null : tabs.get(index); + } + + public int getSelectedTabPosition() { + return selectedTab != null ? selectedTab.getPosition() : -1; + } + + public void removeTab(@NonNull Tab tab) { + if (tab.parent != this) { + throw new IllegalArgumentException("Tab does not belong to this TabLayout."); + } + + removeTabAt(tab.getPosition()); + } + + public void removeTabAt(int position) { + final int selectedTabPosition = selectedTab != null ? selectedTab.getPosition() : 0; + removeTabViewAt(position); + + final Tab removedTab = tabs.remove(position); + if (removedTab != null) { + removedTab.reset(); + releaseFromTabPool(removedTab); + } + + final int newTabCount = tabs.size(); + for (int i = position; i < newTabCount; i++) { + tabs.get(i).setPosition(i); + } + + if (selectedTabPosition == position) { + selectTab(tabs.isEmpty() ? null : tabs.get(Math.max(0, position - 1))); + } + } + + public void removeAllTabs() { + for (int i = slidingTabIndicator.getChildCount() - 1; i >= 0; i--) { + removeTabViewAt(i); + } + + for (final Iterator i = tabs.iterator(); i.hasNext(); ) { + final Tab tab = i.next(); + i.remove(); + tab.reset(); + releaseFromTabPool(tab); + } + + selectedTab = null; + } + + public void setTabMode(@Mode int mode) { + if (mode != this.mode) { + this.mode = mode; + applyModeAndGravity(); + updateBadgePosition(); + } + } + + @Mode + public int getTabMode() { + return mode; + } + + public void setTabGravity(@TabGravity int gravity) { + if (tabGravity != gravity) { + tabGravity = gravity; + applyModeAndGravity(); + } + } + + @TabGravity + public int getTabGravity() { + return tabGravity; + } + + public void setSelectedTabIndicatorGravity(@TabIndicatorGravity int indicatorGravity) { + if (tabIndicatorGravity != indicatorGravity) { + tabIndicatorGravity = indicatorGravity; + ViewCompat.postInvalidateOnAnimation(slidingTabIndicator); + } + } + + @TabIndicatorGravity + public int getTabIndicatorGravity() { + return tabIndicatorGravity; + } + + public void setTabIndicatorAnimationMode(@TabIndicatorAnimationMode int tabIndicatorAnimationMode) { + this.tabIndicatorAnimationMode = tabIndicatorAnimationMode; + switch (tabIndicatorAnimationMode) { + case INDICATOR_ANIMATION_MODE_LINEAR: + this.tabIndicatorInterpolator = new TabIndicatorInterpolator(); + break; + case INDICATOR_ANIMATION_MODE_ELASTIC: + this.tabIndicatorInterpolator = new ElasticTabIndicatorInterpolator(); + break; + default: + throw new IllegalArgumentException(tabIndicatorAnimationMode + " is not a valid TabIndicatorAnimationMode"); + } + } + + @TabIndicatorAnimationMode + public int getTabIndicatorAnimationMode() { + return tabIndicatorAnimationMode; + } + + public void setTabIndicatorFullWidth(boolean tabIndicatorFullWidth) { + this.tabIndicatorFullWidth = tabIndicatorFullWidth; + ViewCompat.postInvalidateOnAnimation(slidingTabIndicator); + } + + public boolean isTabIndicatorFullWidth() { + return tabIndicatorFullWidth; + } + + public void setInlineLabel(boolean inline) { + if (inlineLabel != inline) { + inlineLabel = inline; + for (int i = 0; i < slidingTabIndicator.getChildCount(); i++) { + View child = slidingTabIndicator.getChildAt(i); + if (child instanceof TabView) { + ((TabView) child).updateOrientation(); + } + } + applyModeAndGravity(); + } + } + + public void setInlineLabelResource(@BoolRes int inlineResourceId) { + setInlineLabel(getResources().getBoolean(inlineResourceId)); + } + + public boolean isInlineLabel() { + return inlineLabel; + } + + public void setUnboundedRipple(boolean unboundedRipple) { + if (this.unboundedRipple != unboundedRipple) { + this.unboundedRipple = unboundedRipple; + for (int i = 0; i < slidingTabIndicator.getChildCount(); i++) { + View child = slidingTabIndicator.getChildAt(i); + if (child instanceof TabView) { + ((TabView) child).updateBackgroundDrawable(getContext()); + } + } + } + } + + public void setUnboundedRippleResource(@BoolRes int unboundedRippleResourceId) { + setUnboundedRipple(getResources().getBoolean(unboundedRippleResourceId)); + } + + public boolean hasUnboundedRipple() { + return unboundedRipple; + } + + public void setTabTextColors(@Nullable ColorStateList textColor) { + if (tabTextColors != textColor) { + tabTextColors = textColor; + updateAllTabs(); + } + } + + @Nullable + public ColorStateList getTabTextColors() { + return tabTextColors; + } + + public void setTabTextColors(int normalColor, int selectedColor) { + setTabTextColors(createColorStateList(normalColor, selectedColor)); + } + + public void setTabIconTint(@Nullable ColorStateList iconTint) { + if (tabIconTint != iconTint) { + tabIconTint = iconTint; + updateAllTabs(); + } + } + + public void setTabIconTintResource(@ColorRes int iconTintResourceId) { + setTabIconTint(AppCompatResources.getColorStateList(getContext(), iconTintResourceId)); + } + + @Nullable + public ColorStateList getTabIconTint() { + return tabIconTint; + } + + @Nullable + public ColorStateList getTabRippleColor() { + return tabRippleColorStateList; + } + + public void setTabRippleColor(@Nullable ColorStateList color) { + if (tabRippleColorStateList != color) { + tabRippleColorStateList = color; + for (int i = 0; i < slidingTabIndicator.getChildCount(); i++) { + View child = slidingTabIndicator.getChildAt(i); + if (child instanceof TabView) { + ((TabView) child).updateBackgroundDrawable(getContext()); + } + } + } + } + + public void setTabRippleColorResource(@ColorRes int tabRippleColorResourceId) { + setTabRippleColor(AppCompatResources.getColorStateList(getContext(), tabRippleColorResourceId)); + } + + @NonNull + public Drawable getTabSelectedIndicator() { + return tabSelectedIndicator; + } + + public void setSelectedTabIndicator(@Nullable Drawable tabSelectedIndicator) { + if (this.tabSelectedIndicator != tabSelectedIndicator) { + this.tabSelectedIndicator = tabSelectedIndicator != null ? tabSelectedIndicator : new GradientDrawable(); + } + } + + public void setSelectedTabIndicator(@DrawableRes int tabSelectedIndicatorResourceId) { + if (tabSelectedIndicatorResourceId != 0) { + setSelectedTabIndicator(AppCompatResources.getDrawable(getContext(), tabSelectedIndicatorResourceId)); + } else { + setSelectedTabIndicator(null); + } + } + + public void setupWithViewPager(@Nullable SeslViewPager viewPager) { + setupWithViewPager(viewPager, true); + } + + public void setupWithViewPager(@Nullable final SeslViewPager viewPager, boolean autoRefresh) { + setupWithViewPager(viewPager, autoRefresh, false); + } + + private void setupWithViewPager(@Nullable final SeslViewPager viewPager, boolean autoRefresh, boolean implicitSetup) { + if (this.viewPager != null) { + if (pageChangeListener != null) { + this.viewPager.removeOnPageChangeListener(pageChangeListener); + } + if (adapterChangeListener != null) { + this.viewPager.removeOnAdapterChangeListener(adapterChangeListener); + } + } + + if (currentVpSelectedListener != null) { + removeOnTabSelectedListener(currentVpSelectedListener); + currentVpSelectedListener = null; + } + + if (viewPager != null) { + this.viewPager = viewPager; + + if (pageChangeListener == null) { + pageChangeListener = new TabLayoutOnPageChangeListener(this); + } + pageChangeListener.reset(); + viewPager.addOnPageChangeListener(pageChangeListener); + + currentVpSelectedListener = new ViewPagerOnTabSelectedListener(viewPager); + addOnTabSelectedListener(currentVpSelectedListener); + + final PagerAdapter adapter = viewPager.getAdapter(); + if (adapter != null) { + setPagerAdapter(adapter, autoRefresh); + } + + if (adapterChangeListener == null) { + adapterChangeListener = new AdapterChangeListener(); + } + adapterChangeListener.setAutoRefresh(autoRefresh); + viewPager.addOnAdapterChangeListener(adapterChangeListener); + + setScrollPosition(viewPager.getCurrentItem(), 0f, true); + } else { + this.viewPager = null; + setPagerAdapter(null, false); + } + + setupViewPagerImplicitly = implicitSetup; + } + + @Deprecated + public void setTabsFromPagerAdapter(@Nullable final PagerAdapter adapter) { + setPagerAdapter(adapter, false); + } + + @Override + public boolean shouldDelayChildPressedState() { + return getTabScrollRange() > 0; + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + for (int i = 0; i < getTabCount(); i++) { + Tab tab = getTabAt(i); + if (tab != null && tab.view != null) { + if (tab.view.mMainTabTouchBackground != null) { + tab.view.mMainTabTouchBackground.setAlpha(0.0f); + } + + if (tab.view.mIndicatorView != null) { + if (getSelectedTabPosition() == i) { + tab.view.mIndicatorView.setShow(); + } else { + tab.view.mIndicatorView.setHide(); + } + } + } + } + + MaterialShapeUtils.setParentAbsoluteElevation(this); + + if (viewPager == null) { + final ViewParent vp = getParent(); + if (vp instanceof SeslViewPager) { + setupWithViewPager((SeslViewPager) vp, true, true); + } + } + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + if (setupViewPagerImplicitly) { + setupWithViewPager(null); + setupViewPagerImplicitly = false; + } + } + + private int getTabScrollRange() { + return Math.max(0, slidingTabIndicator.getWidth() - getWidth() - getPaddingLeft() - getPaddingRight()); + } + + void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) { + if (pagerAdapter != null && pagerAdapterObserver != null) { + pagerAdapter.unregisterDataSetObserver(pagerAdapterObserver); + } + + pagerAdapter = adapter; + + if (addObserver && adapter != null) { + if (pagerAdapterObserver == null) { + pagerAdapterObserver = new PagerAdapterObserver(); + } + adapter.registerDataSetObserver(pagerAdapterObserver); + } + + populateFromPagerAdapter(); + } + + void populateFromPagerAdapter() { + removeAllTabs(); + + if (pagerAdapter != null) { + final int adapterCount = pagerAdapter.getCount(); + for (int i = 0; i < adapterCount; i++) { + addTab(newTab().setText(pagerAdapter.getPageTitle(i)), false); + } + + if (viewPager != null && adapterCount > 0) { + final int curItem = viewPager.getCurrentItem(); + if (curItem != getSelectedTabPosition() && curItem < getTabCount()) { + selectTab(getTabAt(curItem), true, true); + } + } + } + } + + private void updateAllTabs() { + for (int i = 0, z = tabs.size(); i < z; i++) { + tabs.get(i).updateView(); + } + } + + @NonNull + private TabView createTabView(@NonNull final Tab tab) { + TabView tabView = tabViewPool != null ? tabViewPool.acquire() : null; + if (tabView == null) { + tabView = new TabView(getContext()); + } + if (tabView.mMainTabTouchBackground != null) { + tabView.mMainTabTouchBackground.setAlpha(0.0f); + } + tabView.setTab(tab); + tabView.setFocusable(true); + tabView.setMinimumWidth(getTabMinWidth()); + if (TextUtils.isEmpty(tab.contentDesc)) { + tabView.setContentDescription(tab.text); + } else { + tabView.setContentDescription(tab.contentDesc); + } + return tabView; + } + + private void configureTab(@NonNull Tab tab, int position) { + tab.setPosition(position); + tabs.add(position, tab); + + final int count = tabs.size(); + for (int i = position + 1; i < count; i++) { + tabs.get(i).setPosition(i); + } + } + + private void addTabView(@NonNull Tab tab) { + final TabView tabView = tab.view; + tabView.setSelected(false); + tabView.setActivated(false); + slidingTabIndicator.addView(tabView, tab.getPosition(), createLayoutParamsForTabs()); + } + + @Override + public void addView(View child) { + addViewInternal(child); + } + + @Override + public void addView(View child, int index) { + addViewInternal(child); + } + + @Override + public void addView(View child, ViewGroup.LayoutParams params) { + addViewInternal(child); + } + + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + addViewInternal(child); + } + + private void addViewInternal(final View child) { + if (child instanceof TabItem) { + addTabFromItemView((TabItem) child); + } else { + throw new IllegalArgumentException("Only TabItem instances can be added to TabLayout"); + } + } + + @NonNull + private LinearLayout.LayoutParams createLayoutParamsForTabs() { + final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); + updateTabViewLayoutParams(lp); + return lp; + } + + private void updateTabViewLayoutParams(@NonNull LinearLayout.LayoutParams lp) { + if (mode == MODE_FIXED && tabGravity == GRAVITY_FILL) { + lp.width = 0; + lp.weight = 1; + } else if (mode == SESL_MODE_FIXED_AUTO || mode == SESL_MODE_WEIGHT_AUTO) { + lp.width = LinearLayout.LayoutParams.WRAP_CONTENT; + lp.weight = 0; + } else { + lp.width = LinearLayout.LayoutParams.WRAP_CONTENT; + lp.weight = 0; + } + } + + @RequiresApi(VERSION_CODES.LOLLIPOP) + @Override + public void setElevation(float elevation) { + super.setElevation(elevation); + + MaterialShapeUtils.setElevation(this, elevation); + } + + @Override + public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + AccessibilityNodeInfoCompat infoCompat = AccessibilityNodeInfoCompat.wrap(info); + infoCompat.setCollectionInfo(CollectionInfoCompat.obtain(1, getTabCount(), false, CollectionInfoCompat.SELECTION_MODE_SINGLE)); + } + + @Override + protected void onDraw(@NonNull Canvas canvas) { + for (int i = 0; i < slidingTabIndicator.getChildCount(); i++) { + View tabView = slidingTabIndicator.getChildAt(i); + if (tabView instanceof TabView) { + ((TabView) tabView).drawBackground(canvas); + } + } + + super.onDraw(canvas); + } + + @SuppressLint("RestrictedApi") + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int idealHeight = Math.round(ViewUtils.dpToPx(getContext(), getDefaultHeight())); + switch (MeasureSpec.getMode(heightMeasureSpec)) { + case MeasureSpec.AT_MOST: + if (getChildCount() == 1 && MeasureSpec.getSize(heightMeasureSpec) >= idealHeight) { + getChildAt(0).setMinimumHeight(idealHeight); + } + break; + case MeasureSpec.UNSPECIFIED: + heightMeasureSpec = MeasureSpec.makeMeasureSpec(idealHeight + getPaddingTop() + getPaddingBottom(), MeasureSpec.EXACTLY); + break; + default: + break; + } + + final int specWidth = MeasureSpec.getSize(widthMeasureSpec); + if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED) { + tabMaxWidth = requestedTabMaxWidth > 0 ? requestedTabMaxWidth : (int) (specWidth - ViewUtils.dpToPx(getContext(), TAB_MIN_WIDTH_MARGIN)); + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + if (getChildCount() == 1) { + final View child = getChildAt(0); + boolean remeasure = false; + + switch (mode) { + case MODE_AUTO: + case MODE_SCROLLABLE: + remeasure = child.getMeasuredWidth() < getMeasuredWidth(); + break; + case MODE_FIXED: + remeasure = child.getMeasuredWidth() != getMeasuredWidth(); + break; + case SESL_MODE_FIXED_AUTO: + case SESL_MODE_WEIGHT_AUTO: + remeasure = true; + break; + } + + if (remeasure) { + int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingTop() + getPaddingBottom(), child.getLayoutParams().height); + + int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY); + child.measure(childWidthMeasureSpec, childHeightMeasureSpec); + } + + checkOverScreen(); + if (mIsOverScreen && getChildAt(0).getMeasuredWidth() < getMeasuredWidth()) { + setPaddingRelative((getMeasuredWidth() - getChildAt(0).getMeasuredWidth()) / 2, 0, 0, 0); + } else { + setPaddingRelative(0, 0, 0, 0); + } + } + } + + private void removeTabViewAt(int position) { + final TabView view = (TabView) slidingTabIndicator.getChildAt(position); + slidingTabIndicator.removeViewAt(position); + if (view != null) { + view.reset(); + tabViewPool.release(view); + } + requestLayout(); + } + + private void animateToTab(int newPosition) { + if (newPosition == Tab.INVALID_POSITION) { + return; + } + + if (getWindowToken() == null|| !ViewCompat.isLaidOut(this)|| slidingTabIndicator.childrenNeedLayout()) { + setScrollPosition(newPosition, 0f, true); + return; + } + + final int startScrollX = getScrollX(); + final int targetScrollX = calculateScrollXForTab(newPosition, 0); + + if (startScrollX != targetScrollX) { + ensureScrollAnimator(); + + scrollAnimator.setIntValues(startScrollX, targetScrollX); + scrollAnimator.start(); + } + + slidingTabIndicator.animateIndicatorToPosition(newPosition, tabIndicatorAnimationDuration); + } + + @SuppressLint("RestrictedApi") + private void ensureScrollAnimator() { + if (scrollAnimator == null) { + scrollAnimator = new ValueAnimator(); + scrollAnimator.setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR); + scrollAnimator.setDuration(tabIndicatorAnimationDuration); + scrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(@NonNull ValueAnimator animator) { + scrollTo((int) animator.getAnimatedValue(), 0); + } + }); + } + } + + void setScrollAnimatorListener(ValueAnimator.AnimatorListener listener) { + ensureScrollAnimator(); + scrollAnimator.addListener(listener); + } + + private void setSelectedTabView(int position, boolean pressed) { + final int tabCount = slidingTabIndicator.getChildCount(); + if (position < tabCount) { + for (int i = 0; i < tabCount; i++) { + final View child = slidingTabIndicator.getChildAt(i); + child.setSelected(i == position); + child.setActivated(i == position); + } + + tabs.get(position).view.setSelected(true); + + for (int i = 0; i < getTabCount(); i++) { + final TabView tabView = tabs.get(i).view; + + if (i == position) { + if (tabView.textView != null) { + startTextColorChangeAnimation(tabView.textView, getSelectedTabTextColor()); + tabView.textView.setTypeface(mBoldTypeface); + tabView.textView.setSelected(true); + } + if (mDepthStyle == DEPTH_TYPE_SUB && tabView.mSubTextView != null) { + startTextColorChangeAnimation(tabView.mSubTextView, seslGetSelectedTabSubTextColor()); + tabView.mSubTextView.setSelected(true); + } + if (tabView.mIndicatorView != null) { + if (!pressed) { + tabs.get(i).view.mIndicatorView.setReleased(); + } else if (tabView.mIndicatorView.getAlpha() != 1.0f) { + tabView.mIndicatorView.setShow(); + } + } + } else { + if (tabView.mIndicatorView != null) { + tabView.mIndicatorView.setHide(); + } + if (tabView.textView != null) { + tabView.textView.setTypeface(mNormalTypeface); + startTextColorChangeAnimation(tabView.textView, tabTextColors.getDefaultColor()); + tabView.textView.setSelected(false); + } + if (mDepthStyle == DEPTH_TYPE_SUB && tabView.mSubTextView != null) { + startTextColorChangeAnimation(tabView.mSubTextView, mSubTabSubTextColors.getDefaultColor()); + tabView.mSubTextView.setSelected(false); + } + } + } + } + } + + public void selectTab(@Nullable Tab tab) { + selectTab(tab, true); + } + + public void selectTab(@Nullable Tab tab, boolean updateIndicator) { + selectTab(tab, updateIndicator, true); + } + + public void selectTab(@Nullable final Tab tab, boolean updateIndicator, boolean pressed) { + if (tab != null && !tab.view.isEnabled()) { + if (viewPager != null) { + viewPager.setCurrentItem(getSelectedTabPosition()); + return; + } + } + + final Tab currentTab = selectedTab; + + if (currentTab == tab) { + if (currentTab != null) { + dispatchTabReselected(tab); + animateToTab(tab.getPosition()); + } + } else { + final int newPosition = tab != null ? tab.getPosition() : Tab.INVALID_POSITION; + if (updateIndicator) { + if ((currentTab == null || currentTab.getPosition() == Tab.INVALID_POSITION) && newPosition != Tab.INVALID_POSITION) { + setScrollPosition(newPosition, 0f, true); + } else { + animateToTab(newPosition); + } + if (newPosition != Tab.INVALID_POSITION) { + setSelectedTabView(newPosition, pressed); + } + } + selectedTab = tab; + if (currentTab != null) { + dispatchTabUnselected(currentTab); + } + if (tab != null) { + dispatchTabSelected(tab); + } + } + } + + private void dispatchTabSelected(@NonNull final Tab tab) { + for (int i = selectedListeners.size() - 1; i >= 0; i--) { + selectedListeners.get(i).onTabSelected(tab); + } + } + + private void dispatchTabUnselected(@NonNull final Tab tab) { + for (int i = selectedListeners.size() - 1; i >= 0; i--) { + selectedListeners.get(i).onTabUnselected(tab); + } + } + + private void dispatchTabReselected(@NonNull final Tab tab) { + for (int i = selectedListeners.size() - 1; i >= 0; i--) { + selectedListeners.get(i).onTabReselected(tab); + } + } + + private int calculateScrollXForTab(int position, float positionOffset) { + if (mode == MODE_SCROLLABLE || mode == MODE_AUTO || mode == SESL_MODE_FIXED_AUTO || mode == SESL_MODE_WEIGHT_AUTO) { + final View selectedChild = slidingTabIndicator.getChildAt(position); + final View nextChild = position + 1 < slidingTabIndicator.getChildCount() ? slidingTabIndicator.getChildAt(position + 1) : null; + final int selectedWidth = selectedChild != null ? selectedChild.getWidth() : 0; + final int nextWidth = nextChild != null ? nextChild.getWidth() : 0; + + int scrollBase = selectedChild.getLeft() + (selectedWidth / 2) - (getWidth() / 2); + int scrollOffset = (int) ((selectedWidth + nextWidth) * 0.5f * positionOffset); + + return (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_LTR) ? scrollBase + scrollOffset : scrollBase - scrollOffset; + } + return 0; + } + + private void applyModeAndGravity() { + ViewCompat.setPaddingRelative(slidingTabIndicator, 0, 0, 0, 0); + + switch (mode) { + case MODE_AUTO: + case MODE_FIXED: + if (tabGravity == GRAVITY_START) { + Log.w(LOG_TAG, "GRAVITY_START is not supported with the current tab mode, GRAVITY_CENTER will be used instead"); + } + slidingTabIndicator.setGravity(Gravity.CENTER_HORIZONTAL); + break; + case MODE_SCROLLABLE: + case SESL_MODE_FIXED_AUTO: + case SESL_MODE_WEIGHT_AUTO: + applyGravityForModeScrollable(tabGravity); + break; + } + + updateTabViews(true); + } + + private void applyGravityForModeScrollable(int tabGravity) { + switch (tabGravity) { + case GRAVITY_CENTER: + slidingTabIndicator.setGravity(Gravity.CENTER_HORIZONTAL); + break; + case GRAVITY_FILL: + Log.w(LOG_TAG, "MODE_SCROLLABLE + GRAVITY_FILL is not supported, GRAVITY_START will be used instead"); + case GRAVITY_START: + slidingTabIndicator.setGravity(GravityCompat.START); + break; + default: + break; + } + } + + void updateTabViews(final boolean requestLayout) { + for (int i = 0; i < slidingTabIndicator.getChildCount(); i++) { + View child = slidingTabIndicator.getChildAt(i); + child.setMinimumWidth(getTabMinWidth()); + updateTabViewLayoutParams((LinearLayout.LayoutParams) child.getLayoutParams()); + if (requestLayout) { + child.requestLayout(); + } + } + updateBadgePosition(); + } + + public static class Tab { + public static final int INVALID_POSITION = -1; + @Nullable private Object tag; + @Nullable private Drawable icon; + @Nullable private CharSequence text; + @Nullable private CharSequence subText; + @Nullable private CharSequence contentDesc; + private int position = INVALID_POSITION; + @Nullable private View customView; + private @LabelVisibility int labelVisibilityMode = TAB_LABEL_VISIBILITY_LABELED; + @Nullable public SamsungTabLayout parent; + @NonNull public TabView view; + private int id = NO_ID; + + public Tab() { + } + + @Nullable + public Object getTag() { + return tag; + } + + @NonNull + public Tab setTag(@Nullable Object tag) { + this.tag = tag; + return this; + } + + @NonNull + public Tab setId(int id) { + this.id = id; + if (view != null) { + view.setId(id); + } + return this; + } + + public int getId() { + return id; + } + + @Nullable + public View getCustomView() { + return customView; + } + + @NonNull + public Tab setCustomView(@Nullable View view) { + if (this.view.textView != null) { + this.view.removeAllViews(); + } + customView = view; + updateView(); + return this; + } + + @NonNull + public Tab setCustomView(@LayoutRes int resId) { + final LayoutInflater inflater = LayoutInflater.from(view.getContext()); + return setCustomView(inflater.inflate(resId, view, false)); + } + + @Nullable + public Drawable getIcon() { + return icon; + } + + public int getPosition() { + return position; + } + + void setPosition(int position) { + this.position = position; + } + + @Nullable + public CharSequence getText() { + return text; + } + + @Nullable + public CharSequence seslGetSubText() { + return subText; + } + + @SuppressLint("UnsafeOptInUsageError") + @NonNull + public Tab setIcon(@Nullable Drawable icon) { + this.icon = icon; + if ((parent.tabGravity == GRAVITY_CENTER) || parent.mode == MODE_AUTO) { + parent.updateTabViews(true); + } + updateView(); + if (BadgeUtils.USE_COMPAT_PARENT && view.hasBadgeDrawable() && view.badgeDrawable.isVisible()) { + view.invalidate(); + } + return this; + } + + @NonNull + public Tab setIcon(@DrawableRes int resId) { + if (parent == null) { + throw new IllegalArgumentException("Tab not attached to a TabLayout"); + } + return setIcon(AppCompatResources.getDrawable(parent.getContext(), resId)); + } + + @NonNull + public Tab setText(@Nullable CharSequence text) { + if (TextUtils.isEmpty(contentDesc) && !TextUtils.isEmpty(text)) { + view.setContentDescription(text); + } + + this.text = text; + updateView(); + return this; + } + + @NonNull + public Tab seslSetSubText(@Nullable CharSequence subText) { + this.subText = subText; + updateView(); + return this; + } + + @NonNull + public Tab setText(@StringRes int resId) { + if (parent == null) { + throw new IllegalArgumentException("Tab not attached to a TabLayout"); + } + return setText(parent.getResources().getText(resId)); + } + + @NonNull + public BadgeDrawable getOrCreateBadge() { + return view.getOrCreateBadge(); + } + + public void removeBadge() { + view.removeBadge(); + } + + @Nullable + public BadgeDrawable getBadge() { + return view.getBadge(); + } + + @SuppressLint("UnsafeOptInUsageError") + @NonNull + public Tab setTabLabelVisibility(@LabelVisibility int mode) { + this.labelVisibilityMode = mode; + if ((parent.tabGravity == GRAVITY_CENTER) || parent.mode == MODE_AUTO) { + parent.updateTabViews(true); + } + this.updateView(); + if (BadgeUtils.USE_COMPAT_PARENT && view.hasBadgeDrawable() && view.badgeDrawable.isVisible()) { + view.invalidate(); + } + return this; + } + + @LabelVisibility + public int getTabLabelVisibility() { + return this.labelVisibilityMode; + } + + public void select() { + if (parent == null) { + throw new IllegalArgumentException("Tab not attached to a TabLayout"); + } + parent.selectTab(this); + } + + public boolean isSelected() { + if (parent == null) { + throw new IllegalArgumentException("Tab not attached to a TabLayout"); + } + int selectedPosition = parent.getSelectedTabPosition(); + return selectedPosition == position; + } + + @NonNull + public Tab setContentDescription(@StringRes int resId) { + if (parent == null) { + throw new IllegalArgumentException("Tab not attached to a TabLayout"); + } + return setContentDescription(parent.getResources().getText(resId)); + } + + @NonNull + public Tab setContentDescription(@Nullable CharSequence contentDesc) { + this.contentDesc = contentDesc; + updateView(); + return this; + } + + @Nullable + public CharSequence getContentDescription() { + return (view == null) ? null : view.getContentDescription(); + } + + void updateView() { + if (view != null) { + view.update(); + } + } + + void reset() { + parent = null; + view = null; + tag = null; + icon = null; + id = NO_ID; + text = null; + contentDesc = null; + position = INVALID_POSITION; + customView = null; + subText = null; + } + + public TextView seslGetTextView() { + if (customView != null || view == null) { + return null; + } + return view.textView; + } + + public TextView seslGetSubTextView() { + if (customView != null || view == null) { + return null; + } + return view.mSubTextView; + } + } + + public final class TabView extends LinearLayout { + private Tab tab; + private TextView textView; + private ImageView iconView; + @Nullable private View badgeAnchorView; + @Nullable private BadgeDrawable badgeDrawable; + + @Nullable private View customView; + @Nullable private TextView customTextView; + @Nullable private ImageView customIconView; + @Nullable private Drawable baseBackgroundDrawable; + + private TextView mDotBadgeView; + private int mIconSize; + private SeslAbsIndicatorView mIndicatorView; + private boolean mIsCallPerformClick; + private View mMainTabTouchBackground; + private TextView mNBadgeView; + private TextView mSubTextView; + private RelativeLayout mTabParentView; + + private int defaultMaxLines = 2; + + View.OnKeyListener mTabViewKeyListener = new View.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + return false; + } + }; + + public TabView(@NonNull Context context) { + super(context); + updateBackgroundDrawable(context); + setGravity(Gravity.CENTER); + setOrientation(inlineLabel ? HORIZONTAL : VERTICAL); + setClickable(true); + setOnKeyListener(mTabViewKeyListener); + if (mDepthStyle == DEPTH_TYPE_MAIN) { + ViewCompat.setPaddingRelative(this, 0, tabPaddingTop, 0, tabPaddingBottom); + } + mIconSize = getResources().getDimensionPixelOffset(R.dimen.sesl_tab_icon_size); + } + + @SuppressLint("RestrictedApi") + private void updateBackgroundDrawable(Context context) { + if (tabBackgroundResId != 0) { + baseBackgroundDrawable = AppCompatResources.getDrawable(context, tabBackgroundResId); + if (baseBackgroundDrawable != null && baseBackgroundDrawable.isStateful()) { + baseBackgroundDrawable.setState(getDrawableState()); + } + ViewCompat.setBackground(this, baseBackgroundDrawable); + } else { + baseBackgroundDrawable = null; + } + } + + private void drawBackground(@NonNull Canvas canvas) { + if (baseBackgroundDrawable != null) { + baseBackgroundDrawable.setBounds(getLeft(), getTop(), getRight(), getBottom()); + baseBackgroundDrawable.draw(canvas); + } + } + + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + int[] state = getDrawableState(); + if (baseBackgroundDrawable != null && baseBackgroundDrawable.isStateful()) { + baseBackgroundDrawable.setState(state); + } + } + + @Override + public boolean performClick() { + if (mIsCallPerformClick) { + mIsCallPerformClick = false; + return true; + } + + final boolean handled = super.performClick(); + + if (tab != null) { + if (!handled) { + playSoundEffect(SoundEffectConstants.CLICK); + } + tab.select(); + return true; + } else { + return handled; + } + } + + @Override + public void setSelected(final boolean selected) { + if (isEnabled()) { + final boolean changed = isSelected() != selected; + + super.setSelected(selected); + + if (changed && selected && Build.VERSION.SDK_INT < 16) { + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + } + + if (textView != null) { + textView.setSelected(selected); + } + if (iconView != null) { + iconView.setSelected(selected); + } + if (customView != null) { + customView.setSelected(selected); + } + if (mIndicatorView != null) { + mIndicatorView.setSelected(selected); + } + if (mSubTextView != null) { + mSubTextView.setSelected(selected); + } + } + } + + @Override + public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(info); + if (badgeDrawable != null && badgeDrawable.isVisible()) { + CharSequence customContentDescription = getContentDescription(); + info.setContentDescription(customContentDescription + ", " + badgeDrawable.getContentDescription()); + } + AccessibilityNodeInfoCompat infoCompat = AccessibilityNodeInfoCompat.wrap(info); + infoCompat.setCollectionItemInfo(CollectionItemInfoCompat.obtain(0,1, tab.getPosition(), 1, false, isSelected())); + if (isSelected()) { + infoCompat.setClickable(false); + infoCompat.removeAction(AccessibilityActionCompat.ACTION_CLICK); + } + infoCompat.setRoleDescription(getResources().getString(R.string.item_view_role_description)); + if (mNBadgeView != null && mNBadgeView.getVisibility() == VISIBLE && mNBadgeView.getContentDescription() != null) { + CharSequence customContentDescription = getContentDescription(); + infoCompat.setContentDescription(customContentDescription + ", " + mNBadgeView.getContentDescription()); + } + } + + @Override + public void onMeasure(final int origWidthMeasureSpec, final int origHeightMeasureSpec) { + final int specWidthSize = MeasureSpec.getSize(origWidthMeasureSpec); + final int specWidthMode = MeasureSpec.getMode(origWidthMeasureSpec); + final int maxWidth = getTabMaxWidth(); + + int widthMeasureSpec = origWidthMeasureSpec; + final int heightMeasureSpec = origHeightMeasureSpec; + + if (mode != SESL_MODE_FIXED_AUTO && mode != SESL_MODE_WEIGHT_AUTO) { + if (mRequestedTabWidth != -1) { + widthMeasureSpec = MeasureSpec.makeMeasureSpec(mRequestedTabWidth, MeasureSpec.EXACTLY); + } else if (maxWidth > 0 && (specWidthMode == MeasureSpec.UNSPECIFIED || specWidthSize > maxWidth)) { + widthMeasureSpec = MeasureSpec.makeMeasureSpec(tabMaxWidth, MeasureSpec.AT_MOST); + } + } else { + if (specWidthMode == 0) { + widthMeasureSpec = MeasureSpec.makeMeasureSpec(tabMaxWidth, MeasureSpec.UNSPECIFIED); + } else if (specWidthMode == MeasureSpec.EXACTLY) { + widthMeasureSpec = MeasureSpec.makeMeasureSpec(specWidthSize, MeasureSpec.EXACTLY); + } + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + if (textView != null && customView == null) { + float textSize = tabTextSize; + checkMaxFontScale(textView, (int) textSize); + if (mDepthStyle == DEPTH_TYPE_SUB && mSubTextView != null) { + checkMaxFontScale(mSubTextView, mSubTabTextSize); + } + int maxLines = defaultMaxLines; + + if (iconView != null && iconView.getVisibility() == VISIBLE) { + maxLines = 1; + } else if (textView != null && textView.getLineCount() > 1) { + textSize = tabTextMultiLineSize; + } + + final float curTextSize = textView.getTextSize(); + final int curLineCount = textView.getLineCount(); + final int curMaxLines = TextViewCompat.getMaxLines(textView); + + if (textSize != curTextSize || (curMaxLines >= 0 && maxLines != curMaxLines)) { + boolean updateTextView = true; + + if (mode == MODE_FIXED && textSize > curTextSize && curLineCount == 1) { + final Layout layout = textView.getLayout(); + if (layout == null || approximateLineWidth(layout, 0, textSize) > getMeasuredWidth() - getPaddingLeft() - getPaddingRight()) { + updateTextView = false; + } + } + + if (updateTextView) { + textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); + checkMaxFontScale(textView, (int) textSize); + if (mDepthStyle == DEPTH_TYPE_SUB && mSubTextView != null) { + checkMaxFontScale(mSubTextView, mSubTabTextSize); + } + textView.setMaxLines(maxLines); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + } + if (customTextView == null && mTabParentView != null && textView != null && tab != null && mode == MODE_SCROLLABLE && mDepthStyle == DEPTH_TYPE_SUB) { + if (tabMaxWidth > 0) { + textView.measure(tabMaxWidth, 0); + } else { + textView.measure(0, 0); + } + + ViewGroup.LayoutParams lp = mTabParentView.getLayoutParams(); + lp.width = textView.getMeasuredWidth() + (getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_side_space) * 2); + mTabParentView.setLayoutParams(lp); + + super.onMeasure(MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.AT_MOST), origHeightMeasureSpec); + } + } + + void setTab(@Nullable final Tab tab) { + if (tab != this.tab) { + this.tab = tab; + update(); + } + } + + void reset() { + setTab(null); + setSelected(false); + } + + @SuppressLint("RestrictedApi") + final void update() { + final Tab tab = this.tab; + final View custom = tab != null ? tab.getCustomView() : null; + if (custom != null) { + final ViewParent customParent = custom.getParent(); + if (customParent != this) { + if (customParent != null) { + ((ViewGroup) customParent).removeView(custom); + } + addView(custom); + } + customView = custom; + if (this.textView != null) { + this.textView.setVisibility(GONE); + } + if (this.iconView != null) { + this.iconView.setVisibility(GONE); + this.iconView.setImageDrawable(null); + } + if (mSubTextView != null) { + mSubTextView.setVisibility(GONE); + } + + customTextView = custom.findViewById(android.R.id.text1); + if (customTextView != null) { + defaultMaxLines = TextViewCompat.getMaxLines(customTextView); + } + customIconView = custom.findViewById(android.R.id.icon); + } else { + if (customView != null) { + removeView(customView); + customView = null; + } + customTextView = null; + customIconView = null; + } + + if (customView == null && tab != null) { + if (mTabParentView == null) { + if (mDepthStyle == DEPTH_TYPE_SUB) { + mTabParentView = (RelativeLayout) LayoutInflater.from(getContext()).inflate(R.layout.sesl_tabs_sub_tab_layout, this, false); + } else { + mTabParentView = (RelativeLayout) LayoutInflater.from(getContext()).inflate(R.layout.sesl_tabs_main_tab_layout, this, false); + mMainTabTouchBackground = mTabParentView.findViewById(R.id.main_tab_touch_background); + if (mMainTabTouchBackground != null && tab.icon == null) { + ViewCompat.setBackground(mMainTabTouchBackground, ContextCompat.getDrawable(getContext(), R.drawable.sesl_tablayout_maintab_touch_background)); + mMainTabTouchBackground.setAlpha(0.0f); + } + } + } + + if (mIndicatorView == null) { + mIndicatorView = mTabParentView.findViewById(R.id.indicator); + } + if (mDepthStyle != DEPTH_TYPE_SUB) { + if (mIndicatorView != null) { + if (!mIsOneUI4) { + ViewGroup.LayoutParams lp = mIndicatorView.getLayoutParams(); + lp.height = (int) ViewUtils.dpToPx(getContext(), 4); + mIndicatorView.setLayoutParams(lp); + } + mIndicatorView.setSelectedIndicatorColor(mTabSelectedIndicatorColor); + } + } else { + if (mIndicatorView != null && mSubTabSelectedIndicatorColor != -1) { + mIndicatorView.setSelectedIndicatorColor(mSubTabSelectedIndicatorColor); + } + } + + if (textView == null) { + textView = mTabParentView.findViewById(R.id.title); + } + defaultMaxLines = TextViewCompat.getMaxLines(textView); + TextViewCompat.setTextAppearance(textView, tabTextAppearance); + if (isSelected()) { + textView.setTypeface(mBoldTypeface); + } else { + textView.setTypeface(mNormalTypeface); + } + checkMaxFontScale(textView, (int) tabTextSize); + textView.setTextColor(tabTextColors); + + if (mDepthStyle == DEPTH_TYPE_SUB) { + if (mSubTextView == null) { + mSubTextView = mTabParentView.findViewById(R.id.sub_title); + } + TextViewCompat.setTextAppearance(mSubTextView, mSubTabSubTextAppearance); + mSubTextView.setTextColor(mSubTabSubTextColors); + if (mSubTextView != null) { + checkMaxFontScale(mSubTextView, mSubTabTextSize); + } + } + + if (iconView == null && mTabParentView != null) { + iconView = mTabParentView.findViewById(R.id.icon); + } + + Drawable iconDrawable = (tab != null && tab.getIcon() != null) ? DrawableCompat.wrap(tab.getIcon()).mutate() : null; + if (iconDrawable != null) { + DrawableCompat.setTintList(iconDrawable, tabIconTint); + if (tabIconTintMode != null) { + DrawableCompat.setTintMode(iconDrawable, tabIconTintMode); + } + } + + seslUpdateTextAndIcon(textView, mSubTextView, iconView); + + //kang + boolean z; + int i; + int i2 = -1; + CharSequence charSequence = null; + if (SamsungTabLayout.this.mDepthStyle == 2) { + if (mode == MODE_SCROLLABLE) { + i2 = -2; + } + if (tab != null) { + charSequence = tab.seslGetSubText(); + } + i = !TextUtils.isEmpty(charSequence) ? SamsungTabLayout.this.mSubTabIndicator2ndHeight : SamsungTabLayout.this.mSubTabIndicatorHeight; + z = this.mTabParentView.getHeight() != i; + } else { + z = false; + if (this.tab.icon != null) { + i = -1; + i2 = -2; + } else { + i = -1; + } + } + + if (mTabParentView.getParent() == null) { + addView(mTabParentView, i2, i); + } else if (z) { + removeView(mTabParentView); + addView(mTabParentView, i2, i); + } + //kang + + tryUpdateBadgeAnchor(); + addOnLayoutChangeListener(iconView); + addOnLayoutChangeListener(textView); + } else { + if (customTextView != null || customIconView != null) { + updateTextAndIcon(customTextView, customIconView); + } + } + + if (tab != null && !TextUtils.isEmpty(tab.contentDesc)) { + setContentDescription(tab.contentDesc); + } + setSelected(tab != null && tab.isSelected()); + } + + @SuppressLint("UnsafeOptInUsageError") + private void inflateAndAddDefaultIconView() { + ViewGroup iconViewParent = this; + if (BadgeUtils.USE_COMPAT_PARENT) { + iconViewParent = createPreApi18BadgeAnchorRoot(); + addView(iconViewParent, 0); + } + this.iconView = (ImageView) LayoutInflater.from(getContext()).inflate(R.layout.sesl_layout_tab_icon, iconViewParent, false); + iconViewParent.addView(iconView, 0); + } + + @SuppressLint("UnsafeOptInUsageError") + private void inflateAndAddDefaultTextView() { + ViewGroup textViewParent = this; + if (BadgeUtils.USE_COMPAT_PARENT) { + textViewParent = createPreApi18BadgeAnchorRoot(); + addView(textViewParent); + } + this.textView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.sesl_layout_tab_text, textViewParent, false); + textViewParent.addView(textView); + } + + @SuppressLint("UnsafeOptInUsageError") + private void inflateAndAddDefaultSubTextView() { + ViewGroup textViewParent = this; + if (BadgeUtils.USE_COMPAT_PARENT) { + textViewParent = createPreApi18BadgeAnchorRoot(); + addView(textViewParent); + } + this.textView = (TextView) LayoutInflater.from(getContext()).inflate(R.layout.sesl_layout_tab_sub_text, textViewParent, false); + textViewParent.addView(textView); + } + + @NonNull + private FrameLayout createPreApi18BadgeAnchorRoot() { + FrameLayout frameLayout = new FrameLayout(getContext()); + FrameLayout.LayoutParams layoutparams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + frameLayout.setLayoutParams(layoutparams); + return frameLayout; + } + + @NonNull + private BadgeDrawable getOrCreateBadge() { + if (badgeDrawable == null) { + badgeDrawable = BadgeDrawable.create(getContext()); + } + tryUpdateBadgeAnchor(); + if (badgeDrawable == null) { + throw new IllegalStateException("Unable to create badge"); + } + return badgeDrawable; + } + + @Nullable + private BadgeDrawable getBadge() { + return badgeDrawable; + } + + private void removeBadge() { + if (badgeAnchorView != null) { + tryRemoveBadgeFromAnchor(); + } + badgeDrawable = null; + } + + private void addOnLayoutChangeListener(@Nullable final View view) { + if (view == null) { + return; + } + view.addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { + if (view.getVisibility() == VISIBLE) { + tryUpdateBadgeDrawableBounds(view); + } + } + }); + } + + private void tryUpdateBadgeAnchor() { + if (!hasBadgeDrawable()) { + return; + } + if (customView != null) { + tryRemoveBadgeFromAnchor(); + } else { + if (iconView != null && tab != null && tab.getIcon() != null) { + if (badgeAnchorView != iconView) { + tryRemoveBadgeFromAnchor(); + tryAttachBadgeToAnchor(iconView); + } else { + tryUpdateBadgeDrawableBounds(iconView); + } + } else if (textView != null && tab != null && tab.getTabLabelVisibility() == TAB_LABEL_VISIBILITY_LABELED) { + if (badgeAnchorView != textView) { + tryRemoveBadgeFromAnchor(); + tryAttachBadgeToAnchor(textView); + } else { + tryUpdateBadgeDrawableBounds(textView); + } + } else { + tryRemoveBadgeFromAnchor(); + } + } + } + + @SuppressLint("UnsafeOptInUsageError") + private void tryAttachBadgeToAnchor(@Nullable View anchorView) { + if (!hasBadgeDrawable()) { + return; + } + if (anchorView != null) { + clipViewToPaddingForBadge(false); + BadgeUtils.attachBadgeDrawable(badgeDrawable, anchorView, getCustomParentForBadge(anchorView)); + badgeAnchorView = anchorView; + } + } + + @SuppressLint("UnsafeOptInUsageError") + private void tryRemoveBadgeFromAnchor() { + if (!hasBadgeDrawable()) { + return; + } + clipViewToPaddingForBadge(true); + if (badgeAnchorView != null) { + BadgeUtils.detachBadgeDrawable(badgeDrawable, badgeAnchorView); + badgeAnchorView = null; + } + } + + private void clipViewToPaddingForBadge(boolean flag) { + setClipChildren(flag); + setClipToPadding(flag); + ViewGroup parent = (ViewGroup) getParent(); + if (parent != null) { + parent.setClipChildren(flag); + parent.setClipToPadding(flag); + } + } + + final void updateOrientation() { + setOrientation(inlineLabel ? HORIZONTAL : VERTICAL); + if (customTextView != null || customIconView != null) { + updateTextAndIcon(customTextView, customIconView); + } else { + updateTextAndIcon(textView, iconView); + } + } + + private void seslUpdateTextAndIcon(@Nullable final TextView textView, @Nullable final TextView subTextView, @Nullable final ImageView iconView) { + updateTextAndIcon(textView, iconView); + + if (subTextView != null) { + CharSequence subText = tab != null ? tab.seslGetSubText() : null; + RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) textView.getLayoutParams(); + if (!TextUtils.isEmpty(subText)) { + lp.removeRule(13); + lp.addRule(2, R.id.center_anchor); + subTextView.setText(subText); + if (tab.labelVisibilityMode == TAB_LABEL_VISIBILITY_LABELED) { + subTextView.setVisibility(VISIBLE); + } else { + subTextView.setVisibility(GONE); + } + setVisibility(VISIBLE); + } else { + lp.addRule(13); + lp.removeRule(2); + subTextView.setVisibility(GONE); + subTextView.setText(null); + } + } + } + + @SuppressLint("RestrictedApi") + private void updateTextAndIcon(@Nullable final TextView textView, @Nullable final ImageView iconView) { + final Drawable icon = (tab != null && tab.getIcon() != null) ? DrawableCompat.wrap(tab.getIcon()).mutate() : null; + if (icon != null) { + DrawableCompat.setTintList(icon, tabIconTint); + if (tabIconTintMode != null) { + DrawableCompat.setTintMode(icon, tabIconTintMode); + } + } + + final CharSequence text = tab != null ? tab.getText() : null; + + if (iconView != null) { + if (icon != null) { + iconView.setImageDrawable(icon); + iconView.setVisibility(VISIBLE); + setVisibility(VISIBLE); + } else { + iconView.setVisibility(GONE); + iconView.setImageDrawable(null); + } + } + + final boolean hasText = !TextUtils.isEmpty(text); + if (textView != null) { + if (hasText) { + textView.setText(text); + if (tab.labelVisibilityMode == TAB_LABEL_VISIBILITY_LABELED) { + textView.setVisibility(VISIBLE); + } else { + textView.setVisibility(GONE); + } + setVisibility(VISIBLE); + } else { + textView.setVisibility(GONE); + textView.setText(null); + } + } + + if (iconView != null) { + MarginLayoutParams lp = ((MarginLayoutParams) iconView.getLayoutParams()); + int iconMargin = 0; + if (hasText && iconView.getVisibility() == VISIBLE) { + iconMargin = mIconTextGap != -1 ? mIconTextGap : (int) ViewUtils.dpToPx(getContext(), DEFAULT_GAP_TEXT_ICON); + } + if (iconMargin != MarginLayoutParamsCompat.getMarginEnd(lp)) { + MarginLayoutParamsCompat.setMarginEnd(lp, iconMargin); + lp.bottomMargin = 0; + iconView.setLayoutParams(lp); + iconView.requestLayout(); + if (textView != null) { + RelativeLayout.LayoutParams lp2 = (RelativeLayout.LayoutParams) textView.getLayoutParams(); + lp2.addRule(13, 0); + lp2.addRule(15, 1); + lp2.addRule(17, R.id.icon); + textView.setLayoutParams(lp2); + } + } + } + + final CharSequence contentDesc = tab != null ? tab.contentDesc : null; + if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP || VERSION.SDK_INT > VERSION_CODES.M) { + Tooltip.setTooltipText(this, contentDesc); + } + } + + @SuppressLint("UnsafeOptInUsageError") + private void tryUpdateBadgeDrawableBounds(@NonNull View anchor) { + if (hasBadgeDrawable() && anchor == badgeAnchorView) { + BadgeUtils.setBadgeDrawableBounds(badgeDrawable, anchor, getCustomParentForBadge(anchor)); + } + } + + private boolean hasBadgeDrawable() { + return badgeDrawable != null; + } + + @SuppressLint("UnsafeOptInUsageError") + @Nullable + private FrameLayout getCustomParentForBadge(@NonNull View anchor) { + if (anchor != iconView && anchor != textView) { + return null; + } + return BadgeUtils.USE_COMPAT_PARENT ? ((FrameLayout) anchor.getParent()) : null; + } + + int getContentWidth() { + boolean initialized = false; + int left = 0; + int right = 0; + + for (View view : new View[] {textView, iconView, customView}) { + if (view != null && view.getVisibility() == View.VISIBLE) { + left = initialized ? Math.min(left, view.getLeft()) : view.getLeft(); + right = initialized ? Math.max(right, view.getRight()) : view.getRight(); + initialized = true; + } + } + + return right - left; + } + + int getContentHeight() { + boolean initialized = false; + int top = 0; + int bottom = 0; + + for (View view : new View[] {textView, iconView, customView}) { + if (view != null && view.getVisibility() == View.VISIBLE) { + top = initialized ? Math.min(top, view.getTop()) : view.getTop(); + bottom = initialized ? Math.max(bottom, view.getBottom()) : view.getBottom(); + initialized = true; + } + } + + return bottom - top; + } + + @Nullable + public Tab getTab() { + return tab; + } + + private float approximateLineWidth(@NonNull Layout layout, int line, float textSize) { + return layout.getLineWidth(line) * (textSize / layout.getPaint().getTextSize()); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + mIconSize = getResources().getDimensionPixelOffset(R.dimen.sesl_tab_icon_size); + } + + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + if (mMainTabTouchBackground != null) { + mMainTabTouchBackground.setVisibility(enabled ? VISIBLE : GONE); + } + } + + @SuppressLint("RestrictedApi") + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + if (mMainTabTouchBackground != null) { + mMainTabTouchBackground.setLeft(0); + mMainTabTouchBackground.setRight(mTabParentView != null ? mTabParentView.getWidth() : r - l); + if (mMainTabTouchBackground.getAnimation() != null && mMainTabTouchBackground.getAnimation().hasEnded()) { + mMainTabTouchBackground.setAlpha(0.0f); + } + } + + if (iconView != null && tab.icon != null) { + if (textView != null && mIndicatorView != null && mTabParentView != null) { + int measuredWidth = mIconSize + textView.getMeasuredWidth(); + if (mIconTextGap != -1) { + measuredWidth += mIconTextGap; + } + + int offset = Math.abs((getWidth() - measuredWidth) / 2); + if (ViewUtils.isLayoutRtl(this)) { + if (iconView.getRight() == mTabParentView.getRight()) { + textView.offsetLeftAndRight(-offset); + iconView.offsetLeftAndRight(-offset); + mIndicatorView.offsetLeftAndRight(-offset); + } + } else if (iconView.getLeft() == this.mTabParentView.getLeft()) { + textView.offsetLeftAndRight(offset); + iconView.offsetLeftAndRight(offset); + mIndicatorView.offsetLeftAndRight(offset); + } + } + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (isEnabled()) { + return tab.getCustomView() != null ? super.onTouchEvent(event) : startTabTouchAnimation(event, null); + } else { + return super.onTouchEvent(event); + } + } + + private boolean startTabTouchAnimation(MotionEvent event, KeyEvent keyEvent) { + if (event != null && tab.getCustomView() == null && textView != null && (event != null || keyEvent != null) && (event == null || keyEvent == null)) { + final int action = event.getAction() & 255; + + switch (action) { + case MotionEvent.ACTION_DOWN: + mIsCallPerformClick = false; + if (tab.position != getSelectedTabPosition() && textView != null) { + textView.setTypeface(mBoldTypeface); + startTextColorChangeAnimation(textView, getSelectedTabTextColor()); + + if (mIndicatorView != null) { + mIndicatorView.setPressed(); + } + + final Tab tab = getTabAt(getSelectedTabPosition()); + if (tab != null) { + if (tab.view.textView != null) { + tab.view.textView.setTypeface(mNormalTypeface); + startTextColorChangeAnimation(tab.view.textView, tabTextColors.getDefaultColor()); + } + if (tab.view.mIndicatorView != null) { + tab.view.mIndicatorView.setHide(); + } + } + } else if (tab.position == getSelectedTabPosition() && mIndicatorView != null) { + mIndicatorView.setPressed(); + } + showMainTabTouchBackground(MotionEvent.ACTION_DOWN); + break; + case MotionEvent.ACTION_UP: + showMainTabTouchBackground(MotionEvent.ACTION_UP); + if (mIndicatorView != null) { + mIndicatorView.setReleased(); + mIndicatorView.onTouchEvent(event); + } + performClick(); + mIsCallPerformClick = true; + break; + case MotionEvent.ACTION_CANCEL: + textView.setTypeface(mNormalTypeface); + startTextColorChangeAnimation(textView, tabTextColors.getDefaultColor()); + + if (mIndicatorView != null && !mIndicatorView.isSelected()) { + mIndicatorView.setHide(); + } + + final Tab tab = getTabAt(getSelectedTabPosition()); + if (tab != null) { + if (tab.view.textView != null) { + tab.view.textView.setTypeface(mBoldTypeface); + startTextColorChangeAnimation(tab.view.textView, getSelectedTabTextColor()); + } + if (tab.view.mIndicatorView != null) { + tab.view.mIndicatorView.setShow(); + } + } + if (mDepthStyle == DEPTH_TYPE_MAIN) { + showMainTabTouchBackground(MotionEvent.ACTION_CANCEL); + } else { + if (mIndicatorView != null && mIndicatorView.isSelected()) { + mIndicatorView.setReleased(); + } + } + break; + } + + return super.onTouchEvent(event); + } + return false; + } + + private void showMainTabTouchBackground(int action) { + if (mMainTabTouchBackground != null && mDepthStyle == DEPTH_TYPE_MAIN && tabBackgroundResId == 0) { + mMainTabTouchBackground.setAlpha(1.0F); + + AnimationSet mainAnimation = new AnimationSet(true); + mainAnimation.setFillAfter(true); + + switch (action) { + case MotionEvent.ACTION_DOWN: + AlphaAnimation fadeIn = new AlphaAnimation(0.0F, 1.0F); + fadeIn.setDuration(100); + fadeIn.setFillAfter(true); + mainAnimation.addAnimation(fadeIn); + + ScaleAnimation scale = new ScaleAnimation(ANIM_RIPPLE_MINOR_SCALE, 1.0F, ANIM_RIPPLE_MINOR_SCALE, 1.0F, 1, 0.5F, 1, 0.5F); + scale.setDuration(ANIM_SHOW_DURATION); + scale.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); + scale.setFillAfter(true); + mainAnimation.addAnimation(scale); + + mMainTabTouchBackground.startAnimation(mainAnimation); + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + if (mMainTabTouchBackground.getAnimation() != null) { + if (mMainTabTouchBackground.getAnimation().hasEnded()) { + AlphaAnimation fadeOut = new AlphaAnimation(1.0f, 0.0f); + fadeOut.setDuration(ANIM_HIDE_DURATION); + fadeOut.setFillAfter(true); + mainAnimation.addAnimation(fadeOut); + + mMainTabTouchBackground.startAnimation(mainAnimation); + } else { + mMainTabTouchBackground.getAnimation().setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + AlphaAnimation fadeOut = new AlphaAnimation(1.0f, 0.0f); + fadeOut.setDuration(ANIM_HIDE_DURATION); + fadeOut.setFillAfter(true); + mMainTabTouchBackground.startAnimation(fadeOut); + } + }); + } + } + break; + } + } + } + } + + class SlidingTabIndicator extends LinearLayout { + ValueAnimator indicatorAnimator; + int selectedPosition = -1; + float selectionOffset; + private int layoutDirection = -1; + + SlidingTabIndicator(Context context) { + super(context); + setWillNotDraw(false); + } + + void setSelectedIndicatorHeight(int height) { + Rect bounds = tabSelectedIndicator.getBounds(); + tabSelectedIndicator.setBounds(bounds.left, 0, bounds.right, height); + this.requestLayout(); + } + + boolean childrenNeedLayout() { + for (int i = 0, z = getChildCount(); i < z; i++) { + final View child = getChildAt(i); + if (child.getWidth() <= 0) { + return true; + } + } + return false; + } + + void setIndicatorPositionFromTabPosition(int position, float positionOffset) { + if (indicatorAnimator != null && indicatorAnimator.isRunning()) { + indicatorAnimator.cancel(); + } + + selectedPosition = position; + selectionOffset = positionOffset; + + final View selectedTitle = getChildAt(selectedPosition); + final View nextTitle = getChildAt(selectedPosition + 1); + + tweenIndicatorPosition(selectedTitle, nextTitle, selectionOffset); + } + + float getIndicatorPosition() { + return selectedPosition + selectionOffset; + } + + @Override + public void onRtlPropertiesChanged(int layoutDirection) { + super.onRtlPropertiesChanged(layoutDirection); + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + if (this.layoutDirection != layoutDirection) { + requestLayout(); + this.layoutDirection = layoutDirection; + } + } + } + + // kang + @SuppressLint("RestrictedApi") + @Override + protected void onMeasure(int i, int i2) { + int i3; + super.onMeasure(i, i2); + if (View.MeasureSpec.getMode(i) == MeasureSpec.EXACTLY) { + int i4 = 0; + boolean z = true; + if (SamsungTabLayout.this.mode == 11 || SamsungTabLayout.this.mode == 12) { + SamsungTabLayout.this.checkOverScreen(); + if (SamsungTabLayout.this.mIsOverScreen) { + i3 = SamsungTabLayout.this.mOverScreenMaxWidth; + } else { + i3 = View.MeasureSpec.getSize(i); + } + int childCount = getChildCount(); + int[] iArr = new int[childCount]; + int i5 = 0; + for (int i6 = 0; i6 < childCount; i6++) { + View childAt = getChildAt(i6); + if (childAt.getVisibility() == VISIBLE) { + childAt.measure(View.MeasureSpec.makeMeasureSpec(SamsungTabLayout.this.tabMaxWidth, MeasureSpec.UNSPECIFIED), i2); + iArr[i6] = childAt.getMeasuredWidth() + (SamsungTabLayout.this.mTabMinSideSpace * 2); + i5 += iArr[i6]; + } + } + int i7 = i3 / childCount; + if (i5 > i3) { + while (i4 < childCount) { + ((LinearLayout.LayoutParams) getChildAt(i4).getLayoutParams()).width = iArr[i4]; + i4++; + } + } else { + if (SamsungTabLayout.this.mode == 11) { + int i8 = 0; + while (true) { + if (i8 >= childCount) { + z = false; + break; + } else if (iArr[i8] > i7) { + break; + } else { + i8++; + } + } + } + if (z) { + int i9 = (i3 - i5) / childCount; + while (i4 < childCount) { + ((LinearLayout.LayoutParams) getChildAt(i4).getLayoutParams()).width = iArr[i4] + i9; + i4++; + } + } else { + while (i4 < childCount) { + ((LinearLayout.LayoutParams) getChildAt(i4).getLayoutParams()).width = i7; + i4++; + } + } + } + if (i5 > i3) { + i3 = i5; + } + super.onMeasure(View.MeasureSpec.makeMeasureSpec(i3, MeasureSpec.EXACTLY), i2); + } else if (SamsungTabLayout.this.tabGravity == 1 || SamsungTabLayout.this.mode == 2 || SamsungTabLayout.this.mFirstTabGravity == 1) { + int childCount2 = getChildCount(); + if (SamsungTabLayout.this.tabGravity == 0 && SamsungTabLayout.this.mFirstTabGravity == 1) { + for (int i10 = 0; i10 < childCount2; i10++) { + View childAt2 = getChildAt(i10); + LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) childAt2.getLayoutParams(); + layoutParams.width = -2; + layoutParams.weight = 0.0f; + childAt2.measure(View.MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), i2); + } + } + int i11 = 0; + for (int i12 = 0; i12 < childCount2; i12++) { + View childAt3 = getChildAt(i12); + if (childAt3.getVisibility() == VISIBLE) { + i11 = Math.max(i11, childAt3.getMeasuredWidth()); + } + } + if (i11 > 0) { + if (i11 * childCount2 <= getMeasuredWidth() - (((int) ViewUtils.dpToPx(getContext(), 16)) * 2)) { + boolean z2 = false; + while (i4 < childCount2) { + LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) getChildAt(i4).getLayoutParams(); + if (layoutParams2.width != i11 || layoutParams2.weight != 0.0f) { + layoutParams2.width = i11; + layoutParams2.weight = 0.0f; + z2 = true; + } + i4++; + } + if (SamsungTabLayout.this.tabGravity == 0 && SamsungTabLayout.this.mFirstTabGravity == 1) { + SamsungTabLayout.this.tabGravity = GRAVITY_CENTER; + } + z = z2; + } else { + SamsungTabLayout.this.tabGravity = 0; + SamsungTabLayout.this.updateTabViews(false); + } + if (z) { + super.onMeasure(i, i2); + } + } + } + } + } + // kang + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + + if (indicatorAnimator != null && indicatorAnimator.isRunning()) { + updateOrRecreateIndicatorAnimation(false, selectedPosition, -1); + } else { + jumpIndicatorToSelectedPosition(); + } + } + + private void jumpIndicatorToSelectedPosition() { + } + + private void tweenIndicatorPosition(View startTitle, View endTitle, float fraction) { + boolean hasVisibleTitle = startTitle != null && startTitle.getWidth() > 0; + if (hasVisibleTitle) { + tabIndicatorInterpolator.setIndicatorBoundsForOffset(SamsungTabLayout.this, startTitle, endTitle, fraction, tabSelectedIndicator); + } else { + tabSelectedIndicator.setBounds(-1, tabSelectedIndicator.getBounds().top, -1, tabSelectedIndicator.getBounds().bottom); + } + + ViewCompat.postInvalidateOnAnimation(this); + } + + void animateIndicatorToPosition(final int position, int duration) { + } + + private void updateOrRecreateIndicatorAnimation(boolean recreateAnimation, final int position, int duration) { + } + + @Override + public void draw(@NonNull Canvas canvas) { + super.draw(canvas); + } + } + + @NonNull + private static ColorStateList createColorStateList(int defaultColor, int selectedColor) { + final int[][] states = new int[2][]; + final int[] colors = new int[2]; + int i = 0; + + states[i] = SELECTED_STATE_SET; + colors[i] = selectedColor; + i++; + + states[i] = EMPTY_STATE_SET; + colors[i] = defaultColor; + i++; + + return new ColorStateList(states, colors); + } + + @Dimension(unit = Dimension.DP) + private int getDefaultHeight() { + return mDepthStyle == DEPTH_TYPE_SUB ? SESL_SUB_DEPTH_DEFAULT_HEIGHT : SESL_DEFAULT_HEIGHT; + } + + private int getTabMinWidth() { + if (requestedTabMinWidth != INVALID_WIDTH) { + return requestedTabMinWidth; + } + return 0; + } + + @Override + public LayoutParams generateLayoutParams(AttributeSet attrs) { + return generateDefaultLayoutParams(); + } + + int getTabMaxWidth() { + return tabMaxWidth; + } + + public static class TabLayoutOnPageChangeListener implements SeslViewPager.OnPageChangeListener { + @NonNull private final WeakReference tabLayoutRef; + private int previousScrollState; + private int scrollState; + + public TabLayoutOnPageChangeListener(SamsungTabLayout tabLayout) { + tabLayoutRef = new WeakReference<>(tabLayout); + } + + @Override + public void onPageScrollStateChanged(final int state) { + previousScrollState = scrollState; + scrollState = state; + } + + @Override + public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) { + final SamsungTabLayout tabLayout = tabLayoutRef.get(); + if (tabLayout != null) { + final boolean updateText = scrollState != SCROLL_STATE_SETTLING || previousScrollState == SCROLL_STATE_DRAGGING; + final boolean updateIndicator = !(scrollState == SCROLL_STATE_SETTLING && previousScrollState == SCROLL_STATE_IDLE); + tabLayout.setScrollPosition(position, positionOffset, updateText, updateIndicator); + } + } + + @Override + public void onPageSelected(final int position) { + final SamsungTabLayout tabLayout = tabLayoutRef.get(); + if (tabLayout != null && tabLayout.getSelectedTabPosition() != position && position < tabLayout.getTabCount()) { + final boolean updateIndicator = scrollState == SCROLL_STATE_IDLE || (scrollState == SCROLL_STATE_SETTLING && previousScrollState == SCROLL_STATE_IDLE); + tabLayout.selectTab(tabLayout.getTabAt(position), updateIndicator); + } + } + + void reset() { + previousScrollState = scrollState = SCROLL_STATE_IDLE; + } + } + + public static class ViewPagerOnTabSelectedListener implements SamsungTabLayout.OnTabSelectedListener { + private final SeslViewPager viewPager; + + public ViewPagerOnTabSelectedListener(SeslViewPager viewPager) { + this.viewPager = viewPager; + } + + @Override + public void onTabSelected(@NonNull SamsungTabLayout.Tab tab) { + viewPager.setCurrentItem(tab.getPosition()); + } + + @Override + public void onTabUnselected(SamsungTabLayout.Tab tab) { + } + + @Override + public void onTabReselected(SamsungTabLayout.Tab tab) { + } + } + + private class PagerAdapterObserver extends DataSetObserver { + PagerAdapterObserver() {} + + @Override + public void onChanged() { + populateFromPagerAdapter(); + } + + @Override + public void onInvalidated() { + populateFromPagerAdapter(); + } + } + + private class AdapterChangeListener implements SeslViewPager.OnAdapterChangeListener { + private boolean autoRefresh; + + AdapterChangeListener() {} + + @Override + public void onAdapterChanged(@NonNull SeslViewPager viewPager, @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) { + if (SamsungTabLayout.this.viewPager == viewPager) { + setPagerAdapter(newAdapter, autoRefresh); + } + } + + void setAutoRefresh(boolean autoRefresh) { + this.autoRefresh = autoRefresh; + } + } + + public void seslSetSubTabStyle() { + if (mDepthStyle == DEPTH_TYPE_MAIN) { + mDepthStyle = DEPTH_TYPE_SUB; + + tabTextColors = getResources().getColorStateList(R.color.sesl_tablayout_subtab_text_color); + + if (tabs.size() > 0) { + int selectedTab = getSelectedTabPosition(); + ArrayList tabs = new ArrayList(this.tabs.size()); + + for (int i = 0; i < this.tabs.size(); i++) { + Tab tab = newTab(); + tab.text = this.tabs.get(i).text; + tab.icon = this.tabs.get(i).icon; + tab.customView = this.tabs.get(i).customView; + tab.subText = this.tabs.get(i).subText; + if (i == selectedTab) { + tab.select(); + } + tab.view.update(); + tabs.add(tab); + } + + removeAllTabs(); + + for (int i = 0; i < this.tabs.size(); i++) { + addTab((Tab) tabs.get(i), i == selectedTab); + if (this.tabs.get(i) != null) { + this.tabs.get(i).view.update(); + } + } + + tabs.clear(); + } + } + } + + // kang + private void updateBadgePosition() { + ArrayList var1 = this.tabs; + if (var1 != null && var1.size() != 0) { + for(int var2 = 0; var2 < this.tabs.size(); ++var2) { + SamsungTabLayout.Tab var11 = (SamsungTabLayout.Tab)this.tabs.get(var2); + SamsungTabLayout.TabView var3 = ((SamsungTabLayout.Tab)this.tabs.get(var2)).view; + if (var11 != null && var3 != null) { + Object var4 = var3.textView; + ImageView var5 = var3.iconView; + if (var3.getWidth() > 0) { + TextView var12 = null; + byte var6 = -1; + int var7; + int var8; + if (var3.mNBadgeView != null && var3.mNBadgeView.getVisibility() == VISIBLE) { + var12 = var3.mNBadgeView; + var7 = ((android.widget.RelativeLayout.LayoutParams)var12.getLayoutParams()).getMarginStart(); + var8 = this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_n_badge_xoffset); + var6 = 1; + } else if (var3.mDotBadgeView != null && var3.mDotBadgeView.getVisibility() == VISIBLE) { + var12 = var3.mDotBadgeView; + var7 = ((android.widget.RelativeLayout.LayoutParams)var12.getLayoutParams()).getMarginStart(); + var8 = this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_dot_badge_offset_x); + var6 = 2; + } else { + var8 = this.getContext().getResources().getDimensionPixelSize(R.dimen.sesl_tablayout_subtab_n_badge_xoffset); + var7 = 0; + } + + if (var12 != null && var12.getVisibility() == VISIBLE) { + var12.measure(0, 0); + int var9; + if (var6 == 1) { + var9 = var12.getMeasuredWidth(); + } else { + var9 = this.getResources().getDimensionPixelSize(R.dimen.sesl_tab_badge_dot_size); + } + + if (var4 == null || ((TextView)var4).getWidth() <= 0) { + var4 = var5; + } + + if (var4 == null) { + return; + } + + int var10; + int var14; + label70: { + var10 = var3.getWidth(); + if (var7 != 0) { + var14 = var7; + if (var7 >= ((View)var4).getRight()) { + break label70; + } + } + + var14 = ((View)var4).getRight() + var8; + } + + if (var14 > var10) { + var7 = var10 - var9; + } else { + var7 = var14 + var9; + if (var7 > var10) { + var7 = var14 - (var7 - var10); + } else { + var7 = var14; + if (var14 > ((View)var4).getRight() + var8) { + var7 = ((View)var4).getRight() + var8; + } + } + } + + var7 = Math.max(0, var7); + android.widget.RelativeLayout.LayoutParams var13 = (android.widget.RelativeLayout.LayoutParams)var12.getLayoutParams(); + var8 = var13.width; + if (var13.getMarginStart() != var7 || var8 != var9) { + var13.setMarginStart(var7); + var13.width = var9; + var12.setLayoutParams(var13); + } + } + } + } + } + } + } + // kang + + public void seslSetSubTabSelectedIndicatorColor(@ColorInt int color) { + mSubTabSelectedIndicatorColor = color; + setSelectedTabIndicatorColor(color); + } + + @Deprecated + public void seslSetTabTextColor(ColorStateList color, boolean refresh) { + if (tabTextColors != color) { + tabTextColors = color; + if (refresh) { + updateAllTabs(); + } else if (tabs != null) { + for (int i = 0; i < tabs.size(); i++) { + TabView tabView = tabs.get(i).view; + if (tabView != null && tabView.textView != null) { + tabView.textView.setTextColor(tabTextColors); + } + } + } + } + } + + public void seslSetBadgeColor(@ColorInt int color) { + mBadgeColor = color; + } + + public void seslSetBadgeTextColor(@ColorInt int color) { + mBadgeTextColor = color; + } + + public void seslSetTabWidth(int width) { + mRequestedTabWidth = width; + } + + private int getSelectedTabTextColor() { + if (tabTextColors != null) { + return tabTextColors.getColorForState(new int[]{android.R.attr.state_selected, android.R.attr.state_enabled}, tabTextColors.getDefaultColor()); + } + return Color.WHITE; + } + + private void startTextColorChangeAnimation(TextView textView, int color) { + if (textView != null) { + textView.setTextColor(color); + } + } + + public void checkMaxFontScale(TextView textView, int size) { + float fontScale = getResources().getConfiguration().fontScale; + if (textView != null && mIsScaledTextSizeType && fontScale > 1.3f) { + textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, (((float) size) / fontScale) * 1.3f); + } + } + + // kang + private void createAddBadge(int type, TabView tabView) { + if (tabView != null && tabView.mTabParentView != null) { + TextView textView = new TextView(getContext()); + Resources resources = getResources(); + int i2 = -1; + if (type == BADGE_TYPE_DOT) { + if (tabView.mDotBadgeView == null) { + textView.setVisibility(GONE); + ViewCompat.setBackground(textView, resources.getDrawable(R.drawable.sesl_dot_badge)); + textView.setId(R.id.sesl_badge_dot); + int dimensionPixelSize = resources.getDimensionPixelSize(R.dimen.sesl_tab_badge_dot_size); + RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(dimensionPixelSize, dimensionPixelSize); + if (tabView.textView != null) { + i2 = tabView.textView.getWidth(); + } + if (i2 > 0 || tabView.iconView == null || tabView.iconView.getVisibility() != VISIBLE) { + layoutParams.addRule(6, R.id.title); + } else { + layoutParams.addRule(6, R.id.icon); + } + textView.setMinHeight(dimensionPixelSize); + textView.setMinWidth(dimensionPixelSize); + tabView.mTabParentView.addView(textView, layoutParams); + tabView.mDotBadgeView = textView; + } + } else if (tabView.mNBadgeView == null) { + textView.setVisibility(GONE); + textView.setMinWidth(resources.getDimensionPixelSize(R.dimen.sesl_tab_badge_number_min_width)); + textView.setTextSize(1, BADGE_N_TEXT_SIZE); + textView.setGravity(17); + textView.setTextColor(resources.getColor(R.color.sesl_badge_text_color)); + ViewCompat.setBackground(textView, resources.getDrawable(R.drawable.sesl_tab_n_badge)); + textView.setId(R.id.sesl_badge_n); + textView.setMaxLines(1); + RelativeLayout.LayoutParams layoutParams2 = new RelativeLayout.LayoutParams(-2, resources.getDimensionPixelSize(R.dimen.sesl_tab_badge_number_height)); + if (tabView.textView != null) { + i2 = tabView.textView.getWidth(); + } + if (i2 > 0 || tabView.iconView == null || tabView.iconView.getVisibility() != VISIBLE) { + layoutParams2.addRule(6, R.id.title); + } else { + layoutParams2.addRule(6, R.id.icon); + } + layoutParams2.setMargins(0, -resources.getDimensionPixelSize(R.dimen.sesl_tab_badge_offset_y), 0, 0); + tabView.mTabParentView.addView(textView, layoutParams2); + tabView.mNBadgeView = textView; + } + } + } + // kang + + public void seslShowDotBadge(int index, boolean show) { + if (tabs.get(index) != null && tabs.get(index).view != null) { + TabView tabView = tabs.get(index).view; + + if (tabView.mDotBadgeView == null) { + createAddBadge(BADGE_TYPE_DOT, tabView); + } + + if (tabView.mDotBadgeView != null) { + if (show) { + tabView.mDotBadgeView.setVisibility(VISIBLE); + if (mBadgeColor != -1) { + DrawableCompat.setTint(tabView.mDotBadgeView.getBackground(), mBadgeColor); + } + updateBadgePosition(); + } else { + tabView.mDotBadgeView.setVisibility(GONE); + } + } + } + } + + public void seslShowBadge(int index, boolean show, String text) { + seslShowBadge(index, show, text, null); + } + + public void seslShowBadge(int index, boolean show, String text, String contentDescription) { + if (mDepthStyle != DEPTH_TYPE_SUB && tabs.get(index) != null && tabs.get(index).view != null) { + TabView tabView = tabs.get(index).view; + + if (tabView.mNBadgeView == null) { + createAddBadge(BADGE_TYPE_N, tabView); + } + + if (tabView.mNBadgeView != null) { + tabView.mNBadgeView.setText(text); + if (show) { + tabView.mNBadgeView.setVisibility(VISIBLE); + + if (mBadgeColor != -1) { + DrawableCompat.setTint(tabView.mNBadgeView.getBackground(), mBadgeColor); + } + if (mBadgeTextColor != -1) { + tabView.mNBadgeView.setTextColor(mBadgeTextColor); + } + if (contentDescription != null) { + tabView.mNBadgeView.setContentDescription(contentDescription); + } + + updateBadgePosition(); + tabView.mNBadgeView.requestLayout(); + } else { + tabView.mNBadgeView.setVisibility(GONE); + } + } + } else { + Log.w(LOG_TAG, "seslShowBadge not supported with DEPTH_TYPE_SUB"); + } + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + updateBadgePosition(); + } + + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + + for (int i = 0; i < getTabCount(); i++) { + Tab tab = getTabAt(i); + if (tab != null && tab.view != null && tab.view.mMainTabTouchBackground != null) { + tab.view.mMainTabTouchBackground.setAlpha(0.0f); + } + } + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + + for (int i = 0; i < getTabCount(); i++) { + Tab tab = getTabAt(i); + if (tab != null && tab.view != null && tab.view.mMainTabTouchBackground != null) { + tab.view.mMainTabTouchBackground.setAlpha(0.0f); + } + } + + updateBadgePosition(); + } + + public void seslSetSubTabIndicatorHeight(int height) { + mSubTabIndicatorHeight = height; + } + + public void seslSetIconTextGap(int gap) { + mIconTextGap = gap; + updateAllTabs(); + } + + public void seslSetTabSubTextColors(ColorStateList color) { + if (mSubTabSubTextColors != color) { + mSubTabSubTextColors = color; + updateAllTabs(); + } + } + + public ColorStateList seslGetTabSubTextColors() { + return mSubTabSubTextColors; + } + + public void seslSetTabSubTextColors(int defaultColor, int selectedColor) { + seslSetTabSubTextColors(createColorStateList(defaultColor, selectedColor)); + } + + private int seslGetSelectedTabSubTextColor() { + ColorStateList colorStateList = this.mSubTabSubTextColors; + if (colorStateList != null) { + return colorStateList.getColorForState(new int[]{16842913, 16842910}, colorStateList.getDefaultColor()); + } + return -1; + } + + // kang + private void checkOverScreen() { + int measuredWidth = getMeasuredWidth(); + if (measuredWidth > ((int) (((float) getResources().getInteger(R.integer.sesl_tablayout_over_screen_width_dp)) * (((float) getContext().getResources().getDisplayMetrics().densityDpi) / 160.0f)))) { + mIsOverScreen = true; + mOverScreenMaxWidth = (int) (ResourcesCompat.getFloat(getResources(), R.dimen.sesl_tablayout_over_screen_max_width_rate) * ((float) measuredWidth)); + } else { + mIsOverScreen = false; + } + } + // kang +} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/AbsIndicatorView.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslAbsIndicatorView.java similarity index 70% rename from yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/AbsIndicatorView.java rename to yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslAbsIndicatorView.java index 90092dae..7c763f9d 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/AbsIndicatorView.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslAbsIndicatorView.java @@ -4,33 +4,33 @@ import android.util.AttributeSet; import android.view.View; -public abstract class AbsIndicatorView extends View { - public AbsIndicatorView(Context context) { +abstract class SeslAbsIndicatorView extends View { + abstract void onHide(); + + abstract void onSetSelectedIndicatorColor(int i); + + abstract void onShow(); + + abstract void startPressEffect(); + + abstract void startReleaseEffect(); + + public SeslAbsIndicatorView(Context context) { super(context); } - public AbsIndicatorView(Context context, AttributeSet attrs) { + public SeslAbsIndicatorView(Context context, AttributeSet attrs) { super(context, attrs); } - public AbsIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) { + public SeslAbsIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } - public AbsIndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + public SeslAbsIndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } - abstract void onHide(); - - abstract void onSetSelectedIndicatorColor(int i); - - abstract void onShow(); - - abstract void startPressEffect(); - - abstract void startReleaseEffect(); - public void setSelectedIndicatorColor(int color) { onSetSelectedIndicatorColor(color); } diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabDotLineIndicator.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabDotLineIndicator.java similarity index 54% rename from yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabDotLineIndicator.java rename to yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabDotLineIndicator.java index 8c29ecde..52b3cd48 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabDotLineIndicator.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabDotLineIndicator.java @@ -5,35 +5,40 @@ import android.graphics.Paint; import android.graphics.drawable.ColorDrawable; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.util.TypedValue; -public class TabDotLineIndicator extends AbsIndicatorView { - private final float mScaleFromDiff; - private int mDiameter; - private int mInterval; +public class SeslTabDotLineIndicator extends SeslAbsIndicatorView { + private static final float CIRCLE_INTERVAL = 2.5f; + private static final float DIAMETER_SIZE = 2.5f; + private static final int SCALE_DIFF = 5; + private final int mDiameter; + private final int mInterval; private Paint mPaint; private float mScaleFrom; + private final float mScaleFromDiff; private int mWidth; - public TabDotLineIndicator(Context context) { + public SeslTabDotLineIndicator(Context context) { this(context, null); } - public TabDotLineIndicator(Context context, AttributeSet attrs) { + public SeslTabDotLineIndicator(Context context, AttributeSet attrs) { this(context, attrs, 0); } - public TabDotLineIndicator(Context context, AttributeSet attrs, int defStyleAttr) { + public SeslTabDotLineIndicator(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } - public TabDotLineIndicator(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); + public SeslTabDotLineIndicator(Context context, AttributeSet attributeSet, int defStyleAttr, int defStyleRes) { + super(context, attributeSet, defStyleAttr, defStyleRes); - mDiameter = (int) TypedValue.applyDimension(1, 2.5f, context.getResources().getDisplayMetrics()); - mInterval = (int) TypedValue.applyDimension(1, 2.5f, context.getResources().getDisplayMetrics()); + DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - mScaleFromDiff = TypedValue.applyDimension(1, 5.0f, context.getResources().getDisplayMetrics()); + mDiameter = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CIRCLE_INTERVAL, displayMetrics); + mInterval = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DIAMETER_SIZE, displayMetrics); + mScaleFromDiff = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, SCALE_DIFF, displayMetrics); mPaint = new Paint(); mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); @@ -76,14 +81,18 @@ void onSetSelectedIndicatorColor(int color) { mPaint.setColor(color); } + // kang @Override - public void onDraw(Canvas canvas) { + protected void onDraw(Canvas canvas) { super.onDraw(canvas); + updateDotLineScaleFrom(); if ((isPressed() || isSelected()) && (getBackground() instanceof ColorDrawable)) { int width = (getWidth() - getPaddingStart()) - getPaddingEnd(); float height = ((float) getHeight()) / 2.0f; - canvas.drawRoundRect(0.0f, height - (((float) mDiameter) / 2.0f), (float) width, height + (((float) mDiameter) / 2.0f), (float) mDiameter, (float) mDiameter, this.mPaint); + float f = ((float) mDiameter) / 2.0f; + canvas.drawRoundRect(0.0f, height - f, (float) width, height + f, (float) mDiameter, (float) mDiameter, this.mPaint); } } + // kang } diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabRoundRectIndicator.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabRoundRectIndicator.java new file mode 100644 index 00000000..7cf061c9 --- /dev/null +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/SeslTabRoundRectIndicator.java @@ -0,0 +1,140 @@ +package de.dlyt.yanndroid.oneui.sesl.tabs; + +import android.content.Context; +import android.graphics.PorterDuff; +import android.graphics.drawable.NinePatchDrawable; +import android.os.Build; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.AlphaAnimation; +import android.view.animation.Animation; +import android.view.animation.AnimationSet; +import android.view.animation.ScaleAnimation; + +import androidx.appcompat.animation.SeslAnimationUtils; +import androidx.core.content.ContextCompat; +import androidx.core.view.ViewCompat; + +import de.dlyt.yanndroid.oneui.R; + +public class SeslTabRoundRectIndicator extends SeslAbsIndicatorView { + private boolean mIsOneUI4; + private static final int DURATION_PRESS = 50; + private static final int DURATION_RELEASE = 350; + private static final float SCALE_MINOR = 0.95f; + private AnimationSet mPressAnimationSet; + + public SeslTabRoundRectIndicator(Context context) { + this(context, null); + } + + public SeslTabRoundRectIndicator(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SeslTabRoundRectIndicator(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public SeslTabRoundRectIndicator(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + mIsOneUI4 = context.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); + ViewCompat.setBackground(this, ContextCompat.getDrawable(context, mIsOneUI4 ? R.drawable.sesl4_tablayout_subtab_indicator_background : R.drawable.sesl_tablayout_subtab_indicator_background)); + onSetSelectedIndicatorColor(getResources().getColor(mIsOneUI4 ? R.color.sesl4_tablayout_subtab_background_stroke_color : R.color.sesl_tablayout_subtab_background_stroke_color)); + } + + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + if (visibility != VISIBLE && !isSelected()) { + onHide(); + } + } + + @Override + void onHide() { + AlphaAnimation alpha = new AlphaAnimation(0.0f, 0.0f); + alpha.setDuration(0); + alpha.setFillAfter(true); + startAnimation(alpha); + setAlpha(0.0f); + } + + @Override + void onShow() { + setAlpha(1.0f); + AlphaAnimation alpha = new AlphaAnimation(1.0f, 1.0f); + alpha.setDuration(0); + alpha.setFillAfter(true); + startAnimation(alpha); + } + + @Override + void startPressEffect() { + setAlpha(1.0f); + + mPressAnimationSet = new AnimationSet(false); + mPressAnimationSet.setStartOffset(DURATION_PRESS); + mPressAnimationSet.setFillAfter(true); + mPressAnimationSet.setAnimationListener(new Animation.AnimationListener() { + @Override + public void onAnimationStart(Animation animation) { + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + + @Override + public void onAnimationEnd(Animation animation) { + mPressAnimationSet = null; + } + }); + + ScaleAnimation scale = new ScaleAnimation(1.0f, SCALE_MINOR, 1.0f, SCALE_MINOR, 1, 0.5f, 1, 0.5f); + scale.setDuration(DURATION_PRESS); + scale.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); + scale.setFillAfter(true); + mPressAnimationSet.addAnimation(scale); + + if (!isSelected()) { + AlphaAnimation alpha = new AlphaAnimation(0.0f, 1.0f); + alpha.setDuration(DURATION_PRESS); + alpha.setFillAfter(true); + alpha.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); + mPressAnimationSet.addAnimation(alpha); + } + + startAnimation(mPressAnimationSet); + } + + @Override + void startReleaseEffect() { + setAlpha(1.0f); + + AnimationSet set = new AnimationSet(false); + set.setFillAfter(true); + + ScaleAnimation scale = new ScaleAnimation(SCALE_MINOR, 1.0f, SCALE_MINOR, 1.0f, 1, 0.5f, 1, 0.5f); + scale.setDuration(DURATION_RELEASE); + scale.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); + scale.setFillAfter(true); + set.addAnimation(scale); + + startAnimation(set); + } + + @Override + void onSetSelectedIndicatorColor(int color) { + if (!(getBackground() instanceof NinePatchDrawable)) { + if (Build.VERSION.SDK_INT >= 22) { + getBackground().setTint(color); + } else { + getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN); + } + if (!isSelected()) { + setHide(); + } + } + } +} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabIndicatorInterpolator.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabIndicatorInterpolator.java new file mode 100644 index 00000000..70b95aca --- /dev/null +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabIndicatorInterpolator.java @@ -0,0 +1,64 @@ +package de.dlyt.yanndroid.oneui.sesl.tabs; + +import android.annotation.SuppressLint; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; +import android.view.View; +import androidx.annotation.Dimension; +import androidx.annotation.FloatRange; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.google.android.material.animation.AnimationUtils; +import com.google.android.material.internal.ViewUtils; + +import de.dlyt.yanndroid.oneui.sesl.tabs.SamsungTabLayout.TabView; + +class TabIndicatorInterpolator { + @Dimension(unit = Dimension.DP) + private static final int MIN_INDICATOR_WIDTH = 24; + + @SuppressLint("RestrictedApi") + static RectF calculateTabViewContentBounds(@NonNull TabView tabView, @Dimension(unit = Dimension.DP) int minWidth) { + int tabViewContentWidth = tabView.getContentWidth(); + int tabViewContentHeight = tabView.getContentHeight(); + int minWidthPx = (int) ViewUtils.dpToPx(tabView.getContext(), minWidth); + + if (tabViewContentWidth < minWidthPx) { + tabViewContentWidth = minWidthPx; + } + + int tabViewCenterX = (tabView.getLeft() + tabView.getRight()) / 2; + int tabViewCenterY = (tabView.getTop() + tabView.getBottom()) / 2; + int contentLeftBounds = tabViewCenterX - (tabViewContentWidth / 2); + int contentTopBounds = tabViewCenterY - (tabViewContentHeight / 2); + int contentRightBounds = tabViewCenterX + (tabViewContentWidth / 2); + int contentBottomBounds = tabViewCenterY + (tabViewCenterX / 2); + + return new RectF(contentLeftBounds, contentTopBounds, contentRightBounds, contentBottomBounds); + } + + static RectF calculateIndicatorWidthForTab(SamsungTabLayout tabLayout, @Nullable View tab) { + if (tab == null) { + return new RectF(); + } + + if (!tabLayout.isTabIndicatorFullWidth() && tab instanceof TabView) { + return calculateTabViewContentBounds((TabView) tab, MIN_INDICATOR_WIDTH); + } + + return new RectF(tab.getLeft(), tab.getTop(), tab.getRight(), tab.getBottom()); + } + + void setIndicatorBoundsForTab(SamsungTabLayout tabLayout, View tab, @NonNull Drawable indicator) { + RectF startIndicator = calculateIndicatorWidthForTab(tabLayout, tab); + indicator.setBounds((int) startIndicator.left, indicator.getBounds().top, (int) startIndicator.right, indicator.getBounds().bottom); + } + + @SuppressLint("RestrictedApi") + void setIndicatorBoundsForOffset(SamsungTabLayout tabLayout, View startTitle, View endTitle, @FloatRange(from = 0.0, to = 1.0) float offset, @NonNull Drawable indicator) { + RectF startIndicator = calculateIndicatorWidthForTab(tabLayout, startTitle); + RectF endIndicator = calculateIndicatorWidthForTab(tabLayout, endTitle); + indicator.setBounds(AnimationUtils.lerp((int) startIndicator.left, (int) endIndicator.left, offset), indicator.getBounds().top, AnimationUtils.lerp((int) startIndicator.right, (int) endIndicator.right, offset), indicator.getBounds().bottom); + } +} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabItem.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabItem.java index 96d8a2b2..98819277 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabItem.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabItem.java @@ -3,30 +3,30 @@ import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.Drawable; +import androidx.appcompat.widget.TintTypedArray; import android.util.AttributeSet; import android.view.View; -import androidx.appcompat.widget.TintTypedArray; - import de.dlyt.yanndroid.oneui.R; public class TabItem extends View { - public final CharSequence text; - public final Drawable icon; - public final int customLayout; + public final CharSequence text; + public CharSequence mSubText; + public final Drawable icon; + public final int customLayout; - public TabItem(Context context) { - this(context, null); - } + public TabItem(Context context) { + this(context, null); + } - @SuppressLint("RestrictedApi") - public TabItem(Context context, AttributeSet attrs) { - super(context, attrs); + @SuppressLint("RestrictedApi") + public TabItem(Context context, AttributeSet attrs) { + super(context, attrs); - final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.TabItem); - text = a.getText(R.styleable.TabItem_android_text); - icon = a.getDrawable(R.styleable.TabItem_android_icon); - customLayout = a.getResourceId(R.styleable.TabItem_android_layout, 0); - a.recycle(); - } -} \ No newline at end of file + final TintTypedArray a = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.TabItem); + text = a.getText(R.styleable.TabItem_android_text); + icon = a.getDrawable(R.styleable.TabItem_android_icon); + customLayout = a.getResourceId(R.styleable.TabItem_android_layout, 0); + a.recycle(); + } +} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabRoundRectIndicator.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabRoundRectIndicator.java deleted file mode 100644 index 7bcf9333..00000000 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/sesl/tabs/TabRoundRectIndicator.java +++ /dev/null @@ -1,124 +0,0 @@ -package de.dlyt.yanndroid.oneui.sesl.tabs; - -import android.content.Context; -import android.graphics.PorterDuff; -import android.graphics.drawable.NinePatchDrawable; -import android.util.AttributeSet; -import android.view.View; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.view.animation.AnimationSet; -import android.view.animation.ScaleAnimation; - -import androidx.appcompat.animation.SeslAnimationUtils; -import androidx.core.content.ContextCompat; -import androidx.core.view.ViewCompat; - -import de.dlyt.yanndroid.oneui.R; - -public class TabRoundRectIndicator extends AbsIndicatorView { - private boolean mIsOneUI4; - private AnimationSet mPressAnimationSet; - - public TabRoundRectIndicator(Context context) { - this(context, null); - } - - public TabRoundRectIndicator(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public TabRoundRectIndicator(Context context, AttributeSet attrs, int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } - - public TabRoundRectIndicator(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - mIsOneUI4 = context.getTheme().obtainStyledAttributes(new int[]{R.attr.isOneUI4}).getBoolean(0, false); - ViewCompat.setBackground(this, ContextCompat.getDrawable(context, mIsOneUI4 ? R.drawable.sesl4_tablayout_subtab_indicator_background : R.drawable.sesl_tablayout_subtab_indicator_background)); - } - - @Override - protected void onVisibilityChanged(View changedView, int visibility) { - super.onVisibilityChanged(changedView, visibility); - if (visibility != 0 && !isSelected()) { - onHide(); - } - } - - @Override - void onHide() { - AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 0.0f); - alphaAnimation.setDuration(0); - alphaAnimation.setFillAfter(true); - startAnimation(alphaAnimation); - setAlpha(0.0f); - } - - @Override - void onShow() { - setAlpha(1.0f); - AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 1.0f); - alphaAnimation.setDuration(0); - alphaAnimation.setFillAfter(true); - startAnimation(alphaAnimation); - } - - @Override - void startPressEffect() { - setAlpha(1.0f); - mPressAnimationSet = new AnimationSet(false); - mPressAnimationSet.setStartOffset(50); - mPressAnimationSet.setFillAfter(true); - mPressAnimationSet.setAnimationListener(new Animation.AnimationListener() { - public void onAnimationStart(Animation animation) { - } - - public void onAnimationRepeat(Animation animation) { - } - - public void onAnimationEnd(Animation animation) { - mPressAnimationSet = null; - } - }); - - ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.95f, 1.0f, 0.95f, 1, 0.5f, 1, 0.5f); - scaleAnimation.setDuration(50); - scaleAnimation.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); - scaleAnimation.setFillAfter(true); - mPressAnimationSet.addAnimation(scaleAnimation); - - if (!isSelected()) { - AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f); - alphaAnimation.setDuration(50); - alphaAnimation.setFillAfter(true); - alphaAnimation.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); - mPressAnimationSet.addAnimation(alphaAnimation); - } - - startAnimation(mPressAnimationSet); - } - - @Override - void startReleaseEffect() { - setAlpha(1.0f); - AnimationSet animationSet = new AnimationSet(false); - animationSet.setFillAfter(true); - ScaleAnimation scaleAnimation = new ScaleAnimation(0.95f, 1.0f, 0.95f, 1.0f, 1, 0.5f, 1, 0.5f); - scaleAnimation.setDuration(350); - scaleAnimation.setInterpolator(SeslAnimationUtils.SINE_IN_OUT_80); - scaleAnimation.setFillAfter(true); - animationSet.addAnimation(scaleAnimation); - startAnimation(animationSet); - } - - @Override - void onSetSelectedIndicatorColor(int color) { - if (!(getBackground() instanceof NinePatchDrawable)) { - getBackground().setColorFilter(color, PorterDuff.Mode.SRC_IN); - if (!isSelected()) { - setHide(); - } - } - } -} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/utils/CustomButtonClickListener.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/utils/CustomButtonClickListener.java index 9a4d0d5b..6cff91b2 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/utils/CustomButtonClickListener.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/utils/CustomButtonClickListener.java @@ -3,13 +3,13 @@ import android.view.MotionEvent; import android.view.View; -import de.dlyt.yanndroid.oneui.widget.BottomNavigationView; +import de.dlyt.yanndroid.oneui.widget.TabLayout; public abstract class CustomButtonClickListener implements View.OnTouchListener { - private BottomNavigationView mBnv; + private TabLayout mTabLayout; - public CustomButtonClickListener(BottomNavigationView bnv) { - mBnv = bnv; + public CustomButtonClickListener(TabLayout tabLayout) { + mTabLayout = tabLayout; } @Override @@ -22,7 +22,7 @@ public boolean onTouch(View v, MotionEvent ev) { case MotionEvent.ACTION_UP: v.setPressed(false); onClick(v); - mBnv.fullScroll(mBnv.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? View.FOCUS_LEFT : View.FOCUS_RIGHT); + mTabLayout.fullScroll(mTabLayout.getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL ? View.FOCUS_LEFT : View.FOCUS_RIGHT); break; case MotionEvent.ACTION_CANCEL: v.setPressed(false); diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/BottomNavigationView.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/BottomNavigationView.java deleted file mode 100644 index 8803631b..00000000 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/BottomNavigationView.java +++ /dev/null @@ -1,201 +0,0 @@ -package de.dlyt.yanndroid.oneui.widget; - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Point; -import android.graphics.drawable.Drawable; -import android.provider.Settings; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.view.Display; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; -import android.widget.TextView; - -import androidx.reflect.content.res.SeslConfigurationReflector; - -import java.util.ArrayList; - -import de.dlyt.yanndroid.oneui.R; -import de.dlyt.yanndroid.oneui.sesl.support.ViewSupport; -import de.dlyt.yanndroid.oneui.sesl.support.WindowManagerSupport; -import de.dlyt.yanndroid.oneui.sesl.tabs.SamsungBaseTabLayout; -import de.dlyt.yanndroid.oneui.utils.CustomButtonClickListener; - -public class BottomNavigationView extends SamsungBaseTabLayout implements View.OnSystemUiVisibilityChangeListener { - private Activity mActivity; - private boolean mIsResumed = false; - - public BottomNavigationView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.bottomNaviViewStyle); - } - - public BottomNavigationView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - mDepthStyle = 1; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - invalidateTabLayout(); - } - - @Override - public void onSystemUiVisibilityChange(int visibility) { - if (mIsResumed) { - invalidateTabLayout(); - } - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - - for (int tabPosition = 0; tabPosition < getTabCount(); tabPosition++) { - ViewGroup tabView = (ViewGroup) getTabView(tabPosition); - if (tabView != null) { - tabView.setEnabled(enabled); - tabView.setAlpha(enabled ? 1.0f : 0.4f); - } - } - } - - public void addTabCustomButton(Drawable icon, CustomButtonClickListener listener) { - Tab tab = newTab().setIcon(icon).setIsCustomButtonView(true); - addTab(tab); - ((ViewGroup) getTabView(tab.getPosition())).setOnTouchListener(listener); - } - - public void setResumeStatus(boolean isResumed) { - mIsResumed = isResumed; - } - - public void updateWidget(Activity activity) { - mActivity = activity; - invalidateTabLayout(); - } - - private void invalidateTabLayout() { - ArrayList tabTextWidthList = new ArrayList<>(); - float tabTextWidthSum = 0.0f; - for (int tabPosition = 0; tabPosition < getTabCount(); tabPosition++) { - Tab tab = getTabAt(tabPosition); - ViewGroup tabView = (ViewGroup) getTabView(tabPosition); - float width = 0.0f; - - if (tab.getIsCustomButtonView()) { - width = tab.getIcon().getIntrinsicWidth(); - tabView.setBackground(getContext().getDrawable(R.drawable.oui_bottomnavview_button_background)); - } else - width = getTabTextWidth(tab.seslGetTextView()); - - tabTextWidthList.add(width); - tabTextWidthSum += width; - ViewSupport.setPointerIcon(tabView, 1000 /* PointerIcon.TYPE_ARROW */); - } - if (tabTextWidthSum >= getContext().getResources().getDisplayMetrics().widthPixels) { - setTabMode(0); - } - addTabPaddingValue(tabTextWidthList, tabTextWidthSum); - } - - private float getTabTextWidth(TextView textView) { - return textView.getPaint().measureText(textView.getText().toString()); - } - - private void addTabPaddingValue(ArrayList tabTextWidthList, float tabTextWidthSum) { - float tabTextPadding = (float) getResources().getDimensionPixelSize(R.dimen.bnv_padding); - float tabTextPaddingSum = tabTextPadding * 8.0f; - float tabLayoutPadding = (float) getResources().getDimensionPixelSize(R.dimen.tab_layout_padding); - - Window window = mActivity.getWindow(); - Point size = new Point(); - if (isVisibleNaviBar(getContext()) || WindowManagerSupport.isMultiWindowMode(mActivity) || isInSamsungDeXMode(getContext())) { - window.getWindowManager().getDefaultDisplay().getSize(size); - } else { - window.getWindowManager().getDefaultDisplay().getRealSize(size); - } - - float screenWidthPixels = (float) size.x; - if (!isMultiWindowMinSize(mActivity, 480, true)) { - float tabLayoutPaddingMax = screenWidthPixels * 0.125f; - float tabLayoutPaddingMin = ((screenWidthPixels - tabTextWidthSum) - tabTextPaddingSum) / 2.0f; - if (tabLayoutPaddingMin >= tabLayoutPaddingMax) { - tabLayoutPadding = tabLayoutPaddingMax; - } else if (tabLayoutPadding < tabLayoutPaddingMin) { - tabLayoutPadding = tabLayoutPaddingMin; - } - } - - float widthPixels = screenWidthPixels - (2.0f * tabLayoutPadding); - if (tabTextWidthSum + tabTextPaddingSum < widthPixels) { - float paddingLeftRight = (float) Math.ceil((double) (((widthPixels - (tabTextWidthSum + tabTextPaddingSum)) / 8.0f) + tabTextPadding)); - float paddingLastTab = (widthPixels - tabTextWidthSum) - (8.0f * paddingLeftRight); - for (int i = 0; i < tabTextWidthList.size(); i++) { - if (paddingLastTab == 0.0f || i != 3) { - getTabView(i).setMinimumWidth((int) ((float) tabTextWidthList.get(i) + (2.0f * paddingLeftRight))); - } else { - getTabView(i).setMinimumWidth((int) ((float) tabTextWidthList.get(i) + (2.0f * paddingLeftRight) + paddingLastTab)); - } - } - } else { - for (int i2 = 0; i2 < tabTextWidthList.size(); i2++) { - getTabView(i2).setMinimumWidth((int) ((float) tabTextWidthList.get(i2) + (2.0f * tabTextPadding))); - } - } - - ((MarginLayoutParams) getLayoutParams()).setMargins((int) tabLayoutPadding, 0, (int) tabLayoutPadding, 0); - requestLayout(); - } - - private View getTabView(int position) { - ViewGroup viewGroup = getTabViewGroup(); - if (viewGroup == null || viewGroup.getChildCount() <= position) { - return null; - } - return viewGroup.getChildAt(position); - } - - private ViewGroup getTabViewGroup() { - if (getChildCount() <= 0) { - return null; - } - View view = getChildAt(0); - if (view == null || !(view instanceof ViewGroup)) { - return null; - } - return (ViewGroup) view; - } - - private double getDensity(Context context) { - Configuration configuration = context.getResources().getConfiguration(); - DisplayMetrics metrics = new DisplayMetrics(); - WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - Display display = windowManager == null ? null : windowManager.getDefaultDisplay(); - if (display != null) { - display.getRealMetrics(metrics); - } - if (display == null) { - return 1.0d; - } - return ((double) configuration.densityDpi) / ((double) metrics.densityDpi); - } - - private boolean isInSamsungDeXMode(Context context) { - return SeslConfigurationReflector.isDexEnabled(context.getResources().getConfiguration()); - } - - private boolean isMultiWindowMinSize(Context context, int minSizeDp, boolean isWidth) { - Configuration configuration = context.getResources().getConfiguration(); - return ((int) (((double) (isWidth ? configuration.screenWidthDp : configuration.screenHeightDp)) * getDensity(context))) <= minSizeDp; - } - - private boolean isVisibleNaviBar(Context context) { - return Settings.Global.getInt(context.getContentResolver(), "navigationbar_hide_bar_enabled", 0) == 0; - } - -} diff --git a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/TabLayout.java b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/TabLayout.java index 4a797232..497e5983 100644 --- a/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/TabLayout.java +++ b/yanndroid/oneui/src/main/java/de/dlyt/yanndroid/oneui/widget/TabLayout.java @@ -1,31 +1,72 @@ package de.dlyt.yanndroid.oneui.widget; import android.content.Context; +import android.content.ContextWrapper; import android.content.res.Configuration; +import android.graphics.Point; +import android.graphics.drawable.Drawable; +import android.provider.Settings; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import android.view.WindowManager; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.reflect.content.res.SeslConfigurationReflector; + import de.dlyt.yanndroid.oneui.R; -import de.dlyt.yanndroid.oneui.sesl.tabs.SamsungBaseTabLayout; +import de.dlyt.yanndroid.oneui.sesl.support.WindowManagerSupport; +import de.dlyt.yanndroid.oneui.sesl.tabs.SamsungTabLayout; +import de.dlyt.yanndroid.oneui.sesl.utils.ReflectUtils; +import de.dlyt.yanndroid.oneui.utils.CustomButtonClickListener; + +public class TabLayout extends SamsungTabLayout { + private Context mContext; + public float mScreenWidthPixels; + public float mTabLayoutPaddingMax; + public float mTabTextPadding; + public float mTabTextPaddingSum; -public class TabLayout extends SamsungBaseTabLayout { + public TabLayout(@NonNull Context context) { + this(context, null); + } - public TabLayout(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.tabLayoutStyle); + public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs) { + this(context, attrs, R.attr.tabStyle); } - public TabLayout(Context context, AttributeSet attrs, int defStyleAttr) { + public TabLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - mDepthStyle = 2; + mContext = context; + + Point point = new Point(); + WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); + if (isVisibleNaviBar() || SeslConfigurationReflector.isDexEnabled(getResources().getConfiguration()) || WindowManagerSupport.isMultiWindowMode(getActivity())) { + wm.getDefaultDisplay().getSize(point); + } else { + wm.getDefaultDisplay().getRealSize(point); + } + mScreenWidthPixels = (float) point.x; + + mTabTextPadding = getResources().getDimension(R.dimen.tab_layout_default_padding); + mTabTextPaddingSum = mTabTextPadding * 8.0f; + mTabLayoutPaddingMax = mScreenWidthPixels * 0.125f; } @Override - public void onConfigurationChanged(Configuration newConfig) { + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + setTabLayoutMargin(); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - updateWidget(); + setTabLayoutMargin(); } @Override @@ -41,128 +82,98 @@ public void setEnabled(boolean enabled) { } } - public void updateWidget() { - Float[] tabCount = new Float[getTabCount()]; - float f = 0.0f; - for (int i = 0; i < getTabCount(); i++) { - TabLayout.Tab tab = getTabAt(i); - if (tab != null) { - tabCount[i] = getTabTextWidth(tab.seslGetTextView()); - f += tabCount[i]; - } + public float calculateTabLayoutPadding(float textWidthSum, float padding) { + Configuration config = mContext.getResources().getConfiguration(); + int screenWidthDp = config.screenWidthDp; + + if (isDisplayDeviceTypeSub(config) && config.orientation == Configuration.ORIENTATION_PORTRAIT) { + return padding / 2.0f; + } + if (screenWidthDp <= 480) { + return padding; + } + + float tabLayoutPaddingMin = ((mScreenWidthPixels - textWidthSum) - mTabTextPaddingSum) / 2.0f; + if (tabLayoutPaddingMin < mTabLayoutPaddingMax) { + return padding < tabLayoutPaddingMin ? tabLayoutPaddingMin : padding; + } else { + return mTabLayoutPaddingMax; } - float tabLayoutPadding = (float) getResources().getDimensionPixelSize(R.dimen.tab_layout_padding); - ((MarginLayoutParams) getLayoutParams()).setMargins((int) tabLayoutPadding, 0, (int) tabLayoutPadding, 0); - setViewDimens(tabCount, f); - post(new Runnable() { - public final void run() { - setSelectedTabScrollPosition(); - } - }); } - private View getTabView(int position) { - ViewGroup viewGroup = getTabViewGroup(); - if (viewGroup == null || viewGroup.getChildCount() <= position) { - return null; + private AppCompatActivity getActivity() { + Context context = getContext(); + while (context instanceof ContextWrapper) { + if (context instanceof AppCompatActivity) { + return (AppCompatActivity) context; + } + context = ((ContextWrapper) context).getBaseContext(); } - return viewGroup.getChildAt(position); + return null; + } + + private float getTabTextWidth(TextView textView) { + return textView.getPaint().measureText(textView.getText().toString()); } private ViewGroup getTabViewGroup() { if (getChildCount() <= 0) { return null; } + View view = getChildAt(0); - if (view == null || !(view instanceof ViewGroup)) { - return null; + if (view != null && view instanceof ViewGroup) { + return (ViewGroup) view; } - return (ViewGroup) view; + return null; } - private void setSelectedTabScrollPosition() { - setScrollPosition(getSelectedTabPosition(), 0.0f, true); + private View getTabView(int position) { + ViewGroup viewGroup = getTabViewGroup(); + if (viewGroup != null && viewGroup.getChildCount() > position) { + return viewGroup.getChildAt(position); + } + return null; } - private float getTabTextWidth(TextView textView) { - return textView.getPaint().measureText(textView.getText().toString()); + private boolean isDisplayDeviceTypeSub(Configuration config) { + if (config == null) { + return false; + } + + Object displayDeviceType = ReflectUtils.genericGetField(Configuration.class, config, "semDisplayDeviceType"); + if (displayDeviceType != null) { + return ((int) displayDeviceType) == 5; /* Configuration.SEM_DISPLAY_DEVICE_TYPE_SUB */ + } else { + return false; + } } - // kang from com.samsung.android.messaging - private void setViewDimens(Float[] fArr, float f) { - int i; - int tabCount = getTabCount(); - if (tabCount > 0) { - int dimensionPixelSize = getResources().getDimensionPixelSize(R.dimen.tablayout_start_end_margin); - i = getDisplayWidth(getContext()); - int i2 = i - (dimensionPixelSize * 2); - float dimensionPixelSize2 = (float) getResources().getDimensionPixelSize(R.dimen.tablayout_text_padding); - float f2 = (float) i2; - float f3 = f2 / ((float) tabCount); - float f4 = dimensionPixelSize2 * 2.0f; - float f5 = (0.75f * f2) - f4; - float f6 = 0.0f; - int i3 = 0; - int i4 = 0; - for (int i5 = 0; i5 < tabCount; i5++) { - Log.d("TabLayout", "i : " + i5 + ", width : " + fArr[i5]); - if (f5 < fArr[i5].floatValue()) { - i3 = (int) (((float) i3) + (fArr[i5].floatValue() - f5)); - fArr[i5] = Float.valueOf(f5); - i4++; - f6 = f5; - } else if (f6 < fArr[i5].floatValue()) { - f6 = fArr[i5].floatValue(); - } - } - float f7 = f - ((float) i3); - setTabMode(0); - Log.d("TabLayout", "[MODE_SCROLLABLE]"); - Log.d("TabLayout", "availableContentWidth : " + i2 + ", tabTextPaddingLeftRight : " + dimensionPixelSize2); - ViewGroup viewGroup = (ViewGroup) getChildAt(0); - int i6 = (tabCount - i4) * 2; - int i7 = i6 > 0 ? ((int) ((f2 - f7) - ((((float) i4) * dimensionPixelSize2) * 2.0f))) / i6 : 0; - int i8 = (int) dimensionPixelSize2; - int i9 = -1; - boolean z = true; - if (i7 < i8) { - i7 = i8; - } else { - float f8 = f6 + dimensionPixelSize2 + dimensionPixelSize2; - if (f3 >= f8) { - setTabMode(1); - for (int i10 = 0; i10 < tabCount; i10++) { - ((ViewGroup) viewGroup.getChildAt(i10)).getChildAt(0).getLayoutParams().width = -1; - getTabAt(i10).seslGetTextView().setMaxWidth(i2); - getTabAt(i10).seslGetTextView().setMinimumWidth(0); - getTabAt(i10).seslGetTextView().setPadding(0, 0, 0, 0); - } - Log.d("TabLayout", "[MODE_FIXED] TabCount : " + tabCount + ", minNeededTabWidth : " + f3 + ", maxTabWidth : " + f8); - return; - } - } - int i11 = 0; - while (i11 < tabCount) { - boolean z2 = fArr[i11].floatValue() >= f5 ? z : false; - int floatValue = (int) (fArr[i11].floatValue() + ((z2 ? dimensionPixelSize2 : (float) i7) * 2.0f)); - ViewGroup.LayoutParams layoutParams = viewGroup.getChildAt(i11).getLayoutParams(); - layoutParams.width = floatValue; - layoutParams.height = i9; - viewGroup.getChildAt(i11).setMinimumWidth(floatValue); - int i12 = z2 ? 0 : (int) (((float) i7) - dimensionPixelSize2); - getTabAt(i11).seslGetTextView().setMaxWidth((int) f5); - getTabAt(i11).seslGetTextView().setMinimumWidth(floatValue - ((int) f4)); - getTabAt(i11).seslGetTextView().setPadding(i12, 0, i12, 0); - Log.d("TabLayout", "params.width : " + layoutParams.width + ", tabWidthList[" + i11 + "] : " + fArr[i11] + ", LeftRightPadding : " + (i7 * 2)); - i11++; - i9 = -1; - z = true; - } - requestLayout(); + private boolean isVisibleNaviBar() { + return Settings.Global.getInt(mContext.getContentResolver(), "navigationbar_hide_bar_enabled", 0) == 0; + } + + private void setTabLayoutMargin() { + float tabTextWidthSum = 0.0f; + for (int i = 0; i < getTabCount(); i++) { + final Tab tab = getTabAt(i); + tabTextWidthSum += getTabTextWidth(tab.seslGetTextView()); } + + final int margin = (int) calculateTabLayoutPadding(tabTextWidthSum, mTabTextPadding); + ((ViewGroup.MarginLayoutParams) getLayoutParams()).setMargins(margin, 0, margin, 0); } - private int getDisplayWidth(Context context) { - return context.getResources().getDisplayMetrics().widthPixels; + public void addTabCustomButton(Drawable icon, CustomButtonClickListener listener) { + if (mDepthStyle != 2) { + Tab tab = newTab().setIcon(icon); + addTab(tab); + + ViewGroup view = ((ViewGroup) getTabView(tab.getPosition())); + view.setBackground(getContext().getDrawable(R.drawable.oui_tablayout_custombutton_background)); + view.setOnTouchListener(listener); + } else { + Log.w("TabLayout", "addTabCustomButton not supported with DEPTH_TYPE_SUB"); + } } -} \ No newline at end of file +} diff --git a/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_indicator_color.xml b/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_indicator_color.xml index eb075071..b1e297f6 100644 --- a/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_indicator_color.xml +++ b/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_indicator_color.xml @@ -1,4 +1,5 @@ - - + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_text_color.xml b/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_text_color.xml index 59555dfa..b0a1cd07 100644 --- a/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_text_color.xml +++ b/yanndroid/oneui/src/main/res/color/sesl4_tablayout_selected_text_color.xml @@ -1,4 +1,5 @@ - - + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_indicator_color.xml b/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_indicator_color.xml index ab5d3066..c61c2347 100644 --- a/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_indicator_color.xml +++ b/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_indicator_color.xml @@ -1,4 +1,5 @@ - + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_text_color.xml b/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_text_color.xml index ab5d3066..c61c2347 100644 --- a/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_text_color.xml +++ b/yanndroid/oneui/src/main/res/color/sesl_tablayout_selected_text_color.xml @@ -1,4 +1,5 @@ - + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_sub_text_color.xml b/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_sub_text_color.xml new file mode 100644 index 00000000..903147e3 --- /dev/null +++ b/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_sub_text_color.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_text_color.xml b/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_text_color.xml old mode 100755 new mode 100644 index 7ee94f40..83c8b69a --- a/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_text_color.xml +++ b/yanndroid/oneui/src/main/res/color/sesl_tablayout_subtab_text_color.xml @@ -1,6 +1,7 @@ - - - - - + + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/color/sesl_tablayout_text_color.xml b/yanndroid/oneui/src/main/res/color/sesl_tablayout_text_color.xml old mode 100755 new mode 100644 index eae01ae5..92bda88f --- a/yanndroid/oneui/src/main/res/color/sesl_tablayout_text_color.xml +++ b/yanndroid/oneui/src/main/res/color/sesl_tablayout_text_color.xml @@ -1,5 +1,6 @@ - - - - + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_maintab_touch_background.xml b/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_maintab_touch_background.xml index 3d7c0bd4..d92ef67c 100644 --- a/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_maintab_touch_background.xml +++ b/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_maintab_touch_background.xml @@ -1,5 +1,6 @@ - + diff --git a/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_subtab_indicator_ripple.xml b/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_subtab_indicator_ripple.xml index a83ba028..d740bf9b 100644 --- a/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_subtab_indicator_ripple.xml +++ b/yanndroid/oneui/src/main/res/drawable-night/sesl_tablayout_subtab_indicator_ripple.xml @@ -1,7 +1,6 @@ - + diff --git a/yanndroid/oneui/src/main/res/drawable-xxhdpi/sesl_tab_n_badge_mtrl.9.png b/yanndroid/oneui/src/main/res/drawable-xxhdpi/sesl_tab_n_badge_mtrl.9.png new file mode 100644 index 0000000000000000000000000000000000000000..e754a046628a12417295432915fb4e5875d2921d GIT binary patch literal 776 zcmV+j1NZ!iP)h)W4tJMA#Y>FKTKm?;J*MI_ z^!rz-1X4Ed(NnK-mzjz^Dq*p-zjGbdKT>F#6CJlJ!`auJgLuhQ>OL`USH^r#rwvN{ z@G6ACv6H?yqU;EG&oc;25r+8)V;B+_^C>GT*<}m^BA5BvN3iJ$w6@6qqc9~U4w(ue@X(dv z>|<$o=O%>s-w)$Xi_*ZM{41ux4zT7-VvgwMd~-xMJD(%EbrdD?&9<8umM8 zrcftd0L}8;_*wVbBo}5CnH?)OJqRA--FZWXK2=a(R1UM=FO`omm`_kY(fn)bn|3z1 z-j9P7c=tZ0)vw9Q%)En{F09Pdc1rFvAjCy!QQEKzEQSB|Y(d1)rm>O$0000 - + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_dot_badge.xml b/yanndroid/oneui/src/main/res/drawable/sesl_dot_badge.xml new file mode 100644 index 00000000..9c64456d --- /dev/null +++ b/yanndroid/oneui/src/main/res/drawable/sesl_dot_badge.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tab_n_badge.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tab_n_badge.xml new file mode 100644 index 00000000..9967691f --- /dev/null +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tab_n_badge.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_indicator_opentheme_background.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_indicator_opentheme_background.xml index 01e5e1f4..40070582 100644 --- a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_indicator_opentheme_background.xml +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_indicator_opentheme_background.xml @@ -1,3 +1,3 @@ - - \ No newline at end of file + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_touch_background.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_touch_background.xml index fc19d548..b67bbf3e 100644 --- a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_touch_background.xml +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_maintab_touch_background.xml @@ -1,5 +1,6 @@ - + diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_background.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_background.xml index 1a4692eb..55b2c3cf 100644 --- a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_background.xml +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_background.xml @@ -1,5 +1,6 @@ - - - - + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_ripple.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_ripple.xml index ccd7c6f4..8e16a709 100644 --- a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_ripple.xml +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_ripple.xml @@ -1,7 +1,6 @@ - + diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_shape.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_shape.xml index 84fc9319..5bb0a06c 100644 --- a/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_shape.xml +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tablayout_subtab_indicator_shape.xml @@ -1,9 +1,7 @@ - - - - - + + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/drawable/sesl_tabs_default_indicator.xml b/yanndroid/oneui/src/main/res/drawable/sesl_tabs_default_indicator.xml index c2fd5594..e88fabec 100644 --- a/yanndroid/oneui/src/main/res/drawable/sesl_tabs_default_indicator.xml +++ b/yanndroid/oneui/src/main/res/drawable/sesl_tabs_default_indicator.xml @@ -1,5 +1,6 @@ - + diff --git a/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_icon.xml b/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_icon.xml new file mode 100644 index 00000000..e984e601 --- /dev/null +++ b/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_icon.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_sub_text.xml b/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_sub_text.xml new file mode 100644 index 00000000..4a9193ed --- /dev/null +++ b/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_sub_text.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_text.xml b/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_text.xml new file mode 100644 index 00000000..4a9193ed --- /dev/null +++ b/yanndroid/oneui/src/main/res/layout/sesl_layout_tab_text.xml @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/layout/sesl_tabs_main_tab_layout.xml b/yanndroid/oneui/src/main/res/layout/sesl_tabs_main_tab_layout.xml index 7f0e462d..1dbb9aa4 100644 --- a/yanndroid/oneui/src/main/res/layout/sesl_tabs_main_tab_layout.xml +++ b/yanndroid/oneui/src/main/res/layout/sesl_tabs_main_tab_layout.xml @@ -1,37 +1,8 @@ - - - - - - - - - + + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/layout/sesl_tabs_sub_tab_layout.xml b/yanndroid/oneui/src/main/res/layout/sesl_tabs_sub_tab_layout.xml index 988437b8..521d3d2e 100644 --- a/yanndroid/oneui/src/main/res/layout/sesl_tabs_sub_tab_layout.xml +++ b/yanndroid/oneui/src/main/res/layout/sesl_tabs_sub_tab_layout.xml @@ -1,19 +1,8 @@ - - - - - + + + + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/values-night/colors.xml b/yanndroid/oneui/src/main/res/values-night/colors.xml index 9a42699e..1165fae2 100644 --- a/yanndroid/oneui/src/main/res/values-night/colors.xml +++ b/yanndroid/oneui/src/main/res/values-night/colors.xml @@ -124,17 +124,18 @@ - #252525 - #99FFFFFF - #999999 - #33A8A9A9 - #FFFFFF - #A8A9A9 - #66A8A9A9 - #1AFFFFFF - #FAFAFA - #FAFAFA - + #fffafafa + #99ffffff + #ffffffff + #1affffff + #ff909090 + #ff3e91ff + #ff999999 + #33999999 + #ffe5e5e5 + #ff999999 + #66999999 + #fffafafa #ffe5e5e5 diff --git a/yanndroid/oneui/src/main/res/values/attrs.xml b/yanndroid/oneui/src/main/res/values/attrs.xml index a0b85fda..3068cb5d 100644 --- a/yanndroid/oneui/src/main/res/values/attrs.xml +++ b/yanndroid/oneui/src/main/res/values/attrs.xml @@ -16,9 +16,6 @@ - - - @@ -167,31 +164,31 @@ - - + + - - - + + + - - + + - - - - - + + + + + - + @@ -223,36 +220,45 @@ - + - - - - + + + + + - - - - - + + - + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + diff --git a/yanndroid/oneui/src/main/res/values/colors.xml b/yanndroid/oneui/src/main/res/values/colors.xml index 99d902c1..857870f1 100644 --- a/yanndroid/oneui/src/main/res/values/colors.xml +++ b/yanndroid/oneui/src/main/res/values/colors.xml @@ -198,17 +198,21 @@ - #FAFAFA - #FAFAFA - #717171 - #858585 - #66858585 - #252525 - #858585 - #66858585 - #0D000000 - #010101 - #252525 + #ffef5e16 + @color/sesl_white + #ff252525 + #ff717171 + #ff000000 + #0d000000 + #ff909090 + #66858585 + #ff0072de + #ff8c8c8c + #668c8c8c + #ff252525 + #ff8c8c8c + #668c8c8c + #ff010101 #ff505050 diff --git a/yanndroid/oneui/src/main/res/values/dimens.xml b/yanndroid/oneui/src/main/res/values/dimens.xml index 691d241e..6369bfed 100644 --- a/yanndroid/oneui/src/main/res/values/dimens.xml +++ b/yanndroid/oneui/src/main/res/values/dimens.xml @@ -260,21 +260,28 @@ + 6.0dip + 17.0dip + 17.0dip + 6.0dip + 24.0dip 0.0dip + 10.0dip 72.0dip + 12.0sp 15.0sp 12.0sp + 0.75 4.0dip + 50.0dip 36.0dip - 18.0dip + 23.0dip 1.0dip 3.0dip 12.0dip - 24.0dip - 8.0dip - 24.0dip - 24.0dip - 12.0dip + 24.0dip + + 48.0dip @@ -451,7 +458,6 @@ 16.0sp - 2.0dip 38.0sp 14.0sp diff --git a/yanndroid/oneui/src/main/res/values/ids.xml b/yanndroid/oneui/src/main/res/values/ids.xml index bcaf8ae0..b54cf488 100644 --- a/yanndroid/oneui/src/main/res/values/ids.xml +++ b/yanndroid/oneui/src/main/res/values/ids.xml @@ -3,4 +3,6 @@ + + \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/values/integer.xml b/yanndroid/oneui/src/main/res/values/integer.xml index 4ffdadc2..e9a65f95 100644 --- a/yanndroid/oneui/src/main/res/values/integer.xml +++ b/yanndroid/oneui/src/main/res/values/integer.xml @@ -7,5 +7,6 @@ 100 100 100 + 480 \ No newline at end of file diff --git a/yanndroid/oneui/src/main/res/values/strings.xml b/yanndroid/oneui/src/main/res/values/strings.xml index ae1dfe94..c466a759 100644 --- a/yanndroid/oneui/src/main/res/values/strings.xml +++ b/yanndroid/oneui/src/main/res/values/strings.xml @@ -1,6 +1,9 @@ closed opened + sans-serif + sans-serif-light + sec-roboto-light sec-roboto-light de.dlyt.yanndroid.oneui.sesl.appbar.SamsungAppBarLayout$ScrollingViewBehavior diff --git a/yanndroid/oneui/src/main/res/values/styles.xml b/yanndroid/oneui/src/main/res/values/styles.xml index 0a9ebaf1..b9e5feb3 100644 --- a/yanndroid/oneui/src/main/res/values/styles.xml +++ b/yanndroid/oneui/src/main/res/values/styles.xml @@ -78,8 +78,7 @@ @style/AppBarLayoutStyle @style/CollapsingToolbarLayoutStyle - @style/BaseTabLayoutStyle - @style/TabLayoutStyle + @style/TabLayoutStyle @style/PreferenceThemeStyle @@ -593,13 +592,13 @@ - - @@ -936,7 +939,7 @@ @drawable/sesl4_list_go_to_top - @style/OneUI4.BaseTabLayoutStyle + @style/OneUI4.TabLayoutStyle @@ -1055,7 +1058,7 @@ - From 430b3ab89b31b04614c9d8bb1119dff167c22d98 Mon Sep 17 00:00:00 2001 From: BlackMesa123 Date: Wed, 26 Jan 2022 16:43:56 +0100 Subject: [PATCH 2/2] app/oneuiexample: tablayout badge demo Signed-off-by: BlackMesa123 --- .../java/de/dlyt/yanndroid/oneuiexample/MainActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java index 0b3b7e7d..f2e7ae92 100644 --- a/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java +++ b/app/src/main/java/de/dlyt/yanndroid/oneuiexample/MainActivity.java @@ -204,6 +204,7 @@ private void setCurrentItem() { drawerLayout.getToolbarMenu().findItem(R.id.search).setVisible(true); drawerLayout.setImmersiveScroll(false); ((androidx.drawerlayout.widget.DrawerLayout) drawerLayout.findViewById(R.id.drawerLayout)).setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_UNLOCKED); + tabLayout.seslShowDotBadge(1, true); } else { // MainActivitySecondFragment drawerLayout.setSubtitle("Preferences"); @@ -211,8 +212,8 @@ private void setCurrentItem() { drawerLayout.getToolbarMenu().findItem(R.id.search).setVisible(false); drawerLayout.setImmersiveScroll(true); ((androidx.drawerlayout.widget.DrawerLayout) drawerLayout.findViewById(R.id.drawerLayout)).setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED); + tabLayout.seslShowDotBadge(1, false); } - } } } @@ -359,6 +360,7 @@ private void popupView(View view) { @Override public boolean onMenuItemClick(MenuItem item) { item.setBadge(item.getBadge() + 1); + tabLayout.seslShowBadge(2, true, String.valueOf(item.getBadge())); return true; }