diff --git a/app/src/main/java/com/gh/common/view/AbstractSwipeRefreshHeader.java b/app/src/main/java/com/gh/common/view/AbstractSwipeRefreshHeader.java new file mode 100644 index 0000000000..dc168e9eab --- /dev/null +++ b/app/src/main/java/com/gh/common/view/AbstractSwipeRefreshHeader.java @@ -0,0 +1,295 @@ +package com.gh.common.view; + +import android.content.Context; +import android.graphics.drawable.Animatable; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; +import android.support.annotation.DrawableRes; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.LinearInterpolator; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import com.scwang.smartrefresh.layout.api.RefreshInternal; +import com.scwang.smartrefresh.layout.api.RefreshKernel; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.internal.ArrowDrawable; +import com.scwang.smartrefresh.layout.internal.InternalAbstract; +import com.scwang.smartrefresh.layout.internal.ProgressDrawable; +import com.scwang.smartrefresh.layout.util.DensityUtil; + +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static com.scwang.smartrefresh.layout.util.SmartUtil.getColor; + +public abstract class AbstractSwipeRefreshHeader extends InternalAbstract implements RefreshInternal { + public static final byte ID_TEXT_TITLE = 1; + public static final byte ID_IMAGE_ARROW = 2; + public static final byte ID_IMAGE_PROGRESS = 3; + + protected TextView mTitleText; + protected ImageView mArrowView; + protected ImageView mProgressView; + protected LinearLayout mCenterLayout; + protected RefreshKernel mRefreshKernel; + protected ArrowDrawable mArrowDrawable; + protected ProgressDrawable mProgressDrawable; + protected Integer mAccentColor; + protected Integer mPrimaryColor; + protected int mBackgroundColor; + protected int mFinishDuration = 500; + + private DensityUtil mDensityUtil = new DensityUtil(); + + public AbstractSwipeRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + mSpinnerStyle = SpinnerStyle.Translate; + mArrowView = new ImageView(context); + mProgressView = new ImageView(context); + mTitleText = new TextView(context); + mTitleText.setTextColor(0xff5d5d5d); + mCenterLayout = new LinearLayout(context); + mCenterLayout.setGravity(Gravity.CENTER_HORIZONTAL); + mCenterLayout.setOrientation(LinearLayout.VERTICAL); + + final View thisView = this; + final ViewGroup thisGroup = this; + final View arrowView = mArrowView; + final View titleView = mTitleText; + final View progressView = mProgressView; + final ViewGroup centerLayout = mCenterLayout; + + titleView.setId(ID_TEXT_TITLE); + arrowView.setId(ID_IMAGE_ARROW); + progressView.setId(ID_IMAGE_PROGRESS); + centerLayout.setId(android.R.id.widget_frame); + + LinearLayout.LayoutParams lpHeaderText = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + centerLayout.addView(titleView, lpHeaderText); + + RelativeLayout.LayoutParams lpHeaderLayout = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + lpHeaderLayout.addRule(CENTER_IN_PARENT); + thisGroup.addView(centerLayout, lpHeaderLayout); + + RelativeLayout.LayoutParams lpArrow = new RelativeLayout.LayoutParams(mDensityUtil.dip2px(15), mDensityUtil.dip2px(15)); + lpArrow.addRule(CENTER_VERTICAL); + lpArrow.addRule(LEFT_OF, android.R.id.widget_frame); + thisGroup.addView(arrowView, lpArrow); + + RelativeLayout.LayoutParams lpProgress = new RelativeLayout.LayoutParams((ViewGroup.LayoutParams) lpArrow); + lpProgress.addRule(CENTER_VERTICAL); + lpProgress.addRule(LEFT_OF, android.R.id.widget_frame); + progressView.animate().setInterpolator(new LinearInterpolator()); + thisGroup.addView(progressView, lpProgress); + + if (thisView.isInEditMode()) { + arrowView.setVisibility(GONE); + } else { + progressView.setVisibility(GONE); + } + + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + final View arrowView = mArrowView; + final View progressView = mProgressView; + arrowView.animate().cancel(); + progressView.animate().cancel(); + } + final Drawable drawable = mProgressView.getDrawable(); + if (drawable instanceof Animatable) { + if (((Animatable) drawable).isRunning()) { + ((Animatable) drawable).stop(); + } + } + } + + protected T self() { + //noinspection unchecked + return (T) this; + } + + @Override + public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) { + mRefreshKernel = kernel; + mRefreshKernel.requestDrawBackgroundFor(this, mBackgroundColor); + } + + @Override + public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) { + if (mProgressView.getVisibility() != VISIBLE) { + mProgressView.setVisibility(VISIBLE); + Drawable drawable = mProgressView.getDrawable(); + if (drawable instanceof Animatable) { + ((Animatable) drawable).start(); + } else { + mProgressView.animate().rotation(36000).setDuration(100000); + } + } + } + + @Override + public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) { + onStartAnimator(refreshLayout, height, maxDragHeight); + } + + @Override + public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) { + Drawable drawable = mProgressView.getDrawable(); + if (drawable instanceof Animatable) { + if (((Animatable) drawable).isRunning()) { + ((Animatable) drawable).stop(); + } + } else { + mProgressView.animate().rotation(0).setDuration(0); + } + mProgressView.setVisibility(GONE); + return mFinishDuration; + } + + @Override + @Deprecated + public void setPrimaryColors(@ColorInt int... colors) { + if (colors.length > 0) { + final View thisView = this; + if (!(thisView.getBackground() instanceof BitmapDrawable) && mPrimaryColor == null) { + setPrimaryColor(colors[0]); + mPrimaryColor = null; + } + if (mAccentColor == null) { + if (colors.length > 1) { + setAccentColor(colors[1]); + } + mAccentColor = null; + } + } + } + + public T setProgressDrawable(Drawable drawable) { + mProgressDrawable = null; + mProgressView.setImageDrawable(drawable); + return self(); + } + + public T setProgressResource(@DrawableRes int resId) { + mProgressDrawable = null; + mProgressView.setImageResource(resId); + return self(); + } + + public T setArrowDrawable(Drawable drawable) { + mArrowDrawable = null; + mArrowView.setImageDrawable(drawable); + return self(); + } + + public T setArrowResource(@DrawableRes int resId) { + mArrowDrawable = null; + mArrowView.setImageResource(resId); + return self(); + } + + public T setSpinnerStyle(SpinnerStyle style) { + this.mSpinnerStyle = style; + return self(); + } + + public T setPrimaryColor(@ColorInt int primaryColor) { + mBackgroundColor = mPrimaryColor = primaryColor; + if (mRefreshKernel != null) { + mRefreshKernel.requestDrawBackgroundFor(this, mPrimaryColor); + } + return self(); + } + + public T setAccentColor(@ColorInt int accentColor) { + mAccentColor = accentColor; + mTitleText.setTextColor(accentColor); + if (mArrowDrawable != null) { + mArrowDrawable.setColor(accentColor); + } + if (mProgressDrawable != null) { + mProgressDrawable.setColor(accentColor); + } + return self(); + } + + public T setPrimaryColorId(@ColorRes int colorId) { + final View thisView = this; + setPrimaryColor(getColor(thisView.getContext(), colorId)); + return self(); + } + + public T setAccentColorId(@ColorRes int colorId) { + final View thisView = this; + setAccentColor(getColor(thisView.getContext(), colorId)); + return self(); + } + + public T setFinishDuration(int delay) { + mFinishDuration = delay; + return self(); + } + + public T setTextSizeTitle(float size) { + mTitleText.setTextSize(size); + if (mRefreshKernel != null) { + mRefreshKernel.requestRemeasureHeightFor(this); + } + return self(); + } + + public T setDrawableMarginRight(float dp) { + final View arrowView = mArrowView; + final View progressView = mProgressView; + MarginLayoutParams lpArrow = (MarginLayoutParams) arrowView.getLayoutParams(); + MarginLayoutParams lpProgress = (MarginLayoutParams) progressView.getLayoutParams(); + lpArrow.rightMargin = lpProgress.rightMargin = DensityUtil.dp2px(dp); + arrowView.setLayoutParams(lpArrow); + progressView.setLayoutParams(lpProgress); + return self(); + } + + public T setDrawableSize(float dp) { + final View arrowView = mArrowView; + final View progressView = mProgressView; + ViewGroup.LayoutParams lpArrow = arrowView.getLayoutParams(); + ViewGroup.LayoutParams lpProgress = progressView.getLayoutParams(); + lpArrow.width = lpProgress.width = DensityUtil.dp2px(dp); + lpArrow.height = lpProgress.height = DensityUtil.dp2px(dp); + arrowView.setLayoutParams(lpArrow); + progressView.setLayoutParams(lpProgress); + return self(); + } + + public T setDrawableArrowSize(float dp) { + final View arrowView = mArrowView; + ViewGroup.LayoutParams lpArrow = arrowView.getLayoutParams(); + lpArrow.height = lpArrow.width = DensityUtil.dp2px(dp); + arrowView.setLayoutParams(lpArrow); + return self(); + } + + public T setDrawableProgressSize(float dp) { + final View progressView = mProgressView; + ViewGroup.LayoutParams lpProgress = progressView.getLayoutParams(); + lpProgress.height = lpProgress.width = DensityUtil.dp2px(dp); + progressView.setLayoutParams(lpProgress); + return self(); + } + + +} diff --git a/app/src/main/java/com/gh/common/view/SwipeRefreshHeader.java b/app/src/main/java/com/gh/common/view/SwipeRefreshHeader.java new file mode 100644 index 0000000000..b2fbc308b4 --- /dev/null +++ b/app/src/main/java/com/gh/common/view/SwipeRefreshHeader.java @@ -0,0 +1,172 @@ +package com.gh.common.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.support.annotation.ColorInt; +import android.support.annotation.NonNull; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.scwang.smartrefresh.layout.R; +import com.scwang.smartrefresh.layout.api.RefreshHeader; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.internal.ArrowDrawable; +import com.scwang.smartrefresh.layout.internal.ProgressDrawable; +import com.scwang.smartrefresh.layout.util.DensityUtil; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class SwipeRefreshHeader extends AbstractSwipeRefreshHeader implements RefreshHeader { + + public static final byte ID_TEXT_UPDATE = 4; + + public static String REFRESH_HEADER_PULLING = "下拉可以刷新";//"下拉可以刷新"; + public static String REFRESH_HEADER_REFRESHING = "正在刷新...";//"正在刷新..."; + public static String REFRESH_HEADER_LOADING = "刷新中...";//"正在加载..."; + public static String REFRESH_HEADER_RELEASE = "释放立即刷新";//"释放立即刷新"; + public static String REFRESH_HEADER_FINISH = "刷新完成";//"刷新完成"; + public static String REFRESH_HEADER_FAILED = "获取失败,请检查网络设置";//"刷新失败"; + + private TextView successView; + + public SwipeRefreshHeader(Context context) { + this(context, null); + } + + public SwipeRefreshHeader(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SwipeRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + final View arrowView = mArrowView; + final View progressView = mProgressView; + final DensityUtil density = new DensityUtil(); + + successView = (TextView) LayoutInflater.from(context).inflate(com.gh.gamecenter.R.layout.piece_refresh_hint, null); + LinearLayout.LayoutParams successViewLp = new LinearLayout.LayoutParams(MATCH_PARENT, density.dip2px(45)); + addView(successView, successViewLp); + + TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ClassicsHeader); + + LayoutParams lpArrow = (LayoutParams) arrowView.getLayoutParams(); + LayoutParams lpProgress = (LayoutParams) progressView.getLayoutParams(); + LinearLayout.LayoutParams lpUpdateText = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); + lpUpdateText.topMargin = ta.getDimensionPixelSize(R.styleable.ClassicsHeader_srlTextTimeMarginTop, density.dip2px(0)); + lpProgress.rightMargin = ta.getDimensionPixelSize(R.styleable.ClassicsFooter_srlDrawableMarginRight, density.dip2px(10)); + lpArrow.rightMargin = lpProgress.rightMargin; + + lpArrow.width = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableArrowSize, lpArrow.width); + lpArrow.height = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableArrowSize, lpArrow.height); + lpProgress.width = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableProgressSize, lpProgress.width); + lpProgress.height = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableProgressSize, lpProgress.height); + + lpArrow.width = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableSize, lpArrow.width); + lpArrow.height = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableSize, lpArrow.height); + lpProgress.width = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableSize, lpProgress.width); + lpProgress.height = ta.getLayoutDimension(R.styleable.ClassicsHeader_srlDrawableSize, lpProgress.height); + + mFinishDuration = ta.getInt(R.styleable.ClassicsHeader_srlFinishDuration, 1000); + mSpinnerStyle = SpinnerStyle.values()[ta.getInt(R.styleable.ClassicsHeader_srlClassicsSpinnerStyle, mSpinnerStyle.ordinal())]; + + if (ta.hasValue(R.styleable.ClassicsHeader_srlDrawableArrow)) { + mArrowView.setImageDrawable(ta.getDrawable(R.styleable.ClassicsHeader_srlDrawableArrow)); + } else { + mArrowDrawable = new ArrowDrawable(); + mArrowDrawable.setColor(0xff666666); + mArrowView.setImageDrawable(mArrowDrawable); + } + + if (ta.hasValue(R.styleable.ClassicsHeader_srlDrawableProgress)) { + mProgressView.setImageDrawable(ta.getDrawable(R.styleable.ClassicsHeader_srlDrawableProgress)); + } else { + mProgressDrawable = new ProgressDrawable(); + mProgressDrawable.setColor(0xff666666); + mProgressView.setImageDrawable(mProgressDrawable); + } + + if (ta.hasValue(R.styleable.ClassicsHeader_srlTextSizeTitle)) { + mTitleText.setTextSize(TypedValue.COMPLEX_UNIT_PX, ta.getDimensionPixelSize(R.styleable.ClassicsHeader_srlTextSizeTitle, DensityUtil.dp2px(12))); + } else { + mTitleText.setTextSize(12); + } + + if (ta.hasValue(R.styleable.ClassicsHeader_srlPrimaryColor)) { + setPrimaryColor(ta.getColor(R.styleable.ClassicsHeader_srlPrimaryColor, 0)); + } + if (ta.hasValue(R.styleable.ClassicsHeader_srlAccentColor)) { + setAccentColor(ta.getColor(R.styleable.ClassicsHeader_srlAccentColor, 0)); + } + + ta.recycle(); + + mTitleText.setText(this.isInEditMode() ? REFRESH_HEADER_REFRESHING : REFRESH_HEADER_PULLING); + } + + public void setFinishText(String text) { + REFRESH_HEADER_FINISH = text; + } + + @Override + public int onFinish(@NonNull RefreshLayout layout, boolean success) { + mCenterLayout.setVisibility(GONE); + mArrowView.setVisibility(GONE); + mProgressView.setVisibility(GONE); + if (success) { + successView.setVisibility(VISIBLE); + successView.setText(REFRESH_HEADER_FINISH); + return super.onFinish(layout, success); + } else { + successView.setVisibility(GONE); + super.onFinish(layout, success); + return 0; + } + } + + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + switch (newState) { + case PullDownToRefresh: + successView.setVisibility(GONE); + mCenterLayout.setVisibility(VISIBLE); + mTitleText.setText(REFRESH_HEADER_PULLING); + mArrowView.setVisibility(VISIBLE); + mArrowView.animate().rotation(0); + break; + case Refreshing: + case RefreshReleased: + successView.setVisibility(GONE); + mCenterLayout.setVisibility(VISIBLE); + mTitleText.setText(REFRESH_HEADER_REFRESHING); + mArrowView.setVisibility(GONE); + break; + case ReleaseToRefresh: + successView.setVisibility(GONE); + mCenterLayout.setVisibility(VISIBLE); + mTitleText.setText(REFRESH_HEADER_RELEASE); + mArrowView.animate().rotation(180); + break; + case Loading: + successView.setVisibility(GONE); + mCenterLayout.setVisibility(VISIBLE); + mArrowView.setVisibility(GONE); + mTitleText.setText(REFRESH_HEADER_LOADING); + break; + } + } + + public SwipeRefreshHeader setAccentColor(@ColorInt int accentColor) { + return super.setAccentColor(accentColor); + } + +} + diff --git a/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryAdapter.kt b/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryAdapter.kt index 9c809e4709..d0688a149e 100644 --- a/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryAdapter.kt +++ b/app/src/main/java/com/gh/gamecenter/category/CategoryDirectoryAdapter.kt @@ -107,7 +107,7 @@ class CategoryDirectoryAdapter(context: Context, var categoryTitle: String) : Li 0 -> { subCategoryView = SubCategoryView(binding.root.context) - val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT) + val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT) params.setMargins(0, marginTop, 0, 0) subCategoryView?.categoryTitle = categoryTitle diff --git a/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsFragment.java b/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsFragment.java index 37d7c99eb2..8d6dc93710 100644 --- a/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsFragment.java +++ b/app/src/main/java/com/gh/gamecenter/qa/recommends/AskQuestionsRecommendsFragment.java @@ -6,13 +6,13 @@ import android.os.Bundle; import android.os.Message; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v7.widget.RecyclerView; import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; import com.gh.common.util.AskLogUtils; import com.gh.common.util.CheckLoginUtils; -import com.gh.common.util.DisplayUtils; +import com.gh.common.view.SwipeRefreshHeader; +import com.gh.common.view.VerticalItemDecoration; import com.gh.gamecenter.R; import com.gh.gamecenter.baselist.ListFragment; import com.gh.gamecenter.baselist.LoadStatus; @@ -43,43 +43,20 @@ public class AskQuestionsRecommendsFragment extends ListFragment= 35) { - mBaseHandler.sendEmptyMessageDelayed(1, 2000); - return; - } - ViewGroup.LayoutParams layoutParams = mRefreshHint.getLayoutParams(); - layoutParams.height = DisplayUtils.dip2px(getContext(), mRefreshHeight); - mRefreshHint.setLayoutParams(layoutParams); - mBaseHandler.sendEmptyMessage(0); - } else if (msg.what == 2) { - mListViewModel.load(null); - } + if (msg.what == 2) mListViewModel.load(null); } @Override @@ -87,34 +64,30 @@ public class AskQuestionsRecommendsFragment extends ListFragment { - startActivity(QuestionEditActivity.Companion.getIntent(getContext())); - }; + mOnLoginListener = () -> startActivity(QuestionEditActivity.Companion.getIntent(getContext())); mListViewModel.getRefreshCount().observe(this, integer -> { if (integer != null) { - mRefreshHeight = 8; switch (integer) { case 0: - mRefreshHint.setText("已经没有新内容咯,请稍后再试"); - mBaseHandler.sendEmptyMessage(0); + swipeRefreshHeader.setFinishText("已经没有新内容咯,请稍后再试"); AskLogUtils.communityRefresh(getContext(), integer); + refreshLayout.finishRefresh(); break; case -1: toast("获取失败,请检查网络设置"); + refreshLayout.finishRefresh(false); break; default: - mRefreshHint.setText("成功获取" + integer + "条内容"); - mBaseHandler.sendEmptyMessage(0); + swipeRefreshHeader.setFinishText("成功获取" + integer + "条内容"); + refreshLayout.finishRefresh(); AskLogUtils.communityRefresh(getContext(), integer); break; } } - refreshLayout.finishRefresh(); if (mListLoading.getVisibility() == View.VISIBLE) mListLoading.setVisibility(View.GONE); if (mListRv.getVisibility() == View.GONE) mListRv.setVisibility(View.VISIBLE); @@ -130,12 +103,19 @@ public class AskQuestionsRecommendsFragment extends ListFragment onRefresh()); + refreshLayout.setOnRefreshListener( + refreshLayout -> { + if (!mInitRefresh) { + onRefresh(); + } + mInitRefresh = false; + } + ); } @Override protected void hideRefreshingLayout() { - refreshLayout.finishRefresh(); + swipeRefreshHeader.postDelayed(() -> refreshLayout.finishRefresh(), 200); } @Override @@ -169,6 +149,7 @@ public class AskQuestionsRecommendsFragment extends ListFragment + android:layout_height = "match_parent"> + android:layout_height = "match_parent"> - + android:layout_height = "40dp" /> + android:layout_height = "wrap_content" /> - - @@ -29,6 +31,8 @@ android:layout_weight="1" android:layout_height="wrap_content" android:gravity="center" + android:ellipsize="end" + android:maxLines="1" android:textColor="#000000" android:textSize="12sp" tools:text="空海爭霸" /> @@ -45,8 +49,10 @@ android:id="@+id/tv_right_sub_category" android:layout_width="0dp" android:layout_weight="1" + android:ellipsize="end" android:layout_height="wrap_content" android:gravity="center" + android:maxLines="1" android:textColor="#000000" android:textSize="12sp" tools:text="地海爭霸" /> diff --git a/app/src/main/res/layout/piece_refresh_hint.xml b/app/src/main/res/layout/piece_refresh_hint.xml new file mode 100644 index 0000000000..563d335aba --- /dev/null +++ b/app/src/main/res/layout/piece_refresh_hint.xml @@ -0,0 +1,12 @@ + +