仿二手车汽车之家折叠列表效果
2018-12-09 本文已影响0人
刘孙猫咪

public class ViewDropList extends FrameLayout {
private ViewDragHelper dragHelper;
private View listView;
private boolean mMenuIsOpen = false;
//头部高度
private int headerHeight;
public ViewDropList(Context context) {
this(context, null);
}
public ViewDropList(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ViewDropList(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
dragHelper = ViewDragHelper.create(this, callback);
}
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
//在这个方法中可以指定哪个字view可以拖动,返回true代表全部子view可以拖动
return listView == child;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
//垂直拖动的时候回调
//设定拖动范围
if (top <= 0) {
top = 0;
}
if (top >= headerHeight) {
top = headerHeight;
}
return top;
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
//横向拖动的时候回调 将值改为return left
return super.clampViewPositionHorizontal(child, left, dx);
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
//拖动松手的时候会回调
if (listView == releasedChild) {
int listViewTop = listView.getTop();
if (listViewTop > headerHeight / 2) {
//滚动打开
dragHelper.settleCapturedViewAt(0, headerHeight);
mMenuIsOpen = true;
} else {
//滚动关闭
dragHelper.settleCapturedViewAt(0, 0);
mMenuIsOpen = false;
}
invalidate();
}
}
};
private float downY;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// //判断是否打开,打开的话直接将事件拦截掉
// if(mMenuIsOpen){
// // 向下滑动 && 滚动到了顶部,拦截不让ListView做处理
// return true;
// }
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//按下的时候记录下按下坐标
downY = ev.getY();
dragHelper.processTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
//获取移动是的坐标
float evY = ev.getY();
if (evY - downY > 0 && !canChildScrollUp()) {
// 向下滑动 && 滚动到了顶部,拦截不让ListView做处理
return true;
} else {
if (listView instanceof RecyclerView) {
//如果是打开请recycleview已经滚动到最底部了,将事件拦截掉
if (mMenuIsOpen && isVisBottom((RecyclerView) listView)) {
return true;
}
}
}
break;
}
return super.onInterceptTouchEvent(ev);
}
/**
* 判断recycleview是否滚动到底部
* @param recyclerView
* @return
*/
private boolean isVisBottom(RecyclerView recyclerView) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//屏幕中最后一个可见子项的position
int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition();
//当前屏幕所看到的子项个数
int visibleItemCount = layoutManager.getChildCount();
//当前RecyclerView的所有子项个数
int totalItemCount = layoutManager.getItemCount();
//RecyclerView的滑动状态
int state = recyclerView.getScrollState();
if (visibleItemCount > 0 && lastVisibleItemPosition == totalItemCount - 1 && state == recyclerView.SCROLL_STATE_IDLE) {
return true;
} else {
return false;
}
}
/**
* @return Whether it is possible for the child view of this layout to
* scroll up. Override this if the child view is a custom view.
* 判断View是否滚动到了最顶部,还能不能向上滚
*/
public boolean canChildScrollUp() {
if (android.os.Build.VERSION.SDK_INT < 14) {
if (listView instanceof AbsListView) {
final AbsListView absListView = (AbsListView) listView;
return absListView.getChildCount() > 0
&& (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0)
.getTop() < absListView.getPaddingTop());
} else {
return ViewCompat.canScrollVertically(listView, -1) || listView.getScrollY() > 0;
}
} else {
return ViewCompat.canScrollVertically(listView, -1);
}
}
@Override
public void computeScroll() {
super.computeScroll();
if (dragHelper.continueSettling(true)) {
invalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
dragHelper.processTouchEvent(event);
return true;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
View childAt = getChildAt(0);
headerHeight = childAt.getMeasuredHeight();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//该方法在加载完布局会调用
//获取子view
int childCount = getChildCount();
if (childCount != 2) {
return;
}
//获取列表view
listView = getChildAt(1);
}
}
<?xml version="1.0" encoding="utf-8"?>
<com.lsm.view_day14.ViewDropList xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lsm.view_day14.MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:text="头部内容"
android:background="@color/colorAccent"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"/>
</com.lsm.view_day14.ViewDropList>
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<String> list=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for(int i=0;i<20;i++){
list.add("item"+i);
}
recyclerView= (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DropListAdapter adapter=new DropListAdapter();
recyclerView.setAdapter(adapter);
}
class DropListAdapter extends RecyclerView.Adapter<DropListAdapter.DropHolder>{
@Override
public DropHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_layout, parent, false);
DropHolder holder=new DropHolder(view);
return holder;
}
@Override
public void onBindViewHolder(DropHolder holder, int position) {
final String txt = list.get(position);
holder.tvItem.setText(txt);
holder.tvItem.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,txt,Toast.LENGTH_LONG).show();
}
});
}
@Override
public int getItemCount() {
return list.size();
}
class DropHolder extends RecyclerView.ViewHolder{
public TextView tvItem;
public DropHolder(View itemView) {
super(itemView);
tvItem= (TextView) itemView.findViewById(R.id.tv_item);
}
}
}
}