概述
刚最近写了个浮动按钮和大家分享一下,只是在FloatingActionButton基础上做了点扩展,所以滑动范围仅限于父控件范围
使用效果
和正常用FloatingActionButton就可以了,加了个扩展属性scrollEnable,xml使用如下:
<com.zcx.www.scrollfloatingbuttonlib.ScrollFloatinigButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:scrollEnable="true"
app:srcCompat="@android:drawable/ic_dialog_email" />
java代码都是自动生成的,还是贴一下吧
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
先看看效果
代码实现
主要是处理一下滑动就好了
/**
* author: zhouchaoxiang
* date: 2019/4/25
* explain:可滑动的floatActionButton
*/
public class ScrollFloatinigButton extends FloatingActionButton {
private static final String TAG = "ScrollFloatinigButton";
private float mX;
private float mY;
private int mParentWidth;
private int mParentHeight;
private boolean mScrollEnable = true;
private int mScrollLeft;
private int mScrollTop;
private int mRight;
private int mScrollRight;
private int mScrollBottom;
private boolean hasScroll;
boolean isScroll = false;
public ScrollFloatinigButton(Context context) {
this(context, null);
}
public ScrollFloatinigButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ScrollFloatinigButton(Context context, AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ScrollFloatinigButton);
mScrollEnable = ta.getBoolean(R.styleable.ScrollFloatinigButton_scrollEnable, true);
ta.recycle();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
//防止布局重置时重置ScrollFloatinigButton的位置
ViewParent parent = getParent();
if (parent instanceof ViewGroup) {
((ViewGroup) getParent()).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 (hasScroll && mScrollRight != 0 && mScrollBottom != 0)
layout(mScrollLeft, mScrollTop, mScrollRight, mScrollBottom);
}
});
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (getParent() instanceof ViewGroup) {
mParentWidth = ((ViewGroup) getParent()).getWidth();
mParentHeight = ((ViewGroup) getParent()).getHeight();
}
Log.i(TAG, "onSizeChanged: ");
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (!mScrollEnable) return super.onTouchEvent(ev);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mX = ev.getX();
mY = ev.getY();
super.onTouchEvent(ev);
return true;
case MotionEvent.ACTION_MOVE:
int scaledTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
float x = ev.getX();
float y = ev.getY();
x = x - mX;
y = y - mY;
if (Math.abs(scaledTouchSlop) < Math.abs(x) || Math.abs(scaledTouchSlop) < Math.abs(y)) {
isScroll = true;
}
if (isScroll) {
mScrollLeft = (int) (getX() + x);
mScrollTop = (int) (getY() + y);
mScrollRight = (int) (getX() + getWidth() + x);
mScrollBottom = (int) (getY() + getHeight() + y);
//防止滑出父界面
if (mScrollLeft < 0 || mScrollRight > mParentWidth) {
mScrollLeft = (int) getX();
mScrollRight = (int) getX() + getWidth();
}
if (mScrollTop < 0 || mScrollBottom > mParentHeight) {
mScrollTop = (int) getY();
mScrollBottom = (int) getY() + getHeight();
}
layout(mScrollLeft, mScrollTop, mScrollRight, mScrollBottom);
hasScroll = true;
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (isScroll) {
isScroll = false;
setPressed(false);//重置点击状态
return true;
}
break;
}
return super.onTouchEvent(ev);
}
public void setScrollEnable(boolean scrollEnable) {
mScrollEnable = scrollEnable;
}
public boolean isScrollEnable() {
return mScrollEnable;
}
}
在values目录下创建attrs.xml文件,添加如下属性
<resources>
<declare-styleable name="ScrollFloatinigButton">
<attr name="scrollEnable" format="boolean" />
</declare-styleable>
</resources>
大功告成.
总结
这里就总结一下滑动了几种方式吧.
- scrollTo和scrollBy
可滑动view里面的内容,scrollTo为绝对坐标,scrollBy为相对于view的当前坐标 - LayoutParams
可滑动view本身,范围限view的父控件范围,这种方式通过设置LayoutParams的margin值达到移动view的效果,可滑动view本身. - view.layout()和offsetLeftAndRight或offsetTopAndBottom
可滑动view本身,范围限view的父控件范围,重新设置view的四个顶点坐标来达到滑动view的效果 - 属性动画
可滑动view到任意位置,具体如下
view.setTranslationX();
view.setTranslationY();