ViewCompat:android官方实现兼容的一个帮助类

Posted Iaouei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ViewCompat:android官方实现兼容的一个帮助类相关的知识,希望对你有一定的参考价值。

类代码:

package android.support.v4.view;

import android.content.res.ColorStateList;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.FloatRange;
import android.support.annotation.IdRes;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.WeakHashMap;

/**API4以后引入的实现兼容的一个帮助类
 * Helper for accessing features in @link View introduced after API
 * level 4 in a backwards compatible fashion.
 */
public class ViewCompat 
    private static final String TAG = "ViewCompat";

    //常量 略,本节旨在观察此类的结构

//这个接口列出了这个类支持的方法,这些方法在此类中都有实现,我们也可以实现此接口进行重写
    interface ViewCompatImpl 
        public boolean canScrollHorizontally(View v, int direction);
        public boolean canScrollVertically(View v, int direction);
        public int getOverScrollMode(View v);
        public void setOverScrollMode(View v, int mode);
        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event);
        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event);
        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info);
        public void setAccessibilityDelegate(View v, @Nullable AccessibilityDelegateCompat delegate);
        public boolean hasAccessibilityDelegate(View v);
        public boolean hasTransientState(View view);
        public void setHasTransientState(View view, boolean hasTransientState);
        public void postInvalidateOnAnimation(View view);
        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom);
        public void postOnAnimation(View view, Runnable action);
        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis);
        public int getImportantForAccessibility(View view);
        public void setImportantForAccessibility(View view, int mode);
        public boolean isImportantForAccessibility(View view);
        public boolean performAccessibilityAction(View view, int action, Bundle arguments);
        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view);
        public float getAlpha(View view);
        public void setLayerType(View view, int layerType, Paint paint);
        public int getLayerType(View view);
        public int getLabelFor(View view);
        public void setLabelFor(View view, int id);
        public void setLayerPaint(View view, Paint paint);
        public int getLayoutDirection(View view);
        public void setLayoutDirection(View view, int layoutDirection);
        public ViewParent getParentForAccessibility(View view);
        public boolean isOpaque(View view);
        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState);
        public int getMeasuredWidthAndState(View view);
        public int getMeasuredHeightAndState(View view);
        public int getMeasuredState(View view);
        public int getAccessibilityLiveRegion(View view);
        public void setAccessibilityLiveRegion(View view, int mode);
        public int getPaddingStart(View view);
        public int getPaddingEnd(View view);
        public void setPaddingRelative(View view, int start, int top, int end, int bottom);
        public void dispatchStartTemporaryDetach(View view);
        public void dispatchFinishTemporaryDetach(View view);
        public float getX(View view);
        public float getY(View view);
        public float getRotation(View view);
        public float getRotationX(View view);
        public float getRotationY(View view);
        public float getScaleX(View view);
        public float getScaleY(View view);
        public float getTranslationX(View view);
        public float getTranslationY(View view);
        public int getMinimumWidth(View view);
        public int getMinimumHeight(View view);
        public ViewPropertyAnimatorCompat animate(View view);
        public void setRotation(View view, float value);
        public void setRotationX(View view, float value);
        public void setRotationY(View view, float value);
        public void setScaleX(View view, float value);
        public void setScaleY(View view, float value);
        public void setTranslationX(View view, float value);
        public void setTranslationY(View view, float value);
        public void setX(View view, float value);
        public void setY(View view, float value);
        public void setAlpha(View view, float value);
        public void setPivotX(View view, float value);
        public void setPivotY(View view, float value);
        public float getPivotX(View view);
        public float getPivotY(View view);
        public void setElevation(View view, float elevation);
        public float getElevation(View view);
        public void setTranslationZ(View view, float translationZ);
        public float getTranslationZ(View view);
        public void setClipBounds(View view, Rect clipBounds);
        public Rect getClipBounds(View view);
        public void setTransitionName(View view, String transitionName);
        public String getTransitionName(View view);
        public int getWindowSystemUiVisibility(View view);
        public void requestApplyInsets(View view);
        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled);
        public boolean getFitsSystemWindows(View view);
        public boolean hasOverlappingRendering(View view);
        void setFitsSystemWindows(View view, boolean fitSystemWindows);
        void jumpDrawablesToCurrentState(View v);
        void setOnApplyWindowInsetsListener(View view, OnApplyWindowInsetsListener listener);
        WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets);
        WindowInsetsCompat dispatchApplyWindowInsets(View v, WindowInsetsCompat insets);
        void setSaveFromParentEnabled(View view, boolean enabled);
        void setActivated(View view, boolean activated);
        boolean isPaddingRelative(View view);
        ColorStateList getBackgroundTintList(View view);
        void setBackgroundTintList(View view, ColorStateList tintList);
        PorterDuff.Mode getBackgroundTintMode(View view);
        void setBackgroundTintMode(View view, PorterDuff.Mode mode);
        void setNestedScrollingEnabled(View view, boolean enabled);
        boolean isNestedScrollingEnabled(View view);
        boolean startNestedScroll(View view, int axes);
        void stopNestedScroll(View view);
        boolean hasNestedScrollingParent(View view);
        boolean dispatchNestedScroll(View view, int dxConsumed, int dyConsumed, int dxUnconsumed,
                int dyUnconsumed, int[] offsetInWindow);
        boolean dispatchNestedPreScroll(View view, int dx, int dy, int[] consumed,
                int[] offsetInWindow);
        boolean dispatchNestedFling(View view, float velocityX, float velocityY, boolean consumed);
        boolean dispatchNestedPreFling(View view, float velocityX, float velocityY);
        boolean isLaidOut(View view);
        int combineMeasuredStates(int curState, int newState);
        public float getZ(View view);
        public boolean isAttachedToWindow(View view);
        public boolean hasOnClickListeners(View view);
        public void setScrollIndicators(View view, int indicators);
        public void setScrollIndicators(View view, int indicators, int mask);
        public int getScrollIndicators(View view);
    

    static class BaseViewCompatImpl implements ViewCompatImpl 
        private Method mDispatchStartTemporaryDetach;
        private Method mDispatchFinishTemporaryDetach;
        private boolean mTempDetachBound;
        WeakHashMap<View, ViewPropertyAnimatorCompat> mViewPropertyAnimatorCompatMap = null;


        public boolean canScrollHorizontally(View v, int direction) 
            return (v instanceof ScrollingView) &&
                canScrollingViewScrollHorizontally((ScrollingView) v, direction);
        
        public boolean canScrollVertically(View v, int direction) 
            return (v instanceof ScrollingView) &&
                    canScrollingViewScrollVertically((ScrollingView) v, direction);
        
        public int getOverScrollMode(View v) 
            return OVER_SCROLL_NEVER;
        
        public void setOverScrollMode(View v, int mode) 
            // Do nothing; API doesn't exist
        
        public void setAccessibilityDelegate(View v, AccessibilityDelegateCompat delegate) 
            // Do nothing; API doesn't exist
        

        @Override
        public boolean hasAccessibilityDelegate(View v) 
            return false;
        

        public void onPopulateAccessibilityEvent(View v, AccessibilityEvent event) 
            // Do nothing; API doesn't exist
        
        public void onInitializeAccessibilityEvent(View v, AccessibilityEvent event) 
         // Do nothing; API doesn't exist
        
        public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfoCompat info) 
            // Do nothing; API doesn't exist
        
        public boolean hasTransientState(View view) 
            // A view can't have transient state if transient state wasn't supported.
            return false;
        
        public void setHasTransientState(View view, boolean hasTransientState) 
            // Do nothing; API doesn't exist
        
        public void postInvalidateOnAnimation(View view) 
            view.invalidate();
        
        public void postInvalidateOnAnimation(View view, int left, int top, int right, int bottom) 
            view.invalidate(left, top, right, bottom);
        
        public void postOnAnimation(View view, Runnable action) 
            view.postDelayed(action, getFrameTime());
        
        public void postOnAnimationDelayed(View view, Runnable action, long delayMillis) 
            view.postDelayed(action, getFrameTime() + delayMillis);
        
        long getFrameTime() 
            return FAKE_FRAME_TIME;
        
        public int getImportantForAccessibility(View view) 
            return 0;
        
        public void setImportantForAccessibility(View view, int mode) 

        
        public boolean isImportantForAccessibility(View view) 
            return true;
        
        public boolean performAccessibilityAction(View view, int action, Bundle arguments) 
            return false;
        
        public AccessibilityNodeProviderCompat getAccessibilityNodeProvider(View view) 
            return null;
        
        public float getAlpha(View view) 
            return 1.0f;
        
        public void setLayerType(View view, int layerType, Paint paint) 
            // No-op until layers became available (HC)
        
        public int getLayerType(View view) 
            return LAYER_TYPE_NONE;
        
        public int getLabelFor(View view) 
            return 0;
        
        public void setLabelFor(View view, int id) 

        
        public void setLayerPaint(View view, Paint p) 
            // No-op until layers became available (HC)
        

        @Override
        public int getLayoutDirection(View view) 
            return LAYOUT_DIRECTION_LTR;
        

        @Override
        public void setLayoutDirection(View view, int layoutDirection) 
            // No-op
        

        @Override
        public ViewParent getParentForAccessibility(View view) 
            return view.getParent();
        

        @Override
        public boolean isOpaque(View view) 
            final Drawable bg = view.getBackground();
            if (bg != null) 
                return bg.getOpacity() == PixelFormat.OPAQUE;
            
            return false;
        

        public int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) 
            return View.resolveSize(size, measureSpec);
        

        @Override
        public int getMeasuredWidthAndState(View view) 
            return view.getMeasuredWidth();
        

        @Override
        public int getMeasuredHeightAndState(View view) 
            return view.getMeasuredHeight();
        

        @Override
        public int getMeasuredState(View view) 
            return 0;
        

        @Override
        public int getAccessibilityLiveRegion(View view) 
            return ACCESSIBILITY_LIVE_REGION_NONE;
        

        @Override
        public void setAccessibilityLiveRegion(View view, int mode) 
            // No-op
        

        @Override
        public int getPaddingStart(View view) 
            return view.getPaddingLeft();
        

        @Override
        public int getPaddingEnd(View view) 
            return view.getPaddingRight();
        

        @Override
        public void setPaddingRelative(View view, int start, int top, int end, int bottom) 
            view.setPadding(start, top, end, bottom);
        

        @Override
        public void dispatchStartTemporaryDetach(View view) 
            if (!mTempDetachBound) 
                bindTempDetach();
            
            if (mDispatchStartTemporaryDetach != null) 
                try 
                    mDispatchStartTemporaryDetach.invoke(view);
                 catch (Exception e) 
                    Log.d(TAG, "Error calling dispatchStartTemporaryDetach", e);
                
             else 
                // Try this instead
                view.onStartTemporaryDetach();
            
        

        @Override
        public void dispatchFinishTemporaryDetach(View view) 
            if (!mTempDetachBound) 
                bindTempDetach();
            
            if (mDispatchFinishTemporaryDetach != null) 
                try 
                    mDispatchFinishTemporaryDetach.invoke(view);
                 catch (Exception e) 
                    Log.d(TAG, "Error calling dispatchFinishTemporaryDetach", e);
                
             else 
                // Try this instead
                view.onFinishTemporaryDetach();
            
        

        @Override
        public boolean hasOverlappingRendering(View view) 
            return true;
        

        private void bindTempDetach() 
            try 
                mDispatchStartTemporaryDetach = View.class.getDeclaredMethod(
                        "dispatchStartTemporaryDetach");
                mDispatchFinishTemporaryDetach = View.class.getDeclaredMethod(
                        "dispatchFinishTemporaryDetach");
             catch (NoSuchMethodException e) 
                Log.e(TAG, "Couldn't find method", e);
            
            mTempDetachBound = true;
        

        @Override
        public float getTranslationX(View view) 
            return 0;
        

        @Override
        public float getTranslationY(View view) 
            return 0;
        

        @Override
        public float getX(View view) 
            return 0;
        

        @Override
        public float getY(View view) 
            return 0;
        

        @Override
        public float getRotation(View view) 
            return 0;
        

        @Override
        public float getRotationX(View view) 
            return 0;
        

        @Override
        public float getRotationY(View view) 
            return 0;
        

        @Override
        public float getScaleX(View view) 
            return 0;
        

        @Override
        public float getScaleY(View view) 
            return 0;
        

        @Override
        public int getMinimumWidth(View view) 
            return ViewCompatBase.getMinimumWidth(view);
        

        @Override
        public int getMinimumHeight(View view) 
            return ViewCompatBase.getMinimumHeight(view);
        

        @Override
        public ViewPropertyAnimatorCompat animate(View view) 
            return new ViewPropertyAnimatorCompat(view);
        

        @Override
        public void setRotation(View view, float value) 
            // noop
        

        @Override
        public void setTranslationX(View view, float value) 
            // noop
        

        @Override
        public void setTranslationY(View view, float value) 
            // noop
        

        @Override
        public void setAlpha(View view, float value) 
            // noop
        

        @Override
        public void setRotationX(View view, float value) 
            // noop
        

        @Override
        public void setRotationY(View view, float value) 
            // noop
        

        @Override
        public void setScaleX(View view, float value) 
            // noop
        

        @Override
        public void setScaleY(View view, float value) 
            // noop
        

        @Override
        public void setX(View view, float value) 
            // noop
        

        @Override
        public void setY(View view, float value) 
            // noop
        

        @Override
        public void setPivotX(View view, float value) 
            // noop
        

        @Override
        public void setPivotY(View view, float value) 
            // noop
        

        @Override
        public float getPivotX(View view) 
            return 0;
        

        @Override
        public float getPivotY(View view) 
            return 0;
        

        @Override
        public void setTransitionName(View view, String transitionName) 
        

        @Override
        public String getTransitionName(View view) 
            return null;
        

        @Override
        public int getWindowSystemUiVisibility(View view) 
            return 0;
        

        @Override
        public void requestApplyInsets(View view) 
        

        @Override
        public void setElevation(View view, float elevation) 
        

        @Override
        public float getElevation(View view) 
            return 0f;
        

        @Override
        public void setTranslationZ(View view, float translationZ) 
        

        @Override
        public float getTranslationZ(View view) 
            return 0f;
        

        @Override
        public void setClipBounds(View view, Rect clipBounds) 
        

        @Override
        public Rect getClipBounds(View view) 
            return null;
        

        @Override
        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) 
            // noop
        

        @Override
        public boolean getFitsSystemWindows(View view) 
            return false;
        

        @Override
        public void setFitsSystemWindows(View view, boolean fitSystemWindows) 
            // noop
        

        @Override
        public void jumpDrawablesToCurrentState(View view) 
            // Do nothing; API didn't exist.
        

        @Override
        public void setOnApplyWindowInsetsListener(View view,
                OnApplyWindowInsetsListener listener) 
            // noop
        

        @Override
        public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) 
            return insets;
        

        @Override
        public WindowInsetsCompat dispatchApplyWindowInsets(View v, WindowInsetsCompat insets) 
            return insets;
        

        @Override
        public void setSaveFromParentEnabled(View v, boolean enabled) 
            // noop
        

        @Override
        public void setActivated(View view, boolean activated) 
            // noop
        

        @Override
        public boolean isPaddingRelative(View view) 
            return false;
        

        public void setNestedScrollingEnabled(View view, boolean enabled) 
            if (view instanceof NestedScrollingChild) 
                ((NestedScrollingChild) view).setNestedScrollingEnabled(enabled);
            
        

        @Override
        public boolean isNestedScrollingEnabled(View view) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).isNestedScrollingEnabled();
            
            return false;
        

        @Override
        public ColorStateList getBackgroundTintList(View view) 
            return ViewCompatBase.getBackgroundTintList(view);
        

        @Override
        public void setBackgroundTintList(View view, ColorStateList tintList) 
            ViewCompatBase.setBackgroundTintList(view, tintList);
        

        @Override
        public void setBackgroundTintMode(View view, PorterDuff.Mode mode) 
            ViewCompatBase.setBackgroundTintMode(view, mode);
        

        @Override
        public PorterDuff.Mode getBackgroundTintMode(View view) 
            return ViewCompatBase.getBackgroundTintMode(view);
        

        private boolean canScrollingViewScrollHorizontally(ScrollingView view, int direction) 
            final int offset = view.computeHorizontalScrollOffset();
            final int range = view.computeHorizontalScrollRange() -
                    view.computeHorizontalScrollExtent();
            if (range == 0) return false;
            if (direction < 0) 
                return offset > 0;
             else 
                return offset < range - 1;
            
        

        private boolean canScrollingViewScrollVertically(ScrollingView view, int direction) 
            final int offset = view.computeVerticalScrollOffset();
            final int range = view.computeVerticalScrollRange() -
                    view.computeVerticalScrollExtent();
            if (range == 0) return false;
            if (direction < 0) 
                return offset > 0;
             else 
                return offset < range - 1;
            
        

        public boolean startNestedScroll(View view, int axes) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).startNestedScroll(axes);
            
            return false;
        

        @Override
        public void stopNestedScroll(View view) 
            if (view instanceof NestedScrollingChild) 
                ((NestedScrollingChild) view).stopNestedScroll();
            
        

        @Override
        public boolean hasNestedScrollingParent(View view) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).hasNestedScrollingParent();
            
            return false;
        

        @Override
        public boolean dispatchNestedScroll(View view, int dxConsumed, int dyConsumed,
                int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).dispatchNestedScroll(dxConsumed, dyConsumed,
                        dxUnconsumed, dyUnconsumed, offsetInWindow);
            
            return false;
        

        @Override
        public boolean dispatchNestedPreScroll(View view, int dx, int dy,
                int[] consumed, int[] offsetInWindow) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).dispatchNestedPreScroll(dx, dy, consumed,
                        offsetInWindow);
            
            return false;
        

        @Override
        public boolean dispatchNestedFling(View view, float velocityX, float velocityY,
                boolean consumed) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).dispatchNestedFling(velocityX, velocityY,
                        consumed);
            
            return false;
        

        @Override
        public boolean dispatchNestedPreFling(View view, float velocityX, float velocityY) 
            if (view instanceof NestedScrollingChild) 
                return ((NestedScrollingChild) view).dispatchNestedPreFling(velocityX, velocityY);
            
            return false;
        

        @Override
        public boolean isLaidOut(View view) 
            return ViewCompatBase.isLaidOut(view);
        

        @Override
        public int combineMeasuredStates(int curState, int newState) 
            return curState | newState;
        

        @Override
        public float getZ(View view) 
            return getTranslationZ(view) + getElevation(view);
        

        @Override
        public boolean isAttachedToWindow(View view) 
            return ViewCompatBase.isAttachedToWindow(view);
        

        @Override
        public boolean hasOnClickListeners(View view) 
            return false;
        

        @Override
        public int getScrollIndicators(View view) 
            return 0;
        

        @Override
        public void setScrollIndicators(View view, int indicators) 
            // no-op
        

        @Override
        public void setScrollIndicators(View view, int indicators, int mask) 
            // no-op
        
    

    static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl 
        @Override
        public boolean isOpaque(View view) 
            return ViewCompatEclairMr1.isOpaque(view);
        

        @Override
        public void setChildrenDrawingOrderEnabled(ViewGroup viewGroup, boolean enabled) 
            ViewCompatEclairMr1.setChildrenDrawingOrderEnabled(viewGroup, enabled);
        
    

    static class GBViewCompatImpl extends EclairMr1ViewCompatImpl 
        @Override
        public int getOverScrollMode(View v) 
            return ViewCompatGingerbread.getOverScrollMode(v);
        
        @Override
        public void setOverScrollMode(View v, int mode) 
            ViewCompatGingerbread.setOverScrollMode(v, mode);
        
    

    static class HCViewCompatImpl extends GBViewCompatImpl 
        @Override
        long getFrameTime() 
            return ViewCompatHC.getFrameTime();
        
        @Override
        public float getAlpha(View view) 
            return ViewCompatHC.getAlpha(view);
        
        @Override
        public void setLayerType(View view, int layerType, Paint paint) 
            ViewCompatHC.setLayerType(view, layerType, paint);
        
        @Override
        public int getLayerType(View vie

以上是关于ViewCompat:android官方实现兼容的一个帮助类的主要内容,如果未能解决你的问题,请参考以下文章

ViewCompat.animate(view) 动画的操作

SwitchCompat

Android 兼容 Java 8 语法特性的原理分析

转:android Support 兼容包详解

Android上有不兼容的类吗?

Android P版本(9.0) 新功能介绍和兼容性处理