Handle insets

This commit is contained in:
NekoInverter committed 2021-01-24 17:30:31 +08:00
1 parent 4fd2b94812
commit a52e579b9a
17 files changed
+375 -134

No files matched your search

@@ -49,7 +49,9 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -1534,4 +1536,20 @@ public class DownloadsScene extends ToolbarScene
}
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
if (mRecyclerView != null) {
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), insets1.bottom);
}
if (mFabLayout != null) {
int corner_fab_margin = getResources().getDimensionPixelOffset(R.dimen.corner_fab_margin);
mFabLayout.setPadding(mFabLayout.getPaddingLeft(), mFabLayout.getPaddingTop(), corner_fab_margin + insets1.right, corner_fab_margin + insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
@@ -23,6 +23,7 @@ import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.text.TextUtils;
@@ -32,6 +33,9 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -39,6 +43,8 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.WindowInsetsCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -81,6 +87,7 @@ import com.hippo.widget.FabLayout;
import com.hippo.widget.SearchBarMover;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.ObjectUtils;
import com.hippo.yorozuya.SimpleHandler;
import com.hippo.yorozuya.ViewUtils;
@@ -107,6 +114,8 @@ public class FavoritesScene extends BaseScene implements
public int current; // -1 for error
public int limit; // -1 for error
@Nullable
private ContentLayout mContentLayout;
@Nullable
@ViewLifeCircle
private EasyRecyclerView mRecyclerView;
@Nullable
@@ -245,14 +254,57 @@ public class FavoritesScene extends BaseScene implements
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_favorites, container, false);
ContentLayout contentLayout = view.findViewById(R.id.content_layout);
mContentLayout = view.findViewById(R.id.content_layout);
MainActivity activity = getMainActivity();
AssertUtils.assertNotNull(activity);
mDrawerLayout = (EhDrawerLayout) ViewUtils.$$(activity, R.id.draw_view);
mRecyclerView = contentLayout.getRecyclerView();
FastScroller fastScroller = contentLayout.getFastScroller();
mRecyclerView = mContentLayout.getRecyclerView();
FastScroller fastScroller = mContentLayout.getFastScroller();
mSearchBar = (SearchBar) ViewUtils.$$(view, R.id.search_bar);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
view.setWindowInsetsAnimationCallback(new WindowInsetsAnimation.Callback(WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP) {
int startBottomFabLayout = 0;
int endBottomFabLayout = 0;
WindowInsetsAnimation animation;
@Override
public void onPrepare(@NonNull WindowInsetsAnimation animation) {
this.animation = animation;
if (mFabLayout != null) {
startBottomFabLayout = mFabLayout.getPaddingBottom();
}
}
@NonNull
@Override
public WindowInsetsAnimation.Bounds onStart(@NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) {
this.animation = animation;
if (mFabLayout != null) {
endBottomFabLayout = mFabLayout.getPaddingBottom();
mFabLayout.setTranslationY(-(startBottomFabLayout - endBottomFabLayout));
}
return bounds;
}
@NonNull
@Override
public WindowInsets onProgress(@NonNull WindowInsets insets, @NonNull List<WindowInsetsAnimation> runningAnimations) {
if (mFabLayout != null) {
int offset = MathUtils.lerp(-(startBottomFabLayout - endBottomFabLayout), 0, animation.getInterpolatedFraction());
mFabLayout.setTranslationY(offset);
}
return insets;
}
@Override
public void onEnd(@NonNull WindowInsetsAnimation animation) {
startBottomFabLayout = 0;
endBottomFabLayout = 0;
this.animation = null;
}
});
}
Context context = getContext();
AssertUtils.assertNotNull(context);
@@ -261,9 +313,9 @@ public class FavoritesScene extends BaseScene implements
mHelper = new FavoritesHelper();
mHelper.setEmptyString(resources.getString(R.string.gallery_list_empty_hit));
contentLayout.setHelper(mHelper);
contentLayout.getFastScroller().setOnDragHandlerListener(this);
contentLayout.setFitPaddingTop(paddingTopSB);
mContentLayout.setHelper(mHelper);
mContentLayout.getFastScroller().setOnDragHandlerListener(this);
mContentLayout.setFitPaddingTop(paddingTopSB);
mAdapter = new FavoritesAdapter(inflater, resources, mRecyclerView, Settings.getListMode());
mRecyclerView.setClipToPadding(false);
@@ -1331,4 +1383,23 @@ public class FavoritesScene extends BaseScene implements
}
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
if (mSearchBar != null) {
int gallery_search_bar_margin_v = getResources().getDimensionPixelOffset(R.dimen.gallery_search_bar_margin_v);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mSearchBar.getLayoutParams();
layoutParams.topMargin = insets1.top + gallery_search_bar_margin_v;
}
if (mContentLayout != null) {
mContentLayout.setTopInsets(insets1.top);
mContentLayout.setFitPaddingBottom(insets1.bottom);
}
if (mFabLayout != null) {
int corner_fab_margin = getResources().getDimensionPixelOffset(R.dimen.corner_fab_margin);
mFabLayout.setPadding(mFabLayout.getPaddingLeft(), mFabLayout.getPaddingTop(), corner_fab_margin + insets1.right, corner_fab_margin + insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
@@ -51,6 +51,7 @@ import androidx.core.text.util.LinkifyCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
@@ -68,7 +69,6 @@ import com.hippo.ehviewer.client.data.GalleryCommentList;
import com.hippo.ehviewer.client.data.GalleryDetail;
import com.hippo.ehviewer.client.parser.VoteCommentParser;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.refreshlayout.RefreshLayout;
import com.hippo.scene.SceneFragment;
import com.hippo.text.Html;
import com.hippo.text.URLImageGetter;
@@ -92,7 +92,7 @@ import java.util.ArrayList;
import java.util.List;
public final class GalleryCommentsScene extends ToolbarScene
implements View.OnClickListener, RefreshLayout.OnRefreshListener {
implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
public static final String TAG = GalleryCommentsScene.class.getSimpleName();
@@ -126,7 +126,7 @@ public final class GalleryCommentsScene extends ToolbarScene
private CommentAdapter mAdapter;
@Nullable
private ViewTransition mViewTransition;
private RefreshLayout mRefreshLayout;
private SwipeRefreshLayout mRefreshLayout;
private Drawable mSendDrawable;
private Drawable mPencilDrawable;
private long mCommentId;
@@ -193,22 +193,16 @@ public final class GalleryCommentsScene extends ToolbarScene
mEditText = (EditText) ViewUtils.$$(mEditPanel, R.id.edit_text);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
mFab = (FloatingActionButton) ViewUtils.$$(view, R.id.fab);
mRefreshLayout = (RefreshLayout) ViewUtils.$$(view, R.id.refresh_layout);
mRefreshLayout = (SwipeRefreshLayout) ViewUtils.$$(view, R.id.refresh_layout);
mRefreshLayout.setHeaderColorSchemeResources(
mRefreshLayout.setColorSchemeResources(
R.color.loading_indicator_red,
R.color.loading_indicator_purple,
R.color.loading_indicator_blue,
R.color.loading_indicator_cyan,
R.color.loading_indicator_green,
R.color.loading_indicator_yellow);
mRefreshLayout.setFooterColorSchemeResources(
R.color.loading_indicator_red,
R.color.loading_indicator_blue,
R.color.loading_indicator_green,
R.color.loading_indicator_orange);
mRefreshLayout.setOnRefreshListener(this);
mRefreshLayout.setEnableSwipeFooter(false);
Context context = requireContext();
Resources resources = getResources();
@@ -643,7 +637,7 @@ public final class GalleryCommentsScene extends ToolbarScene
return;
}
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setRefreshing(false);
mRefreshingComments = false;
mCommentList = result;
mAdapter.notifyDataSetChanged();
@@ -660,7 +654,7 @@ public final class GalleryCommentsScene extends ToolbarScene
return;
}
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setRefreshing(false);
mRefreshingComments = false;
int position = mAdapter.getItemCount() - 1;
if (position >= 0) {
@@ -725,7 +719,7 @@ public final class GalleryCommentsScene extends ToolbarScene
}
@Override
public void onHeaderRefresh() {
public void onRefresh() {
if (!mRefreshingComments && mAdapter != null) {
MainActivity activity = (MainActivity) requireActivity();
mRefreshingComments = true;
@@ -742,11 +736,6 @@ public final class GalleryCommentsScene extends ToolbarScene
}
}
@Override
public void onFooterRefresh() {
}
private static class RefreshCommentListener extends EhCallback<GalleryCommentsScene, GalleryDetail> {
public RefreshCommentListener(Context context, int stageId, String sceneTag) {
@@ -44,6 +44,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
@@ -60,7 +61,9 @@ import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.transition.TransitionInflater;
@@ -162,7 +165,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
private ViewTransition mViewTransition;
// Header
@Nullable
private View mHeader;
private FrameLayout mHeader;
@Nullable
private View mColorBg;
@Nullable
@@ -535,7 +538,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
mTip.setCompoundDrawables(null, drawable, null, null);
mTip.setOnClickListener(this);
mHeader = ViewUtils.$$(mainView, R.id.header);
mHeader = (FrameLayout) ViewUtils.$$(mainView, R.id.header);
mColorBg = ViewUtils.$$(mHeader, R.id.color_bg);
mThumb = (LoadImageView) ViewUtils.$$(mHeader, R.id.thumb);
mTitle = (TextView) ViewUtils.$$(mHeader, R.id.title);
@@ -2188,4 +2191,17 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
EhApplication.getEhClient(context).execute(request);
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
if (mHeader != null) {
mHeader.findViewById(R.id.header_content).setPadding(0, insets1.top, 0, 0);
}
if (mPreviews != null) {
int keylineMargin = getResources().getDimensionPixelOffset(R.dimen.keyline_margin);
mPreviews.setPadding(keylineMargin, keylineMargin, keylineMargin, keylineMargin + insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
@@ -39,6 +39,7 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -51,6 +52,8 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.WindowInsetsCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -155,6 +158,8 @@ public final class GalleryListScene extends BaseScene
View life cycle
---------------*/
@Nullable
private ContentLayout mContentLayout;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private SearchLayout mSearchLayout;
@@ -554,9 +559,9 @@ public final class GalleryListScene extends BaseScene
mShowActionFab = true;
View mainLayout = ViewUtils.$$(view, R.id.main_layout);
ContentLayout contentLayout = (ContentLayout) ViewUtils.$$(mainLayout, R.id.content_layout);
mRecyclerView = contentLayout.getRecyclerView();
FastScroller fastScroller = contentLayout.getFastScroller();
mContentLayout = (ContentLayout) ViewUtils.$$(mainLayout, R.id.content_layout);
mRecyclerView = mContentLayout.getRecyclerView();
FastScroller fastScroller = mContentLayout.getFastScroller();
mSearchLayout = (SearchLayout) ViewUtils.$$(mainLayout, R.id.search_layout);
mSearchBar = (SearchBar) ViewUtils.$$(mainLayout, R.id.search_bar);
mFabLayout = (FabLayout) ViewUtils.$$(mainLayout, R.id.fab_layout);
@@ -565,12 +570,12 @@ public final class GalleryListScene extends BaseScene
int paddingTopSB = resources.getDimensionPixelOffset(R.dimen.gallery_padding_top_search_bar);
int paddingBottomFab = resources.getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
mViewTransition = new BringOutTransition(contentLayout, mSearchLayout);
mViewTransition = new BringOutTransition(mContentLayout, mSearchLayout);
mHelper = new GalleryListHelper();
contentLayout.setHelper(mHelper);
contentLayout.getFastScroller().setOnDragHandlerListener(this);
contentLayout.setFitPaddingTop(paddingTopSB);
mContentLayout.setHelper(mHelper);
mContentLayout.getFastScroller().setOnDragHandlerListener(this);
mContentLayout.setFitPaddingTop(paddingTopSB);
mAdapter = new GalleryListAdapter(inflater, resources,
mRecyclerView, Settings.getListMode());
@@ -1897,4 +1902,33 @@ public final class GalleryListScene extends BaseScene
}
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
int corner_fab_margin = getResources().getDimensionPixelOffset(R.dimen.corner_fab_margin);
if (mSearchBar != null) {
int gallery_search_bar_margin_v = getResources().getDimensionPixelOffset(R.dimen.gallery_search_bar_margin_v);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mSearchBar.getLayoutParams();
layoutParams.topMargin = insets1.top + gallery_search_bar_margin_v;
}
if (mContentLayout != null) {
mContentLayout.setTopInsets(insets1.top);
mContentLayout.setFitPaddingBottom(insets1.bottom);
}
if (mSearchFab != null) {
FabLayout fabLayout = (FabLayout) mSearchFab.getParent();
fabLayout.setPadding(mSearchFab.getPaddingLeft(), mSearchFab.getPaddingTop(), corner_fab_margin + insets1.right, corner_fab_margin + insets1.bottom);
}
if (mFabLayout != null) {
mFabLayout.setPadding(mSearchFab.getPaddingLeft(), mSearchFab.getPaddingTop(), corner_fab_margin + insets1.right, corner_fab_margin + insets1.bottom);
}
if (mSearchLayout != null) {
int paddingTopSB = getResources().getDimensionPixelOffset(R.dimen.gallery_padding_top_search_bar);
int paddingBottomFab = getResources().getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
mSearchLayout.setPadding(mSearchLayout.getPaddingLeft(), paddingTopSB + insets1.top,
mSearchLayout.getPaddingRight(), paddingBottomFab + insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
@@ -33,9 +33,12 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.graphics.Insets;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.hippo.android.resource.AttrResources;
import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.MarginItemDecoration;
import com.hippo.ehviewer.EhApplication;
@@ -79,6 +82,8 @@ public class GalleryPreviewsScene extends ToolbarScene {
View life cycle
---------------*/
@Nullable
private ContentLayout mContentLayout;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private GalleryPreviewAdapter mAdapter;
@@ -133,10 +138,10 @@ public class GalleryPreviewsScene extends ToolbarScene {
@Override
public View onCreateViewWithToolbar(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ContentLayout contentLayout = (ContentLayout) inflater.inflate(
mContentLayout = (ContentLayout) inflater.inflate(
R.layout.scene_gallery_previews, container, false);
contentLayout.hideFastScroll();
mRecyclerView = contentLayout.getRecyclerView();
mContentLayout.hideFastScroll();
mRecyclerView = mContentLayout.getRecyclerView();
Context context = getContext();
AssertUtils.assertNotNull(context);
@@ -155,7 +160,7 @@ public class GalleryPreviewsScene extends ToolbarScene {
decoration.applyPaddings(mRecyclerView);
mHelper = new GalleryPreviewHelper();
contentLayout.setHelper(mHelper);
mContentLayout.setHelper(mHelper);
// Only refresh for the first time
if (!mHasFirstRefresh) {
@@ -163,7 +168,7 @@ public class GalleryPreviewsScene extends ToolbarScene {
mHelper.firstRefresh();
}
return contentLayout;
return mContentLayout;
}
@Override
@@ -448,4 +453,16 @@ public class GalleryPreviewsScene extends ToolbarScene {
mSlider = null;
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
if (mContentLayout != null) {
mContentLayout.setFitPaddingBottom(insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
@@ -34,7 +34,9 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
@@ -692,4 +694,18 @@ public class HistoryScene extends ToolbarScene {
updateView(true);
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
if (mRecyclerView != null) {
int paddingH = getResources().getDimensionPixelOffset(R.dimen.gallery_list_margin_h);
int paddingV = getResources().getDimensionPixelOffset(R.dimen.gallery_list_margin_v);
mRecyclerView.setPadding(paddingH, paddingV, paddingH, paddingV + insets1.bottom);
}
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
return WindowInsetsCompat.CONSUMED;
}
}
@@ -17,6 +17,7 @@
package com.hippo.ehviewer.ui.scene;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -29,7 +30,11 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.Toolbar;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.hippo.android.resource.AttrResources;
import com.hippo.ehviewer.R;
public abstract class ToolbarScene extends BaseScene {
@@ -52,6 +57,16 @@ public abstract class ToolbarScene extends BaseScene {
View view = inflater.inflate(R.layout.scene_toolbar, container, false);
Toolbar toolbar = view.findViewById(R.id.toolbar);
FrameLayout contentPanel = view.findViewById(R.id.content_panel);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !(this instanceof GalleryCommentsScene)) {
ViewCompat.setOnApplyWindowInsetsListener(view, (v, insets) -> {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
view.setPadding(insets1.left, 0, insets1.right, insets1.bottom);
View statusBarBackground = view.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
return WindowInsetsCompat.CONSUMED;
});
}
View contentView = onCreateViewWithToolbar(inflater, contentPanel, savedInstanceState);
if (contentView == null) {
@@ -127,4 +142,14 @@ public abstract class ToolbarScene extends BaseScene {
mTempTitle = title;
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
v.setPadding(insets1.left, 0, insets1.right, insets1.bottom);
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
return WindowInsetsCompat.CONSUMED;
}
}
@@ -22,6 +22,9 @@ import android.view.View;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.Insets;
import androidx.core.view.OnApplyWindowInsetsListener;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
@@ -34,7 +37,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
public class SceneFragment extends Fragment {
public class SceneFragment extends Fragment implements OnApplyWindowInsetsListener {
public static final int LAUNCH_MODE_STANDARD = 0;
public static final int LAUNCH_MODE_SINGLE_TOP = 1;
@@ -165,6 +168,13 @@ public class SceneFragment extends Fragment {
this.result = result;
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
v.setPadding(insets1.left, insets1.top, insets1.right, insets1.bottom);
return WindowInsetsCompat.CONSUMED;
}
@IntDef({LAUNCH_MODE_STANDARD, LAUNCH_MODE_SINGLE_TOP, LAUNCH_MODE_SINGLE_TASK})
@Retention(RetentionPolicy.SOURCE)
public @interface LaunchMode {
@@ -24,6 +24,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
@@ -195,6 +196,10 @@ public abstract class StageActivity extends EhActivity {
}
public void onSceneViewCreated(SceneFragment scene, Bundle savedInstanceState) {
View view = scene.getView();
if (view != null) {
ViewCompat.setOnApplyWindowInsetsListener(view, scene);
}
}
public void onSceneViewDestroyed(SceneFragment scene) {
@@ -21,6 +21,7 @@ import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import com.hippo.ehviewer.R;
@@ -153,4 +154,9 @@ public class StageLayout extends FrameLayout {
return super.drawChild(canvas, child, drawingTime);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
return insets;
}
}
@@ -17,6 +17,7 @@
package com.hippo.widget;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
@@ -33,8 +34,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.progressindicator.CircularProgressIndicator;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.hippo.android.resource.AttrResources;
import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.FastScroller;
@@ -42,7 +45,6 @@ import com.hippo.easyrecyclerview.HandlerDrawable;
import com.hippo.easyrecyclerview.LayoutManagerUtils;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.refreshlayout.RefreshLayout;
import com.hippo.util.ExceptionUtils;
import com.hippo.view.ViewTransition;
import com.hippo.yorozuya.IntIdGenerator;
@@ -60,7 +62,8 @@ public class ContentLayout extends FrameLayout {
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private SwipeRefreshLayout mRefreshLayout;
private LinearProgressIndicator mBottomProgress;
private EasyRecyclerView mRecyclerView;
private FastScroller mFastScroller;
@@ -92,6 +95,7 @@ public class ContentLayout extends FrameLayout {
mContentView = findViewById(R.id.content_view);
mRefreshLayout = mContentView.findViewById(R.id.refresh_layout);
mBottomProgress = mContentView.findViewById(R.id.bottom_progress);
mFastScroller = mContentView.findViewById(R.id.fast_scroller);
mRecyclerView = mRefreshLayout.findViewById(R.id.recycler_view);
@@ -100,18 +104,23 @@ public class ContentLayout extends FrameLayout {
drawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
mFastScroller.setHandlerDrawable(drawable);
mRefreshLayout.setHeaderColorSchemeResources(
mRefreshLayout.setColorSchemeResources(
R.color.loading_indicator_red,
R.color.loading_indicator_purple,
R.color.loading_indicator_blue,
R.color.loading_indicator_cyan,
R.color.loading_indicator_green,
R.color.loading_indicator_yellow);
mRefreshLayout.setFooterColorSchemeResources(
R.color.loading_indicator_red,
R.color.loading_indicator_blue,
R.color.loading_indicator_green,
R.color.loading_indicator_orange);
Resources resources = getResources();
mBottomProgress.setIndicatorColor(
resources.getColor(R.color.loading_indicator_red),
resources.getColor(R.color.loading_indicator_purple),
resources.getColor(R.color.loading_indicator_blue),
resources.getColor(R.color.loading_indicator_cyan),
resources.getColor(R.color.loading_indicator_green),
resources.getColor(R.color.loading_indicator_yellow));
mBottomProgress.setIndeterminateAnimationType(LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS);
mRecyclerViewOriginTop = mRecyclerView.getPaddingTop();
mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom();
@@ -126,7 +135,7 @@ public class ContentLayout extends FrameLayout {
return mFastScroller;
}
public RefreshLayout getRefreshLayout() {
public SwipeRefreshLayout getRefreshLayout() {
return mRefreshLayout;
}
@@ -149,7 +158,11 @@ public class ContentLayout extends FrameLayout {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerViewOriginTop + fitPaddingTop, mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
// RefreshLayout
mRefreshLayout.setHeaderProgressViewOffset(true, 0, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32)); // TODO
mRefreshLayout.setProgressViewOffset(true, 0, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32)); // TODO
}
public void setTopInsets(int topInsets) {
setPadding(0, topInsets, 0, 0);
}
public void setFitPaddingBottom(int fitPaddingBottom) {
@@ -157,6 +170,12 @@ public class ContentLayout extends FrameLayout {
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(),
mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(),
mRecyclerViewOriginBottom + fitPaddingBottom);
mTipView.setPadding(mTipView.getPaddingLeft(), mTipView.getPaddingTop(), mTipView.getPaddingRight(), fitPaddingBottom);
mProgressView.setPadding(mTipView.getPaddingLeft(), mTipView.getPaddingTop(), mTipView.getPaddingRight(), fitPaddingBottom);
mFastScroller.setPadding(mFastScroller.getPaddingLeft(), mFastScroller.getPaddingTop(), mFastScroller.getPaddingRight(), fitPaddingBottom);
if (fitPaddingBottom > LayoutUtils.dp2pix(getContext(), 16)) {
mBottomProgress.setPadding(0, 0, 0, fitPaddingBottom);
}
}
@Override
@@ -200,7 +219,8 @@ public class ContentLayout extends FrameLayout {
private CircularProgressIndicator mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private SwipeRefreshLayout mRefreshLayout;
private LinearProgressIndicator mBottomProgress;
private EasyRecyclerView mRecyclerView;
private ViewTransition mViewTransition;
/**
@@ -233,9 +253,9 @@ public class ContentLayout extends FrameLayout {
private int mCurrentTaskPage;
private int mNextPageScrollSize;
private String mEmptyString = "No hint";
private final RefreshLayout.OnRefreshListener mOnRefreshListener = new RefreshLayout.OnRefreshListener() {
private final SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onHeaderRefresh() {
public void onRefresh() {
if (mStartPage > 0) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE_KEEP_POS;
@@ -245,41 +265,36 @@ public class ContentLayout extends FrameLayout {
doRefresh();
}
}
@Override
public void onFooterRefresh() {
if (mEndPage < mPages) {
// Get next page
// Fill pages before NextPage with empty list
while (mNextPage > mEndPage && mEndPage < mPages) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
onGetPageData(mCurrentTaskId, mPages, mNextPage, Collections.emptyList());
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (mEndPage == mPages) {
// Refresh last page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH_PAGE;
mCurrentTaskPage = mEndPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
Log.e(TAG, "Try to footer refresh, but mEndPage = " + mEndPage + ", mPages = " + mPages);
mRefreshLayout.setFooterRefreshing(false);
}
}
};
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (!mRefreshLayout.isRefreshing() && mRefreshLayout.isAlmostBottom() && mEndPage < mPages) {
if (!mRefreshLayout.isRefreshing() && !recyclerView.canScrollVertically(1) && mEndPage < mPages) {
// Get next page
mRefreshLayout.setFooterRefreshing(true);
mOnRefreshListener.onFooterRefresh();
mBottomProgress.show();
if (mEndPage < mPages) {
// Get next page
// Fill pages before NextPage with empty list
while (mNextPage > mEndPage && mEndPage < mPages) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
onGetPageData(mCurrentTaskId, mPages, mNextPage, Collections.emptyList());
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (mEndPage == mPages) {
// Refresh last page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH_PAGE;
mCurrentTaskPage = mEndPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
Log.e(TAG, "Try to footer refresh, but mEndPage = " + mEndPage + ", mPages = " + mPages);
mBottomProgress.hide();
}
}
}
};
@@ -293,6 +308,7 @@ public class ContentLayout extends FrameLayout {
mContentView = contentLayout.mContentView;
mRefreshLayout = contentLayout.mRefreshLayout;
mBottomProgress = contentLayout.mBottomProgress;
mRecyclerView = contentLayout.mRecyclerView;
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.big_sad_pandroid);
@@ -458,13 +474,13 @@ public class ContentLayout extends FrameLayout {
if (true || mEndPage >= mPages) { // Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
@@ -481,8 +497,8 @@ public class ContentLayout extends FrameLayout {
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// RecyclerView scroll
@@ -509,13 +525,13 @@ public class ContentLayout extends FrameLayout {
if (true || mStartPage <= 0) { // OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
@@ -540,8 +556,8 @@ public class ContentLayout extends FrameLayout {
notifyItemRangeInserted(0, data.size());
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mRecyclerView.isAttachedToWindow()) {
@@ -572,13 +588,13 @@ public class ContentLayout extends FrameLayout {
if (true || mEndPage >= mPages) { // OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
@@ -603,8 +619,8 @@ public class ContentLayout extends FrameLayout {
notifyItemRangeInserted(oldDataSize, dataSize);
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mRecyclerView.isAttachedToWindow()) {
@@ -634,13 +650,13 @@ public class ContentLayout extends FrameLayout {
if (true || mEndPage >= mPages) { // Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
@@ -657,8 +673,8 @@ public class ContentLayout extends FrameLayout {
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mRecyclerView.isAttachedToWindow()) {
@@ -700,13 +716,13 @@ public class ContentLayout extends FrameLayout {
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// RecyclerView scroll
@@ -723,8 +739,8 @@ public class ContentLayout extends FrameLayout {
public void onGetException(int taskId, Exception e) {
if (mCurrentTaskId == taskId) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
String readableError;
if (e != null) {
@@ -775,18 +791,18 @@ public class ContentLayout extends FrameLayout {
default:
case REFRESH_TYPE_HEADER:
showContent();
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
break;
case REFRESH_TYPE_FOOTER:
showContent();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
break;
case REFRESH_TYPE_PROGRESS_VIEW:
showProgressBar();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
break;
}
@@ -821,8 +837,8 @@ public class ContentLayout extends FrameLayout {
private void cancelCurrentTask() {
mCurrentTaskId = mIdGenerator.nextId();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
}
private int getPageStart(int page) {
@@ -881,24 +897,24 @@ public class ContentLayout extends FrameLayout {
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), position, 0);
onScrollToPosition(position);
} else if (page == mStartPage - 1) {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (page == mEndPage) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_SOMEWHERE;