首先看效果图
接下来看我们的布局文件
代码如下
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mvvm.md.Main2Activity">
<android.support.v7.widget.RecyclerView
android:id="@+id/rc_main"
app:layout_scrollFlags="scroll|enterAlways|snap"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!--app:layout_behavior="@string/appbar_scrolling_view_behavior"-->
<android.support.design.widget.FloatingActionButton
app:layout_anchor="@id/rc_main"
app:layout_behavior="com.mvvm.md.ABbehavior"
app:layout_anchorGravity="bottom|right"
android:layout_width="wrap_content"
android:layout_margin="30dp"
android:layout_height="wrap_content"/>
</android.support.design.widget.CoordinatorLayout>
这里我们需要注意以下几点
1. app:layout_behavior=”com.mvvm.md.ABbehavior”是我们自定义的behavior路径
2. 我们的recyclerview要定义如下属性 app:layout_scrollFlags=”scroll|enterAlways|snap”
3. 我们要控制的FloatingActionButton以及RecyclerView要是CoordinatorLayout的子view不能为子view的子view也就是说这两个布局只能是CoordinatorLayout的儿子
接下来是我们在Activity中的调用逻辑
代码如下
final List<String> items = new ArrayList<>();
for (int i = 0; i < 50; i++) {
items.add("-----" + i + "-----");
}
RecyclerView rc_main = (RecyclerView) findViewById(R.id.rc_main);
rc_main.setLayoutManager(new LinearLayoutManager(Main2Activity.this, LinearLayoutManager.VERTICAL, false));
rc_main.setAdapter(new RecyclerView.Adapter() {
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(View.inflate(Main2Activity.this, R.layout.item_vg, null));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((TextView) holder.itemView.findViewById(R.id.tv_content)).setText(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
});
class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView) {
super(itemView);
}
}
代码很简单只是给recyclerview设置了适配器并没有做别的事情
接下来使我们的自定义的behavior
代码也很简单如下
public class ABbehavior extends FloatingActionButton.Behavior {
boolean isOut = false;//是否滑出界面
boolean isAnimEnd = true;//动画是否结束
public ABbehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
Log.e("---------", dyConsumed + "");
if (dyConsumed > 0) {//手指向上滑动按钮向下滑动
if (!isOut && isAnimEnd) {
int dy = child.getMeasuredHeight() + ((CoordinatorLayout.LayoutParams) child.getLayoutParams()).bottomMargin;
child.animate().translationY(dy)
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
isAnimEnd = false;
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimEnd = true;
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
})
.setDuration(500).start();
isOut = true;
}
} else {
if (isOut && isAnimEnd) {
child.animate().translationY(0).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
isAnimEnd = false;
}
@Override
public void onAnimationEnd(Animator animation) {
isAnimEnd = true;
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}).setDuration(500).start();
isOut = false;
}
}
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
}
}