feat: 侧边滑动返回 & 两侧支持

This commit is contained in:
HuanCheng65 2022-06-16 12:16:17 +08:00
parent d55b0d6df8
commit 5faef59cbc
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
15 changed files with 542 additions and 88 deletions

View File

@ -84,9 +84,6 @@ dependencies {
//Local Files
implementation fileTree(include: ["*.jar"], dir: "libs")
//
implementation "me.imid.swipebacklayout.lib:library:1.3.0"
// Glide
implementation "com.android.support:support-annotations:28.0.0"
kapt "com.android.support:support-annotations:28.0.0"

View File

@ -23,6 +23,7 @@ import androidx.annotation.CallSuper
import androidx.annotation.ColorInt
import androidx.annotation.Keep
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import butterknife.ButterKnife
import cn.jzvd.Jzvd
@ -30,16 +31,16 @@ import com.gyf.immersionbar.ImmersionBar
import com.huanchengfly.tieba.post.BaseApplication
import com.huanchengfly.tieba.post.BaseApplication.Companion.instance
import com.huanchengfly.tieba.post.R
import com.huanchengfly.tieba.post.ui.slideback.SlideBack
import com.huanchengfly.tieba.post.ui.theme.interfaces.ExtraRefreshable
import com.huanchengfly.tieba.post.ui.theme.utils.ThemeUtils
import com.huanchengfly.tieba.post.utils.*
import com.huanchengfly.tieba.post.widgets.VoicePlayerView
import com.huanchengfly.tieba.post.widgets.theme.TintToolbar
import kotlinx.coroutines.*
import me.imid.swipebacklayout.lib.app.SwipeBackActivity
import kotlin.coroutines.CoroutineContext
abstract class BaseActivity : SwipeBackActivity(), ExtraRefreshable, CoroutineScope {
abstract class BaseActivity : AppCompatActivity(), ExtraRefreshable, CoroutineScope {
val job = Job()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
@ -99,6 +100,8 @@ abstract class BaseActivity : SwipeBackActivity(), ExtraRefreshable, CoroutineSc
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
SlideBack.create()
.attachToActivity(this)
fixBackground()
getDeviceDensity()
instance.addActivity(this)

View File

@ -166,7 +166,6 @@ open class MainActivity : BaseActivity(), NavigationBarView.OnItemSelectedListen
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSwipeBackEnable(false)
ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background))
findView()
initView()

View File

@ -10,14 +10,11 @@ import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.widget.TextViewCompat
import androidx.recyclerview.widget.RecyclerView
import butterknife.BindView
import cn.dreamtobe.kpswitch.util.KeyboardUtil
import com.alibaba.android.vlayout.DelegateAdapter
import com.alibaba.android.vlayout.VirtualLayoutManager
import com.alibaba.android.vlayout.layout.LinearLayoutHelper
import com.google.android.material.tabs.TabLayout
import com.google.android.material.textfield.TextInputLayout
import com.huanchengfly.tieba.post.R
@ -26,8 +23,6 @@ import com.huanchengfly.tieba.post.adapters.HeaderDelegateAdapter
import com.huanchengfly.tieba.post.adapters.HeaderDelegateAdapter.Companion.NO_ICON
import com.huanchengfly.tieba.post.adapters.SearchHistoryAdapter
import com.huanchengfly.tieba.post.adapters.SingleLayoutDelegateAdapter
import com.huanchengfly.tieba.post.adapters.base.BaseSingleTypeDelegateAdapter
import com.huanchengfly.tieba.post.api.models.web.HotMessageListBean
import com.huanchengfly.tieba.post.components.AutoLineFeedLayoutManager
import com.huanchengfly.tieba.post.components.MyViewHolder
import com.huanchengfly.tieba.post.components.dividers.SpacesItemDecoration
@ -35,16 +30,13 @@ import com.huanchengfly.tieba.post.dpToPx
import com.huanchengfly.tieba.post.fragments.SearchForumFragment
import com.huanchengfly.tieba.post.fragments.SearchThreadFragment
import com.huanchengfly.tieba.post.fragments.SearchUserFragment
import com.huanchengfly.tieba.post.getColorCompat
import com.huanchengfly.tieba.post.interfaces.ISearchFragment
import com.huanchengfly.tieba.post.models.database.SearchHistory
import com.huanchengfly.tieba.post.toastShort
import com.huanchengfly.tieba.post.ui.theme.utils.ColorStateListUtils
import com.huanchengfly.tieba.post.utils.AnimUtil
import com.huanchengfly.tieba.post.utils.NavigationHelper
import com.huanchengfly.tieba.post.utils.ThemeUtil
import com.huanchengfly.tieba.post.utils.anim.animSet
import com.huanchengfly.tieba.post.utils.getIntermixedColorBackground
import com.huanchengfly.tieba.post.widgets.MyViewPager
import org.litepal.LitePal
@ -69,8 +61,6 @@ class NewSearchActivity : BaseActivity(), TabLayout.OnTabSelectedListener {
@BindView(R.id.bottom_app_bar)
lateinit var bottomAppBar: View
var hotMessageListBean: HotMessageListBean? = null
private var keyword: String? = null
set(value) {
field = value
@ -260,51 +250,6 @@ class NewSearchActivity : BaseActivity(), TabLayout.OnTabSelectedListener {
}
}
inner class HotTopicDelegateAdapter(
list: List<HotMessageListBean.HotMessageRetBean>? = null
) : BaseSingleTypeDelegateAdapter<HotMessageListBean.HotMessageRetBean>(
this,
LinearLayoutHelper(),
list
) {
override fun convert(viewHolder: MyViewHolder, item: HotMessageListBean.HotMessageRetBean, position: Int) {
viewHolder.setText(R.id.hot_order, "${position + 1}")
viewHolder.setText(R.id.hot_title, item.mulName)
viewHolder.setText(R.id.hot_desc, item.topicInfo.topicDesc)
val textView = viewHolder.getView<TextView>(R.id.hot_order)
if (position > 2) {
TextViewCompat.setTextAppearance(textView, R.style.TextAppearance_Bold)
textView.setTextColor(context.getColorCompat(R.color.tieba))
} else {
TextViewCompat.setTextAppearance(textView, R.style.TextAppearance_Bold_Italic)
textView.setTextColor(context.getColorCompat(R.color.red_accent))
}
viewHolder.setVisibility(R.id.hot_desc, View.GONE)
viewHolder.itemView.background = getIntermixedColorBackground(
context,
position,
itemCount,
positionOffset = 1,
colors = intArrayOf(R.color.default_color_card, R.color.default_color_divider),
radius = context.resources.getDimension(R.dimen.card_radius)
)
}
override fun getItemLayoutId(): Int {
return R.layout.item_hot_message_list
}
init {
val navigationHelper = NavigationHelper.newInstance(context)
setOnItemClickListener { _, item, _ ->
navigationHelper.navigationByData(
NavigationHelper.ACTION_URL,
"https://tieba.baidu.com/mo/q/hotMessage?topic_id=${item.mulId}&topic_name=${item.mulName}"
)
}
}
}
override fun onTabSelected(tab: TabLayout.Tab) {
val fragment = fragmentAdapter.fragments[tab.position]
if (fragment is Filterable) {

View File

@ -2,12 +2,11 @@ package com.huanchengfly.tieba.post.activities;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.huanchengfly.tieba.post.utils.TiebaUtil;
import me.imid.swipebacklayout.lib.app.SwipeBackActivity;
public class OKSignActivity extends SwipeBackActivity {
public class OKSignActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@ -113,9 +113,8 @@ class ReplyActivity : BaseActivity(), View.OnClickListener,
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setSwipeBackEnable(false)
if (ThemeUtil.THEME_TRANSLUCENT == ThemeUtil.getTheme(this)) {
val constraintLayout = findViewById(R.id.activity_reply_layout) as TintConstraintLayout
val constraintLayout = findViewById<TintConstraintLayout>(R.id.activity_reply_layout)
constraintLayout.setBackgroundTintResId(0)
ThemeUtil.setTranslucentBackground(constraintLayout)
}
@ -278,8 +277,8 @@ class ReplyActivity : BaseActivity(), View.OnClickListener,
}
})
mItemTouchHelper.attachToRecyclerView(insertView)
findViewById(R.id.activity_reply_root).setOnClickListener(this)
findViewById(R.id.activity_reply_layout).setOnClickListener(this)
findViewById<View>(R.id.activity_reply_root).setOnClickListener(this)
findViewById<View>(R.id.activity_reply_layout).setOnClickListener(this)
toolbar.setNavigationIcon(R.drawable.ic_reply_toolbar_round_close)
if (replyInfoBean!!.pid == null && replyInfoBean!!.floorNum == null) {
insertImageBtn.visibility = View.VISIBLE
@ -293,7 +292,7 @@ class ReplyActivity : BaseActivity(), View.OnClickListener,
if (replyInfoBean!!.replyUser != null) {
editText.hint = getString(R.string.hint_reply, replyInfoBean!!.replyUser)
}
val tabLayout = findViewById(R.id.activity_reply_emotion_tab) as TabLayout
val tabLayout = findViewById<TabLayout>(R.id.activity_reply_emotion_tab)
val emotionViewPagerAdapter = TabViewPagerAdapter()
val classicEmotionGridView = GridView(this)
val emojiEmotionGridView = GridView(this)
@ -430,9 +429,9 @@ class ReplyActivity : BaseActivity(), View.OnClickListener,
}
private fun initListener() {
val undo = findViewById(R.id.activity_reply_edit_undo) as TintImageView
val redo = findViewById(R.id.activity_reply_edit_redo) as TintImageView
val clear = findViewById(R.id.activity_reply_edit_clear) as TintImageView
val undo = findViewById<TintImageView>(R.id.activity_reply_edit_undo)
val redo = findViewById<TintImageView>(R.id.activity_reply_edit_redo)
val clear = findViewById<TintImageView>(R.id.activity_reply_edit_clear)
undo.setOnClickListener(this)
setEnabled(undo, false)
redo.setOnClickListener(this)

View File

@ -52,7 +52,6 @@ import com.huanchengfly.tieba.post.utils.preload.PreloadUtil
import com.huanchengfly.tieba.post.utils.preload.loaders.ThreadContentLoader
import com.huanchengfly.tieba.post.widgets.VideoPlayerStandard
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import me.imid.swipebacklayout.lib.SwipeBackLayout.SwipeListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
@ -174,13 +173,6 @@ class ThreadActivity : BaseActivity(), View.OnClickListener, IThreadMenuFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ThemeUtil.setTranslucentThemeBackground(findViewById(R.id.background))
swipeBackLayout.addSwipeListener(object : SwipeListener {
override fun onScrollStateChange(state: Int, scrollPercent: Float) {}
override fun onScrollOverThreshold() {}
override fun onEdgeTouch(edgeFlag: Int) {
exit()
}
})
refreshLayout.apply {
ThemeUtil.setThemeForSmartRefreshLayout(this)
refreshLayout.setOnRefreshListener {
@ -243,8 +235,8 @@ class ThreadActivity : BaseActivity(), View.OnClickListener, IThreadMenuFragment
setSupportActionBar(toolbar)
supportActionBar?.title = null
supportActionBar?.setDisplayHomeAsUpEnabled(true)
findViewById(R.id.thread_bottom_bar_agree).setOnClickListener(this)
findViewById(R.id.thread_reply_bar).setOnClickListener(this)
findViewById<View>(R.id.thread_bottom_bar_agree).setOnClickListener(this)
findViewById<View>(R.id.thread_reply_bar).setOnClickListener(this)
moreBtn.setOnClickListener(this)
toolbar.setOnClickListener(this)
threadHeaderAdapter.setOnToggleSeeLzListener {

View File

@ -204,7 +204,7 @@ class TranslucentThemeActivity : BaseActivity(), View.OnClickListener, OnSeekBar
private fun refreshBackground() {
mProgress.visibility = View.VISIBLE
if (mUri == null) {
findViewById(R.id.background).setBackgroundColor(Color.BLACK)
findViewById<View>(R.id.background).setBackgroundColor(Color.BLACK)
mProgress.visibility = View.GONE
return
}
@ -222,7 +222,8 @@ class TranslucentThemeActivity : BaseActivity(), View.OnClickListener, OnSeekBar
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
resource.alpha = alpha
val bitmap = ImageUtil.drawableToBitmap(resource)
findViewById(R.id.background).background = BitmapDrawable(resources, bitmap)
findViewById<View>(R.id.background).background =
BitmapDrawable(resources, bitmap)
mPalette = Palette.from(bitmap).generate()
mTranslucentThemeColorAdapter.setPalette(mPalette)
mSelectColor.visibility = View.VISIBLE
@ -291,7 +292,7 @@ class TranslucentThemeActivity : BaseActivity(), View.OnClickListener, OnSeekBar
appPreferences.translucentPrimaryColor = toString(themeColor)
ThemeUtils.refreshUI(this)
}
(findViewById(R.id.select_color_recycler_view) as RecyclerView).apply {
(findViewById<RecyclerView>(R.id.select_color_recycler_view)).apply {
addItemDecoration(HorizontalSpacesDecoration(0, 0, 12.dpToPx(), 12.dpToPx(), false))
layoutManager = MyLinearLayoutManager(
this@TranslucentThemeActivity,
@ -302,11 +303,11 @@ class TranslucentThemeActivity : BaseActivity(), View.OnClickListener, OnSeekBar
}
alpha = appPreferences.translucentBackgroundAlpha
blur = appPreferences.translucentBackgroundBlur
(findViewById(R.id.alpha) as SeekBar).apply {
(findViewById<SeekBar>(R.id.alpha)).apply {
progress = this@TranslucentThemeActivity.alpha
setOnSeekBarChangeListener(this@TranslucentThemeActivity)
}
(findViewById(R.id.blur) as SeekBar).apply {
(findViewById<SeekBar>(R.id.blur)).apply {
progress = this@TranslucentThemeActivity.blur
setOnSeekBarChangeListener(this@TranslucentThemeActivity)
}

View File

@ -0,0 +1,134 @@
package com.huanchengfly.tieba.post.ui.slideback;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import androidx.annotation.NonNull;
public class DefaultSlideView implements ISlideView {
private final int arrowWidth;
private final int width;
//private LinearGradient shader;
private final int height;
private Path bezierPath;
private Paint paint, arrowPaint;
private int backViewColor = 0xff000000;
private int arrowColor = Color.WHITE;
public DefaultSlideView(@NonNull Context context) {
width = Utils.d2p(context, 50);
height = Utils.d2p(context, 200);
arrowWidth = Utils.d2p(context, 4);
init(context);
}
public void setBackViewColor(int backViewColor) {
this.backViewColor = backViewColor;
}
public void setArrowColor(int arrowColor) {
this.arrowColor = arrowColor;
}
private void init(Context context) {
bezierPath = new Path();
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(backViewColor);
paint.setStrokeWidth(Utils.d2p(context, 1.5f));
arrowPaint = new Paint();
arrowPaint.setAntiAlias(true);
arrowPaint.setStyle(Paint.Style.FILL_AND_STROKE);
arrowPaint.setColor(arrowColor);
arrowPaint.setStrokeWidth(Utils.d2p(context, 1.5f));
arrowPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
public boolean scrollVertical() {
return true;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public void onDraw(Canvas canvas, float currentWidth, int orientation) {
float height = getHeight();
int maxWidth = getWidth();
float centerY = height / 2;
float progress = currentWidth / maxWidth;
if (progress == 0) {
return;
}
paint.setColor(backViewColor);
paint.setAlpha((int) (200 * progress));
//画半弧背景
/*
ps: 小点为起始点和结束点星号为控制点
·
|
*
*
|
·
|
*
*
|
·
*/
float bezierWidth = currentWidth / 2;
bezierPath.reset();
bezierPath.moveTo(0, 0);
bezierPath.cubicTo(0, height / 4f, bezierWidth, height * 3f / 8, bezierWidth, centerY);
bezierPath.cubicTo(bezierWidth, height * 5f / 8, 0, height * 3f / 4, 0, height);
canvas.drawPath(bezierPath, paint);
arrowPaint.setColor(arrowColor);
arrowPaint.setAlpha((int) (255 * progress));
//画箭头
float arrowStart, arrowEnd;
if (orientation == SlideBackView.ORIENTATION_RIGHT) {
arrowStart = currentWidth / 6;
arrowEnd = arrowStart + (arrowWidth * (progress - 0.7f) / 0.3f);
} else {
arrowStart = currentWidth / 6;
arrowEnd = arrowStart - (arrowWidth * (progress - 0.7f) / 0.3f);
}
if (progress <= 0.2) {
//ingore
} else if (progress <= 0.7f) {
//起初变长竖直过程
float newProgress = (progress - 0.2f) / 0.5f;
canvas.drawLine(arrowStart, centerY - arrowWidth * newProgress, arrowStart, centerY + arrowWidth * newProgress, arrowPaint);
} else {
//后面变形到完整箭头过程
canvas.drawLine(arrowEnd, centerY - arrowWidth, arrowStart, centerY, arrowPaint);
canvas.drawLine(arrowStart, centerY, arrowEnd, centerY + arrowWidth, arrowPaint);
}
}
}

View File

@ -0,0 +1,35 @@
package com.huanchengfly.tieba.post.ui.slideback;
import android.graphics.Canvas;
public interface ISlideView {
/**
* 是否可以垂直滑动
*
* @return
*/
boolean scrollVertical();
/**
* 宽度
*
* @return
*/
int getWidth();
/**
* 高度
*
* @return
*/
int getHeight();
/**
* 绘制
*
* @param canvas
* @param currentWidth 根据手指滑动得出的当前宽度最大值为getWidth())
* @param orientation 滑动方向
*/
void onDraw(Canvas canvas, float currentWidth, int orientation);
}

View File

@ -0,0 +1,5 @@
package com.huanchengfly.tieba.post.ui.slideback;
public interface OnSlide {
void onSlideBack();
}

View File

@ -0,0 +1,62 @@
package com.huanchengfly.tieba.post.ui.slideback;
import android.app.Activity;
import androidx.annotation.NonNull;
public class SlideBack {
private ISlideView slideView; //样式
private OnSlide onSlide; //滑动监听
private int canSlideWidth; //左边触发距离
public static SlideBack create() {
return new SlideBack();
}
/**
* 滑动返回样式
*
* @param slideView the slide view
* @return the slide back
*/
public SlideBack slideView(ISlideView slideView) {
this.slideView = slideView;
return this;
}
/**
* 左边开始触发距离
*
* @param canSlideWidth the can slide width
* @return the slide back
*/
public SlideBack canSlideWidth(int canSlideWidth) {
this.canSlideWidth = canSlideWidth;
return this;
}
/**
* 滑动触发监听
*
* @param onSlide the on slide
* @return the slide back
*/
public SlideBack onSlide(OnSlide onSlide) {
this.onSlide = onSlide;
return this;
}
public SlideControlLayout attachToActivity(@NonNull Activity activity) {
if (slideView == null) {
slideView = new DefaultSlideView(activity);
}
if (canSlideWidth == 0) {
canSlideWidth = Utils.d2p(activity, 18);
}
return new SlideControlLayout(activity, canSlideWidth, slideView, onSlide)
.attachToActivity(activity);
}
}

View File

@ -0,0 +1,96 @@
package com.huanchengfly.tieba.post.ui.slideback;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import androidx.annotation.NonNull;
@SuppressLint("ViewConstructor")
public class SlideBackView extends View {
public static final int ORIENTATION_LEFT = 0;
public static final int ORIENTATION_RIGHT = 1;
private static final DecelerateInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
private ISlideView slideView;
private ValueAnimator animator;
private float rate = 0;//曲线的控制点
private int orientation = 0;//滑动方向
SlideBackView(Context context, @NonNull ISlideView slideView) {
super(context);
setSlideView(slideView);
}
public ISlideView getSlideView() {
return slideView;
}
public SlideBackView setSlideView(@NonNull ISlideView slideView) {
this.slideView = slideView;
setLayoutParams(new SlideControlLayout.LayoutParams(slideView.getWidth(), slideView.getHeight()));
return this;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
slideView.onDraw(canvas, rate, orientation);
}
public void updateOrientation(int orientation) {
this.orientation = orientation;
}
public void updateRate(float updateRate, boolean hasAnim) {
if (updateRate > getWidth()) {
updateRate = getWidth();
}
if (rate == updateRate) {
return;
}
cancelAnim();
if (!hasAnim) {
rate = updateRate;
invalidate();
if (rate == 0) {
setVisibility(GONE);
} else {
setVisibility(VISIBLE);
}
}
animator = ValueAnimator.ofFloat(rate, updateRate);
animator.setDuration(200);
animator.addUpdateListener(animation -> {
rate = (Float) animation.getAnimatedValue();
postInvalidate();
if (rate == 0) {
setVisibility(GONE);
} else {
setVisibility(VISIBLE);
}
});
animator.setInterpolator(DECELERATE_INTERPOLATOR);
animator.start();
}
private void cancelAnim() {
if (animator != null && animator.isRunning()) {
animator.cancel();
}
}
@Override
protected void onDetachedFromWindow() {
cancelAnim();
if (rate != 0) {
rate = 0;
invalidate();
}
super.onDetachedFromWindow();
}
}

View File

@ -0,0 +1,139 @@
package com.huanchengfly.tieba.post.ui.slideback;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
@SuppressLint("ViewConstructor")
public class SlideControlLayout extends FrameLayout {
private final SlideBackView slideBackView;
private final OnSlide onSlide;
private final int canSlideWidth;
private final boolean enable = true;
private float downX;
private float moveX;
private boolean startDrag = false;
SlideControlLayout(@NonNull Context context, int canSlideWidth, ISlideView slideView, OnSlide onSlide) {
super(context);
this.canSlideWidth = canSlideWidth;
this.onSlide = onSlide;
slideBackView = new SlideBackView(context, slideView);
addView(slideBackView);
}
SlideControlLayout attachToActivity(@NonNull Activity activity) {
ViewParent parent = getParent();
if (parent instanceof ViewGroup) {
((ViewGroup) parent).removeView(this);
}
ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
decor.addView(this, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
return this;
}
private void onBack() {
if (onSlide == null) {
Utils.getActivityContext(getContext()).onBackPressed();
} else {
onSlide.onSlideBack();
}
}
private void setSlideViewY(SlideBackView view, int y) {
if (!view.getSlideView().scrollVertical()) {
scrollTo(0, 0);
return;
}
scrollTo(0, -(y - view.getHeight() / 2));
}
//region 手势控制
@Override
public boolean onInterceptTouchEvent(MotionEvent motionEvent) {
if (!enable) {
return false;
}
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
if (motionEvent.getRawX() <= canSlideWidth) {
return true;
}
if (motionEvent.getRawX() >= Utils.getScreenWidth(getContext()) - canSlideWidth) {
return true;
}
}
return super.onInterceptTouchEvent(motionEvent);
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
if (!enable) {
return super.onTouchEvent(motionEvent);
}
float currentX = motionEvent.getRawX();
switch (motionEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
float currentY = motionEvent.getRawY();
if (currentY > Utils.d2p(getContext(), 100)) {
if (currentX <= canSlideWidth) {
setRotationY(0f);
downX = currentX;
startDrag = true;
slideBackView.updateRate(0, false);
slideBackView.updateOrientation(SlideBackView.ORIENTATION_RIGHT);
setSlideViewY(slideBackView, (int) (motionEvent.getRawY()));
} else if (currentX >= Utils.getScreenWidth(getContext()) - canSlideWidth) {
setRotationY(180f);
downX = currentX;
startDrag = true;
slideBackView.updateRate(0, false);
slideBackView.updateOrientation(SlideBackView.ORIENTATION_LEFT);
setSlideViewY(slideBackView, (int) (motionEvent.getRawY()));
}
}
break;
case MotionEvent.ACTION_MOVE:
if (startDrag) {
moveX = currentX - downX;
if (Math.abs(moveX) <= slideBackView.getWidth() * 2) {
slideBackView.updateRate(Math.abs(moveX) / 2, false);
} else {
slideBackView.updateRate(slideBackView.getWidth(), false);
}
setSlideViewY(slideBackView, (int) (motionEvent.getRawY()));
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_OUTSIDE:
if (startDrag && Math.abs(moveX) >= slideBackView.getWidth() * 2) {
onBack();
slideBackView.updateRate(0, false);
} else {
slideBackView.updateRate(0, startDrag);
}
moveX = 0;
startDrag = false;
break;
}
return startDrag || super.onTouchEvent(motionEvent);
}
//endregion
}

View File

@ -0,0 +1,48 @@
package com.huanchengfly.tieba.post.ui.slideback;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.WindowManager;
import androidx.annotation.ColorInt;
public class Utils {
/**
* 屏幕宽度(像素)
*/
private static int screentwidth;
@ColorInt
static int setColorAlpha(int color, float alpha) {
color = Color.argb((int) (alpha * 255), Color.red(color), Color.green(color), Color.blue(color));
return color;
}
static int d2p(Context var0, float var1) {
DisplayMetrics var2 = var0.getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(1, var1, var2);
}
static int getScreenWidth(Context context) {
if (screentwidth > 0)
return screentwidth;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return screentwidth = outMetrics.widthPixels;
}
static Activity getActivityContext(Context context) {
if (context == null)
return null;
else if (context instanceof Activity)
return (Activity) context;
else if (context instanceof ContextWrapper)
return getActivityContext(((ContextWrapper) context).getBaseContext());
return null;
}
}