static void translucentStatusBar(Activity activity, boolean hideStatusBarBackground) { Window window = activity.getWindow(); //添加Flag把状态栏设为可绘制模式 window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); if (hideStatusBarBackground) { //如果为全透明模式,取消设置Window半透明的Flag window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //设置状态栏为透明 window.setStatusBarColor(Color.TRANSPARENT); //设置window的状态栏不可见 window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } else { //如果为半透明模式,添加设置Window半透明的Flag window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //设置系统状态栏处于可见状态 window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } //view不根据系统窗口来调整自己的布局 ViewGroup mContentView = (ViewGroup) window.findViewById(Window.ID_ANDROID_CONTENT); View mChildView = mContentView.getChildAt(0); if (mChildView != null) { ViewCompat.setFitsSystemWindows(mChildView, false); ViewCompat.requestApplyInsets(mChildView); } }
private void fillChild(View view, ItemLayoutInfo layoutInfo) { addView(view); measureChildWithExactlySize(view); final int scaleFix = (int) (mChildSize[mOrientation] * (1 - layoutInfo.scaleXY) / 2); final float gap = (mOrientation == VERTICAL ? getHorizontalSpace() : getVerticalSpace()) - mChildSize[(mOrientation + 1) % 2] * layoutInfo.scaleXY; if (mOrientation == VERTICAL) { int left = (int) (getPaddingLeft() + (gap * 0.5 * mVanishOffset)); layoutDecoratedWithMargins(view, left, layoutInfo.start - scaleFix , left + mChildSize[0], layoutInfo.start + mChildSize[1] - scaleFix); } else { int top = (int) (getPaddingTop() + (gap * 0.5 * mVanishOffset)); layoutDecoratedWithMargins(view, layoutInfo.start - scaleFix, top , layoutInfo.start + mChildSize[0] - scaleFix, top + mChildSize[1]); } ViewCompat.setScaleX(view, layoutInfo.scaleXY); ViewCompat.setScaleY(view, layoutInfo.scaleXY); if (mDecorateHelper != null) { mDecorateHelper.decorateChild(view, layoutInfo.positionOffsetPercent, layoutInfo.layoutPercent, layoutInfo.isBottom); } }
public PullRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); mDecelerateInterpolator = new DecelerateInterpolator(DECELERATE_INTERPOLATION_FACTOR); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); int defaultDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime); mDurationToStartPosition = defaultDuration; mDurationToCorrectPosition = defaultDuration; mSpinnerFinalOffset = mTotalDragDistance = dp2px(DRAG_MAX_DISTANCE); mRefreshView = new ImageView(context); setRefreshDrawable(new PlaneDrawable(getContext(), this)); mRefreshView.setVisibility(GONE); addView(mRefreshView, 0); mLoadView = new ImageView(context); setLoadDrawable(new PlaneLoadDrawable(getContext(), this)); mLoadView.setVisibility(GONE); addView(mLoadView, 0); setWillNotDraw(false); ViewCompat.setChildrenDrawingOrderEnabled(this, true); }
public BGASwipeBackLayout2(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final float density = context.getResources().getDisplayMetrics().density; // ======================== 新加的 START ======================== // mOverhangSize = (int) (DEFAULT_OVERHANG_SIZE * density + 0.5f); mOverhangSize = 0; // ======================== 新加的 END ======================== final ViewConfiguration viewConfig = ViewConfiguration.get(context); setWillNotDraw(false); ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate()); ViewCompat.setImportantForAccessibility(this, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); mDragHelper = ViewDragHelper.create(this, 0.5f, new DragHelperCallback()); mDragHelper.setMinVelocity(MIN_FLING_VELOCITY * density); }
private void slideTo(int slideOffset, boolean forceInstant) { if (animator != null) { animator.cancel(); animator = null; } if (!forceInstant) { animator = ObjectAnimator.ofInt(this, "slideOffset", this.slideOffset, slideOffset); animator.setInterpolator(new FastOutSlowInInterpolator()); animator.setDuration(400); animator.start(); ViewCompat.postInvalidateOnAnimation(this); } else { this.slideOffset = slideOffset; requestLayout(); invalidate(); } }
@Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) { // Return true if we're nested scrolling vertically, and we have scrollable children // and the scrolling view is big enough to scroll final boolean started = (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 && child.hasScrollableChildren() && parent.getHeight() - directTargetChild.getHeight() <= child.getHeight(); if (started && mOffsetAnimator != null) { // Cancel any offset animation mOffsetAnimator.cancel(); } // A new nested scroll has started so clear out the previous ref mLastNestedScrollingChildRef = null; return started; }
private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, RecyclerView.ViewHolder item) { boolean oldItem = false; if (changeInfo.newHolder == item) { changeInfo.newHolder = null; } else if (changeInfo.oldHolder == item) { changeInfo.oldHolder = null; oldItem = true; } else { return false; } ViewCompat.setAlpha(item.itemView, 1); ViewCompat.setTranslationX(item.itemView, 0); ViewCompat.setTranslationY(item.itemView, 0); dispatchChangeFinished(item, oldItem); return true; }
public boolean onLongClick(View v) { if (hasText()) { return false; } int[] screenPos = new int[2]; Rect displayFrame = new Rect(); getLocationOnScreen(screenPos); getWindowVisibleDisplayFrame(displayFrame); Context context = getContext(); int width = getWidth(); int height = getHeight(); int midy = screenPos[1] + (height / 2); int referenceX = screenPos[0] + (width / 2); if (ViewCompat.getLayoutDirection(v) == 0) { referenceX = context.getResources().getDisplayMetrics().widthPixels - referenceX; } Toast cheatSheet = Toast.makeText(context, this.mItemData.getTitle(), 0); if (midy < displayFrame.height()) { cheatSheet.setGravity(8388661, referenceX, (screenPos[1] + height) - displayFrame.top); } else { cheatSheet.setGravity(81, 0, height); } cheatSheet.show(); return true; }
/** * Tests scrollability within child views of v given a delta of dx. * * @param v View to test for horizontal scrollability * @param checkV Whether the view v passed should itself be checked for scrollability (true), * or just its children (false). * @param dx Delta scrolled in pixels along the X axis * @param dy Delta scrolled in pixels along the Y axis * @param x X coordinate of the active touch point * @param y Y coordinate of the active touch point * @return true if child views of v can be scrolled by delta of dx. */ protected boolean canScroll(View v, boolean checkV, int dx, int dy, int x, int y) { if (v instanceof ViewGroup) { final ViewGroup group = (ViewGroup) v; final int scrollX = v.getScrollX(); final int scrollY = v.getScrollY(); final int count = group.getChildCount(); // Count backwards - let topmost views consume scroll distance first. for (int i = count - 1; i >= 0; i--) { // TODO: Add versioned support here for transformed views. // This will not work for transformed views in Honeycomb+ final View child = group.getChildAt(i); if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() && y + scrollY >= child.getTop() && y + scrollY < child.getBottom() && canScroll(child, true, dx, dy, x + scrollX - child.getLeft(), y + scrollY - child.getTop())) { return true; } } } return checkV && (ViewCompat.canScrollHorizontally(v, -dx) || ViewCompat.canScrollVertically(v, -dy)); }
public NestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.mTempRect = new Rect(); this.mIsLayoutDirty = true; this.mIsLaidOut = false; this.mChildToScrollTo = null; this.mIsBeingDragged = false; this.mSmoothScrollingEnabled = true; this.mActivePointerId = -1; this.mScrollOffset = new int[2]; this.mScrollConsumed = new int[2]; initScrollView(); TypedArray a = context.obtainStyledAttributes(attrs, SCROLLVIEW_STYLEABLE, defStyleAttr, 0); setFillViewport(a.getBoolean(0, false)); a.recycle(); this.mParentHelper = new NestedScrollingParentHelper(this); this.mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); ViewCompat.setAccessibilityDelegate(this, ACCESSIBILITY_DELEGATE); }
private float[] getFabTranslationYForBottomNavigationBar(CoordinatorLayout parent, FloatingActionButton fab) { float minOffset = 0; float viewHeight = 0; final List<View> dependencies = parent.getDependencies(fab); for (int i = 0, z = dependencies.size(); i < z; i++) { final View view = dependencies.get(i); if (view instanceof BottomNavigationBar) { viewHeight = view.getHeight(); minOffset = Math.min(minOffset, ViewCompat.getTranslationY(view) - viewHeight); } } float[] returnValues = {minOffset, viewHeight}; return returnValues; }
private void updateChildrenImportantForAccessibility(View drawerView, boolean isDrawerOpen) { final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); if (!isDrawerOpen && !isDrawerView(child) || isDrawerOpen && child == drawerView) { // Drawer is closed and this is a content view or this is an // open drawer view, so it should be visible. ViewCompat.setImportantForAccessibility(child, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES); } else { ViewCompat.setImportantForAccessibility(child, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS); } } }
@Override public void onDestroy() { super.onDestroy(); mItems.clear(); mRecyclerViewAdapter = null; setAppBarLayoutAlpha(255); if (mAppBarLayout != null && !isForeground()) { mAppBarLayout.setTranslationY(0); ViewCompat.setElevation(mAppBarLayout, 0); } if (mLoader != null) { mLoader.cancel(true); mLoader = null; } if (mHandler != null) { mHandler.removeCallbacks(mRefresh); } mAdView = null; for (RecyclerViewItem item : mItems) { item.onDestroy(); } }
/** * Whether child view can scroll up * @return */ public boolean canChildScrollUp() { if (mTargetView == null) { return false; } if (Build.VERSION.SDK_INT < 14) { if (mTargetView instanceof AbsListView) { final AbsListView absListView = (AbsListView) mTargetView; return absListView.getChildCount() > 0 && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) .getTop() < absListView.getPaddingTop()); } else { return ViewCompat.canScrollVertically(mTargetView, -1) || mTargetView.getScrollY() > 0; } } else { return ViewCompat.canScrollVertically(mTargetView, -1); } }
public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, int fromX, int fromY, int toX, int toY) { if (oldHolder == newHolder) { return animateMove(oldHolder, fromX, fromY, toX, toY); } float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView); float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView); float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView); resetAnimation(oldHolder); int deltaX = (int) (((float) (toX - fromX)) - prevTranslationX); int deltaY = (int) (((float) (toY - fromY)) - prevTranslationY); ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX); ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY); ViewCompat.setAlpha(oldHolder.itemView, prevAlpha); if (newHolder != null) { resetAnimation(newHolder); ViewCompat.setTranslationX(newHolder.itemView, (float) (-deltaX)); ViewCompat.setTranslationY(newHolder.itemView, (float) (-deltaY)); ViewCompat.setAlpha(newHolder.itemView, 0.0f); } this.mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY)); return true; }
private void startScaleDownReturnToStartAnimation(int from, Animation.AnimationListener listener) { mFrom = from; mStartingScale = ViewCompat.getScaleX(mHeadViewContainer); mScaleDownToStartAnimation = new Animation() { @Override public void applyTransformation(float interpolatedTime, Transformation t) { float targetScale = (mStartingScale + (-mStartingScale * interpolatedTime)); setAnimationProgress(targetScale); moveToStart(interpolatedTime); } }; mScaleDownToStartAnimation.setDuration(SCALE_DOWN_DURATION); if (listener != null) { mHeadViewContainer.setAnimationListener(listener); } mHeadViewContainer.clearAnimation(); mHeadViewContainer.startAnimation(mScaleDownToStartAnimation); }
/** * Preform your animation. You do not need to override this in most cases cause the default is pretty good. * Listeners will be overridden **/ protected ViewPropertyAnimatorCompat animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) { final View view = holder.itemView; final int deltaX = toX - fromX; final int deltaY = toY - fromY; ViewCompat.animate(view).cancel(); if (deltaX != 0) { ViewCompat.animate(view).translationX(0); } if (deltaY != 0) { ViewCompat.animate(view).translationY(0); } // TODO: make EndActions end listeners instead, since end actions aren't called when // vpas are canceled (and can't end them. why?) // need listener functionality in VPACompat for this. Ick. return ViewCompat.animate(view).setInterpolator(null).setDuration(getMoveDuration()); }
@Override public boolean onTouchEvent(@NonNull MotionEvent event) { final int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: if (event.getX() < fastScroll.getX() - ViewCompat.getPaddingStart(fastScroll)) return false; if (currentAnimator != null) currentAnimator.cancel(); if (bubbleView != null && bubbleView.getVisibility() == GONE) showBubble(); fastScroll.setSelected(true); case MotionEvent.ACTION_MOVE: isDragging = true; setBubbleAndHandlePosition(event.getY()); setRecyclerViewPosition(event.getY()); return true; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: isDragging = false; fastScroll.setSelected(false); hideBubble(); return true; } return super.onTouchEvent(event); }
public final void smoothScrollBy(int dx, int dy) { if (getChildCount() != 0) { if (AnimationUtils.currentAnimationTimeMillis() - this.mLastScroll > 250) { int maxY = Math.max(0, getChildAt(0).getHeight() - ((getHeight() - getPaddingBottom()) - getPaddingTop())); int scrollY = getScrollY(); this.mScroller.startScroll(getScrollX(), scrollY, 0, Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY); ViewCompat.postInvalidateOnAnimation(this); } else { if (!this.mScroller.isFinished()) { this.mScroller.abortAnimation(); } scrollBy(dx, dy); } this.mLastScroll = AnimationUtils.currentAnimationTimeMillis(); } }
/** * Tests scrollability within child views of v given a delta of dx. * * @param v View to test for horizontal scrollability * @param checkV Whether the view v passed should itself be checked for scrollability (true), * or just its children (false). * @param dx Delta scrolled in pixels * @param x X coordinate of the active touch point * @param y Y coordinate of the active touch point * @return true if child views of v can be scrolled by delta of dx. */ protected boolean canScrollHorizontal(View v, boolean checkV, int dx, int x, int y) { if (v instanceof ViewGroup) { final ViewGroup group = (ViewGroup) v; final int scrollX = v.getScrollX(); final int scrollY = v.getScrollY(); final int count = group.getChildCount(); for (int i = count - 1; i >= 0; i--) { // TODO: Add versioned support here for transformed views. final View child = group.getChildAt(i); if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight() && y + scrollY >= child.getTop() && y + scrollY < child.getBottom() && canScrollHorizontal(child, true, dx, x + scrollX - child.getLeft(), y + scrollY - child.getTop())) { return true; } } } return checkV && ViewCompat.canScrollHorizontally(v, -dx); }
/** * @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. */ public boolean canChildScrollUp() { // //For make it can work when my recycler view is in Gone. // return false; if (android.os.Build.VERSION.SDK_INT < 14) { if (mTarget instanceof AbsListView) { final AbsListView absListView = (AbsListView) mTarget; return absListView.getChildCount() > 0 && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) .getTop() < absListView.getPaddingTop()); } else { return ViewCompat.canScrollVertically(mTarget, -1) || mTarget.getScrollY() > 0; } } else { return ViewCompat.canScrollVertically(mTarget, -1); } }
final int getMinimumHeightForVisibleOverlappingContent() { final int topInset = getTopInset(); final int minHeight = ViewCompat.getMinimumHeight(this); if (minHeight != 0) { // If this layout has a min height, use it (doubled) return (minHeight * 2) + topInset; } // Otherwise, we'll use twice the min height of our last child final int childCount = getChildCount(); final int lastChildMinHeight = childCount >= 1 ? ViewCompat.getMinimumHeight(getChildAt(childCount - 1)) : 0; if (lastChildMinHeight != 0) { return (lastChildMinHeight * 2) + topInset; } // If we reach here then we don't have a min height explicitly set. Instead we'll take a // guess at 1/3 of our height being visible return getHeight() / 3; }
@Override public void onChildDraw( final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) { if (isCurrentlyActive) { ViewCompat.setElevation( viewHolder.itemView, Math.min( Math.max(dX / 4f, defaultElevation), defaultElevation * 16f ) ); } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); }
@Override public final void performChange(@NonNull final ViewGroup container, @Nullable final View from, @Nullable final View to, final boolean isPush, @NonNull final ControllerChangeCompletedListener changeListener) { if (to != null && !ViewCompat.isLaidOut(to)) { to.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { final ViewTreeObserver observer = to.getViewTreeObserver(); if (observer.isAlive()) { observer.removeOnPreDrawListener(this); } performAnimation(container, from, to, isPush, changeListener); return true; } }); } else { performAnimation(container, from, to, isPush, changeListener); } }
@Override public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder, int fromX, int fromY, int toX, int toY) { final float prevTranslationX = ViewCompat.getTranslationX(oldHolder.itemView); final float prevTranslationY = ViewCompat.getTranslationY(oldHolder.itemView); final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView); endAnimation(oldHolder); int deltaX = (int) (toX - fromX - prevTranslationX); int deltaY = (int) (toY - fromY - prevTranslationY); // recover prev translation state after ending animation ViewCompat.setTranslationX(oldHolder.itemView, prevTranslationX); ViewCompat.setTranslationY(oldHolder.itemView, prevTranslationY); ViewCompat.setAlpha(oldHolder.itemView, prevAlpha); if (newHolder != null && newHolder.itemView != null) { // carry over translation values endAnimation(newHolder); ViewCompat.setTranslationX(newHolder.itemView, -deltaX); ViewCompat.setTranslationY(newHolder.itemView, -deltaY); ViewCompat.setAlpha(newHolder.itemView, 0); } mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY)); return true; }
@Override public void computeScroll() { if (!mScroller.isFinished() && mScroller.computeScrollOffset()) { int oldX = getScrollX(); int oldY = getScrollY(); int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); if (oldX != x || oldY != y) { scrollTo(x, y); if (!pageScrolled(x)) { mScroller.abortAnimation(); scrollTo(0, y); } } // Keep on drawing until the animation has finished. ViewCompat.postInvalidateOnAnimation(this); return; } // Done with scroll, clean up state. completeScroll(true); }
@Override public boolean animateMove(final RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) { final View view = holder.itemView; fromX += ViewCompat.getTranslationX(holder.itemView); fromY += ViewCompat.getTranslationY(holder.itemView); resetAnimation(holder); int deltaX = toX - fromX; int deltaY = toY - fromY; if (deltaX == 0 && deltaY == 0) { dispatchMoveFinished(holder); return false; } if (deltaX != 0) { ViewCompat.setTranslationX(view, -deltaX); } if (deltaY != 0) { ViewCompat.setTranslationY(view, -deltaY); } mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY)); return true; }
@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (ViewCompat.getFitsSystemWindows(this)) { ViewCompat.requestApplyInsets(this); } }
@Override public void setCurrentViewportWithAnimation(Viewport targetViewport) { if (null != targetViewport) { viewportAnimator.cancelAnimation(); viewportAnimator.startAnimation(getCurrentViewport(), targetViewport); } ViewCompat.postInvalidateOnAnimation(this); }
public static void startWithTransition(Activity activity, Intent intent, View sourceView) { ViewCompat.setTransitionName(sourceView, TRANSITION_NAME); ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( activity, sourceView, TRANSITION_NAME); activity.startActivity(intent, options.toBundle()); }
@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (!isInEditMode()) { mDisplayOrientationDetector.enable(ViewCompat.getDisplay(this)); } }
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Drawable drawable = getDrawable(); if (drawable != null) { /** * 默认情况下,所有的从同一资源(R.drawable.XXX)加载来的drawable实例都共享一个共用的状态, * 如果你更改一个实例的状态,其他所有的实例都会收到相同的通知。 * 使用使 mutate 可以让这个drawable变得状态不定。这个操作不能还原(变为不定后就不能变为原来的状态)。 * 一个状态不定的drawable可以保证它不与其他任何一个drawabe共享它的状态。 * 此处应该是要使用的 mutate(),但是在部分手机上会出现点击后变白的现象,所以没有使用 * 目前这种解决方案没有问题 */ // drawable.mutate().setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); drawable.setColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); ViewCompat.postInvalidateOnAnimation(this); } break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: Drawable drawableUp = getDrawable(); if (drawableUp != null) { // drawableUp.mutate().clearColorFilter(); drawableUp.clearColorFilter(); ViewCompat.postInvalidateOnAnimation(this); } break; } return super.onTouchEvent(event); }
/** * Whether it is possible for the child view of this layout to scroll down. Override this if the child view is a custom view. * 判断是否可以上拉 */ public static boolean canChildScrollDown(View mChildView) { if (Build.VERSION.SDK_INT < 14) { if (mChildView instanceof AbsListView) { final AbsListView absListView = (AbsListView) mChildView; return absListView.getChildCount() > 0 && (absListView.getLastVisiblePosition() < absListView.getChildCount() - 1 || absListView.getChildAt(absListView.getChildCount() - 1).getBottom() > absListView.getPaddingBottom()); } else { return ViewCompat.canScrollVertically(mChildView, 1) || mChildView.getScrollY() < 0; } } else { return ViewCompat.canScrollVertically(mChildView, 1); } }
/** * Smoothly animate mDraggingPane to the target X position within its range. * * @param slideOffset position to animate to * @param velocity initial velocity in case of fling, or 0. */ boolean smoothSlideTo(float slideOffset, int velocity) { if (!isEnabled()) { // Nothing to do. return false; } int panelTop = computePanelTopPosition(slideOffset); if (mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), panelTop)) { setAllChildrenVisible(); ViewCompat.postInvalidateOnAnimation(this); return true; } return false; }
@Override public boolean onClick(View v, IAdapter adapter, SettingsHeaderItem item, int position) { if (mExpandable && item.getSubItems() != null) { if (!item.isExpanded()) { ViewCompat.animate(v.findViewById(R.id.ivIcon)).rotation(180).start(); } else { ViewCompat.animate(v.findViewById(R.id.ivIcon)).rotation(0).start(); } // this notifies the header about changes so that the SettingsSpaceDecorator can update the margins of the header as well // this calls through to the underlying RV and skips fast adapters expand/collapse logic adapter.getFastAdapter().notifyItemRangeChanged(position, 1, Definitions.PAYLOAD_UPDATE_HEADER_DECORATOR); return mOnClickListener == null || mOnClickListener.onClick(v, adapter, item, position); } return mOnClickListener != null && mOnClickListener.onClick(v, adapter, item, position); }
private void setTargetOffsetTopAndBottom(int offset, boolean requiresUpdate) { if (mRefreshView == null) { ensureTarget(); } mRefreshView.bringToFront(); ViewCompat.offsetTopAndBottom(mRefreshView, offset); mCurrentTargetOffsetTop = mRefreshView.getTop(); if (requiresUpdate && android.os.Build.VERSION.SDK_INT < 11) { invalidate(); } }
public MaterialViewPagerHeader withLogo(View logo) { this.mLogo = logo; //when logo get a height, initialise initial & final logo positions toolbarLayout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { //rotation fix, if not set, originalTitleY = Na ViewCompat.setTranslationY(mLogo,0); ViewCompat.setTranslationX(mLogo, 0); originalTitleY = ViewCompat.getY(mLogo); originalTitleX = ViewCompat.getX(mLogo); originalTitleHeight = mLogo.getHeight(); finalTitleHeight = dpToPx(21, context); //the final scale of the logo finalScale = finalTitleHeight / originalTitleHeight; finalTitleY = (toolbar.getPaddingTop() + toolbar.getHeight()) / 2 - finalTitleHeight / 2 - (1 - finalScale) * finalTitleHeight; //(mLogo.getWidth()/2) *(1-finalScale) is the margin left added by the scale() on the logo //when logo scaledown, the content stay in center, so we have to anually remove the left padding finalTitleX = dpToPx(52f, context) - (mLogo.getWidth() / 2) * (1 - finalScale); toolbarLayout.getViewTreeObserver().removeOnPreDrawListener(this); return false; } }); return this; }
/** * @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. */ public boolean canChildScrollUp() { if (android.os.Build.VERSION.SDK_INT < 14) { if (mTarget instanceof AbsListView) { final AbsListView absListView = (AbsListView) mTarget; return absListView.getChildCount() > 0 && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) .getTop() < absListView.getPaddingTop()); } else { return mTarget.getScrollY() > 0; } } else { return ViewCompat.canScrollVertically(mTarget, -1); } }
/** * 是否能右拉 * * @return */ private boolean canChildScrollRight() { if (checkListener != null) { return checkListener.canScrollRight(); } return ViewCompat.canScrollHorizontally(child, 1); }
/** * Constructor that is called when inflating SwipeRefreshLayout from XML. * * @param context * @param attrs */ public SwipeRefreshLayout(Context context, AttributeSet attrs) { super(context, attrs); mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); mMediumAnimationDuration = getResources().getInteger( android.R.integer.config_mediumAnimTime); setWillNotDraw(false); mDecelerateInterpolator = new DecelerateInterpolator(DECELERATE_INTERPOLATION_FACTOR); final TypedArray a = context.obtainStyledAttributes(attrs, LAYOUT_ATTRS); setEnabled(a.getBoolean(0, true)); a.recycle(); final DisplayMetrics metrics = getResources().getDisplayMetrics(); mCircleWidth = (int) (CIRCLE_DIAMETER * metrics.density); mCircleHeight = (int) (CIRCLE_DIAMETER * metrics.density); createProgressView(); ViewCompat.setChildrenDrawingOrderEnabled(this, true); // the absolute offset has to take into account that the circle starts at an offset mSpinnerFinalOffset = DEFAULT_CIRCLE_TARGET * metrics.density; mTotalDragDistance = mSpinnerFinalOffset; requestDisallowInterceptTouchEvent(true); }