import android.content.Context; import android.graphics.Rect; import android.support.v4.view.ViewCompat; import android.support.v4.widget.ViewDragHelper; import android.util.AttributeSet; import android.view.*; import android.widget.FrameLayout; import com.hide.transitionstest.app.R; public class DragLayout extends FrameLayout { public static final int STATE_COLLAPSE = 1; public static final int STATE_EXPAND = 2; private ViewGroup mDragContent; private View mTouchView; private IDragListener iDragListener; private ViewDragHelper mDragHelper; private int mSlideMaxY; private int mTopPadding; private int mCurState = STATE_EXPAND; private ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() { @Override public boolean tryCaptureView(View child, int pointerId) { return child == mDragContent; } @Override public int clampViewPositionVertical(View child, int top, int dy) { return clampHeight(top); } @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { if (iDragListener != null) { iDragListener.onDragChange(dragPercent(top)); } } @Override public int getViewVerticalDragRange(View child) { return mSlideMaxY; } @Override public void onViewReleased(View releasedChild, float xvel, float yvel) { super.onViewReleased(releasedChild, xvel, yvel); int settleTop = mTopPadding; int slideRange = releasedChild.getTop() - mTopPadding; switch (mCurState) { case STATE_EXPAND: if (yvel >= 0 && slideRange > mSlideMaxY / 5) { settleTop = getHeight() - mTouchView.getMeasuredHeight(); } break; case STATE_COLLAPSE: slideRange = getHeight() - releasedChild.getTop() - mTouchView.getMeasuredHeight(); if (yvel > 0 || slideRange < mSlideMaxY / 5) { settleTop = getHeight() - mTouchView.getMeasuredHeight(); } break; } mDragHelper.settleCapturedViewAt(getLeft(), settleTop); invalidate(); } @Override public void onViewDragStateChanged(int state) { super.onViewDragStateChanged(state); switch (state) { case ViewDragHelper.STATE_IDLE: mCurState = mTopPadding == mDragContent.getTop() ? STATE_EXPAND : STATE_COLLAPSE; break; } } }; public DragLayout(Context context) { super(context); init(); } public DragLayout(Context context, AttributeSet attrs) { super(context, attrs); init(); } public DragLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { removeAllViews(); mDragContent = (ViewGroup) LayoutInflater.from(getContext()).inflate(R.layout.drag_layout, null); mTouchView = mDragContent.findViewById(R.id.drag); addView(mDragContent); getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(this); int height = getContext().getResources().getDisplayMetrics().heightPixels * 2 / 3; ViewGroup.LayoutParams params = mDragContent.getLayoutParams(); params.height = height; mDragContent.setLayoutParams(params); mSlideMaxY = height - mTouchView.getMeasuredHeight(); return false; } }); mDragHelper = ViewDragHelper.create(this, 1.0f, mCallback); // ViewGroupCompat.setMotionEventSplittingEnabled(this, false); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean intercept; try { intercept = mDragHelper.shouldInterceptTouchEvent(ev); } catch (Exception e) { e.printStackTrace(); intercept = false; } return intercept; } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int height = getContext().getResources().getDisplayMetrics().heightPixels; int childHeight = height * 2 / 3; Rect statusBarRect = new Rect(); getWindowVisibleDisplayFrame(statusBarRect); int statusBar = statusBarRect.top; height -= statusBar; mTopPadding = height - childHeight; mDragContent.layout(left, top + mTopPadding, right, bottom); } @Override public boolean onTouchEvent(MotionEvent event) { boolean onTouch = true; try { mDragHelper.processTouchEvent(event); } catch (Exception e) { e.printStackTrace(); onTouch = false; } return onTouch; } private int clampHeight(int top) { return Math.max(mTopPadding, Math.min(top, mSlideMaxY + mTopPadding)); } private float dragPercent(int top) { return 1 - (top - mTopPadding) * 1.0f / mSlideMaxY; } @Override public void computeScroll() { super.computeScroll(); if (mDragHelper.continueSettling(true)) { ViewCompat.postInvalidateOnAnimation(this); } } public void setOnDragListener(IDragListener l) { iDragListener = l; } public interface IDragListener { void onDragChange(float fraction); } }
drag_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drag_root" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FAFAFA" android:orientation="vertical"> <TextView android:id="@+id/drag" android:layout_width="match_parent" android:layout_height="50dp" android:background="#000" android:gravity="center" android:text="拖 拽 这 里" android:textColor="#fff" android:textSize="16sp" /> <ScrollView android:id="@+id/drag_content" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:text="1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n15\n15\n15\n15\n15\n15\n15\n15\n15\n15\n15\n15\n" android:textSize="16sp" /> </ScrollView> </LinearLayout>
用法:
import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.transitions.everywhere.TransitionManager; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; import com.hide.transitionplayer.lib.TransitionPlayer; import com.hide.transitionstest.app.widget.DragLayout; /** * * * * * * * * * * * * * * * * * * * * * * * * Created by zhaoyiding * Date: 15/10/12 * * * * * * * * * * * * * * * * * * * * * * * **/ public class DragTransitionActivity extends Activity implements DragLayout.IDragListener { private View mDimView; private ViewGroup mSceneRoot; private TransitionPlayer mTransitionPlayer = new TransitionPlayer(); private ImageView mHeadImg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drag_transition); // mDimView = findViewById(R.id.dimView); // mSceneRoot = (ViewGroup) findViewById(R.id.scene_root); // mHeadImg = (ImageView) findViewById(R.id.headimg); // // initImg(); final DragLayout mDragLayout = (DragLayout) findViewById(R.id.drag_layout); mDragLayout.setOnDragListener(this); // mDragLayout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { // @Override // public boolean onPreDraw() { // mDragLayout.getViewTreeObserver().removeOnPreDrawListener(this); // TransitionManager.beginDelayedTransition(mSceneRoot, mTransitionPlayer); // ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) mHeadImg.getLayoutParams(); // marginParams.topMargin = 0; // mHeadImg.setLayoutParams(marginParams); // mHeadImg.setAlpha(1.0f); // // mHeadImg.post(new Runnable() { // @Override // public void run() { // mTransitionPlayer.setCurrentFraction(1.0f); // // } // }); // return false; // } // }); } // private void initImg() { // int height = getResources().getDisplayMetrics().heightPixels / 3 - IndexActivity.sStatusBarHeight; // FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height); // params.topMargin = -height * 2 / 3; // mHeadImg.setLayoutParams(params); // mHeadImg.setAlpha(0f); // } // // private void setDimViewAlpha(float fraction) { // mDimView.setBackgroundColor(Color.argb((int) (255 * fraction), 0, 0, 0)); // mTransitionPlayer.setCurrentFraction(fraction); // } @Override public void onDragChange(float fraction) { // setDimViewAlpha(fraction); } }
布局activity_drag_transition.xml:
<?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- <View android:id="@+id/dimView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" /> <FrameLayout android:id="@+id/scene_root" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/headimg" android:layout_width="match_parent" android:layout_height="100dp" android:background="#f8f8f8" android:scaleType="centerInside" android:src="@mipmap/google_logo" /> </FrameLayout> --> <com.hide.transitionstest.app.widget.DragLayout android:id="@+id/drag_layout" android:layout_width="match_parent" android:layout_height="match_parent" /> </merge>
仿豌豆荚ViewPager下拉:DragTopLayout
http://www.open-open.com/lib/view/open1422430262923.html