//旋转与透明跟随效果
mDrawerView.setAlpha(1-mDragOffset);
// mRotateView.setRotation((1-mDragOffset)*180);
requestLayout();
if (onDrawerStatusChanged != null) {
onDrawerStatusChanged.onChanged(mParentHeight,top);
}
// if(onDrawerStatusChanged !=null){
// if(mDragOffset == 0 || mDragOffset == 1){
// onDrawerStatusChanged.onChanged(mParentHeight,top);
// }
// }
}
}
public interface OnDrawerStatusChanged{
void onChanged(int parentHeight, int drawerTop);
}
public void maximize()
{
smoothSlideTo(0.0f);
}
public void minimize()
{
smoothSlideTo(1.0f);
}
private boolean smoothSlideTo(float slideOffset) {
final int topBound = mParentHeight - mDrawerHeight - mBottomHeight;
int y = (int) (topBound + slideOffset * mDrawerHeight);
if(mDragHelper.smoothSlideViewTo(mDrawerView, mDrawerView.getLeft(), y))
{
ViewCompat.postInvalidateOnAnimation(this);
return true;
}
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
int act = MotionEventCompat.getActionMasked(event);
// final int action = event.getAction();
switch (act) {
//由于很多情况不能拦截事件,这种时候系统不会调用onTouchEvent()
// 手动把事件传递给mDragHelper.processTouchEvent
case MotionEvent.ACTION_DOWN:
mInitialX = event.getX();
mInitialY = event.getY();
//Feed the down event to the detector so it has
// context when/if dragging begins
// mDetector.onTouchEvent(event);
mDragHelper.processTouchEvent(event);
isUnderBottomView = mDragHelper.isViewUnder(mBottomView, (int)mInitialX, (int)mInitialY);
isUnderDrawerView = mDragHelper.isViewUnder(mDrawerView, (int)mInitialX, (int)mInitialY);
break;
case MotionEvent.ACTION_POINTER_DOWN:
mDragHelper.processTouchEvent(event) ;
break;
case MotionEvent.ACTION_POINTER_UP:
mDragHelper.processTouchEvent(event) ;
break;
case MotionEvent.ACTION_MOVE:
final float x = event.getX();
final float y = event.getY();
final int yDiff = (int) Math.abs(y - mInitialY);
final int xDiff = (int) Math.abs(x - mInitialX);
//Verify that either difference is enough to be a drag
if ((yDiff > mTouchSlop || xDiff > mTouchSlop) && (isUnderBottomView || isUnderDrawerView) ){
//Start capturing events
return true;
}
break;
}
//父类是viewgroup,返回的false
return super.onInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
//down事件返回false,让其底部的平行层级的view能够接收到点击事件
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
return false;
case MotionEvent.ACTION_UP:
return false;
//只有当手指达到拖动阈值时this才确定消耗此系列事件
//若未达到阈值也返回true,则与其平行的view不会收到click事件
case MotionEvent.ACTION_MOVE:
final float x = event.getX();
final float y = event.getY();
final int yDiff = (int) Math.abs(y - mInitialY);
final int xDiff = (int) Math.abs(x - mInitialX);
//Verify that either difference is enough to be a drag
if ((yDiff > mTouchSlop || xDiff > mTouchSlop) && (isUnderBottomView || isUnderDrawerView) ){
//Start capturing events
return true;
}
break;
}
return false;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mBottomView = findViewById(R.id.layout_bottom_bar);
mDrawerView = findViewById(R.id.layout_price_detail);
// mRotateView = findViewById(R.id.img_spread_out);
mBottomView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
maximize();
}
});
mDrawerView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
minimize();
}
});
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec,heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
mParentHeight = this.getHeight();
mBottomHeight = mBottomView.getMeasuredHeight();
mDrawerHeight = mDrawerView.getMeasuredHeight();
// Log.d(TAG, “onLayout: drawHeight:”+drawHeight);
mBottomView.layout(l,mParentHeight - mBottomHeight,r,b);
if(mCurTop == -1){
mCurTop = mParentHeight - mBottomHeight;
}
mDrawerView.layout(l,mCurTop,r,mCurTop + mDrawerHeight);
}
@Override
public void computeScroll() {
if(mDragHelper.continueSettling(true))
{
ViewCompat.postInvalidateOnAnimation(this);
}
}
}
layout布局中使用这个自定义抽屉view即可,第一个LinearLayout是抽屉内容,第二个LinearLayout是固定底部把手
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“match_parent” android:layout_height=“match_parent”>
<com.tianxin.shanghuact.BottomDrawerLayout
android:id=“@+id/bottom_drawer_layout”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>
<LinearLayout
android:id=“@+id/layout_price_detail”
android:layout_width=“match_parent”
android:background=“@color/colorPrimary”
android:orientation=“horizontal”
android:layout_height=“180dp”>
<LinearLayout
android:id=“@+id/layout_bottom_bar”
android:layout_width=“match_parent”
android:background=“@color/transparent”
android:orientation=“horizontal”
最后
在此为大家准备了四节优质的Android高级进阶视频:
架构师项目实战——全球首批Android开发者对Android架构的见解
附相关架构及资料
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
ndroid架构的见解**
附相关架构及资料
[外链图片转存中…(img-FH8GmqZm-1714393129640)]
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!