下面列出了android.support.v4.view.ViewPropertyAnimatorListener#android.support.design.widget.CoordinatorLayout 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void showAccountNotExistDialog(BaseInvokeModel baseInvokeModel, BaseInfo baseInfo) {
bottomSheetDialog = new BottomSheetDialog(MainActivity.this);
DialogAuthorAccountNotExistBinding binding = DataBindingUtil.inflate(LayoutInflater.from(Utils.getContext()), R.layout.dialog_author_account_not_exist, null, false);
bottomSheetDialog.setContentView(binding.getRoot());
// 设置dialog 完全显示
View parent = (View) binding.getRoot().getParent();
BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
binding.getRoot().measure(0, 0);
behavior.setPeekHeight(binding.getRoot().getMeasuredHeight());
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
params.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
parent.setLayoutParams(params);
bottomSheetDialog.setCanceledOnTouchOutside(false);
final ConfrimDialogViewModel confrimDialogViewModel = new ConfrimDialogViewModel(getApplication());
confrimDialogViewModel.setBaseInfo(baseInvokeModel, baseInfo);
binding.setViewModel(confrimDialogViewModel);
bottomSheetDialog.show();
}
@Test
public void dependsOnHeight() {
SimpleViewBehavior behavior = new SimpleViewBehavior.Builder()
.dependsOn(firstView.getId(), SimpleViewBehavior.DEPEND_TYPE_HEIGHT)
.targetValue(100)
.targetX(100)
.targetY(200)
.build();
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(320, 200);
params.setBehavior(behavior);
secondView.setLayoutParams(params);
// resize first view's height
CoordinatorLayout.LayoutParams resizeParams = new CoordinatorLayout.LayoutParams(firstView.getLayoutParams());
resizeParams.height = 100;
firstView.setLayoutParams(resizeParams);
coordinatorLayout.requestLayout();
assertEquals(1.0f, secondView.getCurrentPercent());
}
private void settle(CoordinatorLayout parent, final View child) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "settle: ");
}
if (mFlingRunnable != null) {
child.removeCallbacks(mFlingRunnable);
mFlingRunnable = null;
}
mFlingRunnable = new FlingRunnable(parent, child);
if (child.getTranslationY() < getHeaderOffsetRange() / 3.0f) {
mFlingRunnable.scrollToClosed(DURATION_SHORT);
} else {
mFlingRunnable.scrollToOpen(DURATION_SHORT);
}
}
public void show() {
mSnackBar.show();
if (mBuilder.mSwipeToDismiss) return;
if (mSnackBar.getView().getLayoutParams() instanceof CoordinatorLayout.LayoutParams) {
mSnackBar.getView().getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mSnackBar.getView().getViewTreeObserver().removeOnPreDrawListener(this);
((CoordinatorLayout.LayoutParams) mSnackBar.getView().getLayoutParams()).setBehavior(null);
return true;
}
});
}
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, CircleImageView child, View dependency) {
//初始化一些基础参数
init(parent, child, dependency);
//计算比例
if (child.getY() <= 0) return false;
float percent = (child.getY() - mToolBarHeight) / (mStartAvatarY - mToolBarHeight);
if (percent < 0) {
percent = 0;
}
if (this.percent == percent || percent > 1) return true;
this.percent = percent;
//设置头像的大小
ViewCompat.setScaleX(child, percent);
ViewCompat.setScaleY(child, percent);
return false;
}
private void initScrollTarget(final CoordinatorLayout coordinatorLayout, final AppBarLayout child) {
Utils.log("initScrollTarget | %b", vScrollTarget != null);
if (vScrollTarget != null) {
long tag = getViewTag(vScrollTarget, true);
if (!mScrollTargets.contains(tag)) {
mScrollTargets.add(tag);
OnScrollListener listener = new OnScrollListener() {
@Override
public void onScrollChanged(View view, int x, int y, int dx, int dy, boolean accuracy) {
if (view == vScrollTarget) {
BaseBehavior.this.onScrollChanged(coordinatorLayout, child, view, y, dy, accuracy);
}
}
};
if (vScrollTarget instanceof NestedScrollView) {
ObservableNestedScrollView.newInstance((NestedScrollView) vScrollTarget, mOverrideOnScrollListener, listener);
} else if (vScrollTarget instanceof RecyclerView) {
ObservableRecyclerView.newInstance((RecyclerView) vScrollTarget, listener);
}
}
}
}
@Override
public boolean onLayoutChild(CoordinatorLayout parent, LinearLayout child, int layoutDirection) {
parent.onLayoutChild(child, layoutDirection);
if (isFirst) {
isFirst = false;
if (oLy == 0) {
oLy = child.getY() + child.getHeight();
}
for (int i = 0; i < parent.getChildCount(); i++) {
View view = parent.getChildAt(i);
if (view instanceof AppBarLayout) {
height = view.getMeasuredHeight();
break;
}
}
child.setY(oLy);
}
return true;
}
private Snackbar.SnackbarLayout getSnackBarInstance(CoordinatorLayout parent, V child) {
final List<View> dependencies = parent.getDependencies(child);
for (int i = 0, z = dependencies.size(); i < z; i++) {
final View view = dependencies.get(i);
if (view instanceof Snackbar.SnackbarLayout) {
return (Snackbar.SnackbarLayout) view;
}
}
return null;
}
@Override
public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
if (dependency instanceof AppBarLayout) {
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
int distanceToScroll = fab.getHeight() + fabBottomMargin;
float ratio = (float) dependency.getY() / (float) toolbarHeight;
fab.setTranslationY(-distanceToScroll * ratio);
}
return true;
}
public static <V extends View> MergedAppBarLayoutBehavior from(V view) {
ViewGroup.LayoutParams params = view.getLayoutParams();
if (!(params instanceof CoordinatorLayout.LayoutParams)) {
throw new IllegalArgumentException("The view is not a child of CoordinatorLayout");
}
CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params)
.getBehavior();
if (!(behavior instanceof MergedAppBarLayoutBehavior)) {
throw new IllegalArgumentException("The view is not associated with " +
"MergedAppBarLayoutBehavior");
}
return (MergedAppBarLayoutBehavior) behavior;
}
@Override
public AppBarLayout createViewInstance(ThemedReactContext context) {
AppBarLayout view = new AppBarLayout(context);
int width = CoordinatorLayout.LayoutParams.MATCH_PARENT;
int height = CoordinatorLayout.LayoutParams.WRAP_CONTENT;
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(width, height);
params.setBehavior(new ScrollingAppBarLayoutBehavior(context, null));
view.setLayoutParams(params);
scrollingBehavior = ScrollingAppBarLayoutBehavior.from(view);
return view;
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
shouldBlockNestedScroll = false;
if (isFlinging) {
shouldBlockNestedScroll = true;
}
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
stopAppbarLayoutFling(child); //手指触摸屏幕的时候停止fling事件
break;
}
return super.onInterceptTouchEvent(parent, child, ev);
}
public static void resetViewBottomMargin(@Nullable View view) {
if (view == null) return;
Context context = ContextHelper.getBaseContext(view);
int orientation = context.getResources().getConfiguration().orientation;
if (!(view.getLayoutParams() instanceof CoordinatorLayout.LayoutParams))
return;
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) view.getLayoutParams();
int left = params.leftMargin;
int right = params.rightMargin;
int bottom = params.bottomMargin;
int top = params.topMargin;
int bottomNavBar = 0;
int rightNavBar = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
boolean tabletMode = context.getResources().getBoolean(R.bool.android_helpers_tablet_mode);
if (tabletMode || orientation == Configuration.ORIENTATION_PORTRAIT) {
bottomNavBar = WindowHelper.getNavigationBarHeight(context);
} else {
rightNavBar = WindowHelper.getNavigationBarHeight(context);
}
}
int navBar = WindowHelper.getNavigationBarHeight(context);
if ((bottom > bottomNavBar) && ((bottom - navBar) > 0))
bottom -= navBar;
if ((right > rightNavBar) && ((right - navBar) > 0))
right -= navBar;
params.setMargins(left, top, (right + rightNavBar), (bottom + bottomNavBar));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
params.setMarginEnd((right + rightNavBar));
}
view.setLayoutParams(params);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int
dxUnconsumed, int dyUnconsumed, int type) {
if (!mShouldBlockNestedScroll) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
}
}
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target,
float velocityX, float velocityY) {
return target == mNestedScrollingChildRef.get() &&
(mState != STATE_EXPANDED ||
super.onNestedPreFling(coordinatorLayout, child, target,
velocityX, velocityY));
}
@Override
protected void initFabBehavior() {
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FabOnScroll behavior = new FabOnScroll(fab.getContext(), null);
params.setBehavior(behavior);
params.gravity = Gravity.CENTER_VERTICAL | Gravity.END;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
params.setMargins(App.px16, App.px16, App.px16, App.px16);
}
fab.requestLayout();
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
//注意看ViewCompat.TYPE_TOUCH
//返回1时,表示当前target处于非touch的滑动,
//该bug的引起是因为appbar在滑动时,CoordinatorLayout内的实现NestedScrollingChild2接口的滑动子类还未结束其自身的fling
//所以这里监听子类的非touch时的滑动,然后block掉滑动事件传递给AppBarLayout
if (type == 1) {
mIsFlinging = true;
}
if (!mShouldBlockNestedScroll) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
}
}
public static <V extends View> ScaleDownShowBehavior from(V view) {
ViewGroup.LayoutParams params = view.getLayoutParams();
if (!(params instanceof CoordinatorLayout.LayoutParams)) {
throw new IllegalArgumentException("The view is not a child of CoordinatorLayout");
}
CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) params).getBehavior();
if (!(behavior instanceof ScaleDownShowBehavior)) {
throw new IllegalArgumentException("The view is not associated with ScaleDownShowBehavior");
}
return (ScaleDownShowBehavior) behavior;
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout,
View child, View target,
int dx, int dy,
int[] consumed) {
//Determine direction changes here
if (dy > 0 && mScrollingDirection != DIRECTION_UP) {
mScrollingDirection = DIRECTION_UP;
mScrollDistance = 0;
} else if (dy < 0 && mScrollingDirection != DIRECTION_DOWN) {
mScrollingDirection = DIRECTION_DOWN;
mScrollDistance = 0;
}
}
public void hide() {
if (mBehavior != null) mBehavior.hideView(this, (int) getBarHeight(), true);
else if (getParent() != null && getParent() instanceof CoordinatorLayout) {
mNeedHide = true;
mAnimateHide = true;
} else scrollDown();
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
if (dy > 0 && mTotalDy < 0) {
mTotalDy = 0;
mPreScrollDirection = ScrollDirection.SCROLL_DIRECTION_UP;
onNestedVerticalPreScroll(coordinatorLayout, child, target, dx, dy, consumed, mPreScrollDirection);
} else if (dy < 0 && mTotalDy > 0) {
mTotalDy = 0;
mPreScrollDirection = ScrollDirection.SCROLL_DIRECTION_DOWN;
onNestedVerticalPreScroll(coordinatorLayout, child, target, dx, dy, consumed, mPreScrollDirection);
}
mTotalDy += dy;
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide();
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
if (BuildConfig.DEBUG) {
Log.d(TAG, "onStartNestedScroll: nestedScrollAxes="+nestedScrollAxes);
}
boolean canScroll = canScroll(child, 0);
return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 && canScroll && !isClosed(child);
// return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 && canScroll(child, 0) ;
}
/**
* @param duration open animation duration
*/
public void openPager(int duration) {
View child = mChild.get();
CoordinatorLayout parent = mParent.get();
if (isClosed() && child != null) {
if (mFlingRunnable != null) {
child.removeCallbacks(mFlingRunnable);
mFlingRunnable = null;
}
mFlingRunnable = new FlingRunnable(parent, child);
mFlingRunnable.scrollToOpen(duration);
}
}
/**
* 为滑动返回界面设置状态栏颜色
*
* @param activity 需要设置的activity
* @param color 状态栏颜色值
* @param statusBarAlpha 状态栏透明度
*/
public static void setColorForSwipeBack(Activity activity, @ColorInt int color,
@IntRange(from = 0, to = 255) int statusBarAlpha) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));
View rootView = contentView.getChildAt(0);
int statusBarHeight = getStatusBarHeight(activity);
if (rootView != null && rootView instanceof CoordinatorLayout) {
final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
coordinatorLayout.setFitsSystemWindows(false);
contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;
if (isNeedRequestLayout) {
contentView.setPadding(0, statusBarHeight, 0, 0);
coordinatorLayout.post(new Runnable() {
@Override
public void run() {
coordinatorLayout.requestLayout();
}
});
}
} else {
coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));
}
} else {
contentView.setPadding(0, statusBarHeight, 0, 0);
contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));
}
setTransparentForWindow(activity);
}
}
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target,
float velocityX, float velocityY) {
return target == mNestedScrollingChildRef.get() &&
(mState != STATE_EXPANDED ||
super.onNestedPreFling(coordinatorLayout, child, target,
velocityX, velocityY));
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
mShouldBlockNestedScroll = false;
if (mIsFlinging) {
mShouldBlockNestedScroll = true;
}
return super.onInterceptTouchEvent(parent, child, ev);
}
/**
* 是否拦截触摸事件
* @param parent CoordinatorLayout
* @param child AppBarLayout
* @param ev ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, AppBarLayout child, MotionEvent ev) {
LogUtil.d(TAG, "onInterceptTouchEvent:" + child.getTotalScrollRange());
shouldBlockNestedScroll = isFlinging;
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//手指触摸屏幕的时候停止fling事件
stopAppbarLayoutFling(child);
break;
default:
break;
}
return super.onInterceptTouchEvent(parent, child, ev);
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target,
int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, type);
stopNestedScrollIfNeeded(dyUnconsumed, child, target, type);
}
@Override
public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
if (ViewCompat.getFitsSystemWindows(parent) && !ViewCompat.getFitsSystemWindows(child)) {
ViewCompat.setFitsSystemWindows(child, true);
}
int savedTop = child.getTop();
// First let the parent lay it out
parent.onLayoutChild(child, layoutDirection);
// Offset the bottom sheet
mParentHeight = parent.getHeight();
int peekHeight;
if (mPeekHeightAuto) {
if (mPeekHeightMin == 0) {
mPeekHeightMin = parent.getResources().getDimensionPixelSize(
R.dimen.design_bottom_sheet_peek_height_min);
}
peekHeight = Math.max(mPeekHeightMin, mParentHeight - parent.getWidth() * 9 / 16);
} else {
peekHeight = mPeekHeight;
}
mMinOffset = Math.max(0, mParentHeight - child.getHeight());
mMaxOffset = Math.max(mParentHeight - peekHeight, mMinOffset);
if (mState == STATE_EXPANDED) {
ViewCompat.offsetTopAndBottom(child, mMinOffset);
} else if (mHideable && mState == STATE_HIDDEN) {
ViewCompat.offsetTopAndBottom(child, mParentHeight);
} else if (mState == STATE_COLLAPSED) {
ViewCompat.offsetTopAndBottom(child, mMaxOffset);
} else if (mState == STATE_DRAGGING || mState == STATE_SETTLING) {
ViewCompat.offsetTopAndBottom(child, savedTop - child.getTop());
}
if (mViewDragHelper == null) {
mViewDragHelper = ViewDragHelper.create(parent, mDragCallback);
}
mViewRef = new WeakReference<>(child);
mNestedScrollingChildRef = new WeakReference<>(findScrollingChild(child));
return true;
}