解决自定义View android.view.InflateException: Binary XML file line #1

   Process: com.pipiyang.cn03, PID: 9409
    android.view.InflateException: Binary XML file line #1: Binary XML file line #1: Error inflating class com.example.view.ViewHeadParent
    Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class com.example.view.ViewHeadParent
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at android.view.LayoutInflater.createView(LayoutInflater.java:658)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:801)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
        at com.example.fragment.PullToShowHead.onCreateView(PullToShowHead.java:64)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517)
        at android.os.Handler.handleCallback(Handler.java:907)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7593)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
     Caused by: java.lang.NullPointerException: Attempt to write to field 'int android.view.ViewGroup$MarginLayoutParams.topMargin' on a null object reference
        at com.example.view.ViewHeadParent.init(ViewHeadParent.java:301)
        at com.example.view.ViewHeadParent.(ViewHeadParent.java:58)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
        at android.view.LayoutInflater.createView(LayoutInflater.java:658) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:801) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:741) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:423) 
        at com.example.fragment.PullToShowHead.onCreateView(PullToShowHead.java:64) 
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:1974) 
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252) 
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:742) 
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1617) 
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) 
        at android.os.Handler.handleCallback(Handler.java:907) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:216) 
        at android.app.ActivityThread.main(ActivityThread.java:7593) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 
2019-07-02 20:54:52.552 805-3204/? E/iMonitor: FaultDetect: DUMPTOOL_PRINTF re

XML:



    



Java:

package com.example.view;

import android.content.Context;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.GridView;

import com.example.getphoneapplication.R;


public class ViewHeadParent extends FrameLayout {

    private static final float FRICTION = 1.6f;
    private static final int PULL_TO_REFRESH = 0x0;
    private static final int RELEASE_TO_REFRESH = 0x1;
    public static final int MODE_PULL_DOWN_TO_REFRESH = 0x1;
    private int mTouchSlop;
    private float mInitialMotionY;
    private float lastMotionX;
    private float lastMotionY;
    private boolean isBeingDragged = false;
    private int state = PULL_TO_REFRESH;
    private int currentMode;
    private GridView mGridBookShelf;
    private OnHeadScrollChangedListener mScrollListener;
    private final Handler handler = new Handler();
    private SmoothScrollRunnable currentSmoothScrollRunnable;
    boolean isTob = true;
    private int mCurrentScrollY;
    private VelocityTracker velocity;
    private float velocityY = 0;
    private int mMoveSlop;
    private float initialMotionX;
    private static final int PULL_HOVER = 0x4;
    private static final int PULL_HOVER_REFRESH = 0x4;
    public static int UNIT;
    private boolean isFirstScrollCallBack = true;
    private ViewHeadLayout headerLayout;
    private float mRatio = 0;
    //禁用下拉功能
    private boolean disablePull = false;

    public ViewHeadParent(@NonNull Context context) {
        super(context);
        init(context);
    }

    public ViewHeadParent(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ViewHeadParent(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }



    public void setmGridBookShelf(final GridView mGridBookShelf) {
        this.mGridBookShelf = mGridBookShelf;
    }

    private boolean isCircleComplete() {
        return mRatio >= 1.0f;
    }

    @Override
    public final boolean onTouchEvent(MotionEvent event) {
        if (disablePull) {
            return super.onTouchEvent(event);
        }
        if (event.getAction() == MotionEvent.ACTION_DOWN && event.getEdgeFlags() != 0) {
            return false;
        }

        if (velocity == null) {
            velocity = VelocityTracker.obtain();//获得VelocityTracker类实例
        }
        if (velocity != null) {
            velocity.addMovement(event);
        }
        mCurrentScrollY = getScrollY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE: {
                float y = event.getY();
                float x = event.getX();
                isTob = (int) (y - mInitialMotionY) > 0;
                if (mCurrentScrollY >= 0 && !isTob) {
                    isBeingDragged = false;
                }
                if ((isBeingDragged || isPullDown()) && canScroll()) {
                    this.pullEvent(event);
                    lastMotionY = y;
                    lastMotionX = x;
                    return true;
                } else if ((isBeingDragged || isPullDown()) && !canScroll()) {
                    headerLayout.invalidateRatio(1.0f);
                } else {
                }
                lastMotionY = y;
                lastMotionX = x;
                break;
            }

            case MotionEvent.ACTION_DOWN: {
                if (isReadyForPullDown()) {
                    lastMotionY = mInitialMotionY = event.getY();
                    lastMotionX = initialMotionX = event.getX();
                    return true;
                }
                break;
            }

            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP: {
                if (velocity != null) {
                    velocity.computeCurrentVelocity(1000);
                    velocityY = (int) velocity.getYVelocity();
                }
                if (((!isTob && isBeingDragged && isPullDown()) && isNeedRelease()) || (headerLayout.getCurrentStatus() == ViewHeadLayout.Status.STATUS_DEFAULT)) {
                    isTob = false;
                    smoothScrollTo(0);
                    return true;
                }

                if ((velocityY > mMoveSlop || ((isTob && isBeingDragged && isPullDown()) && isCircleComplete())) && mEnableHoverPull) {
                    isTob = false;
                    state = PULL_HOVER;
                    currentMode = PULL_HOVER_REFRESH;
                    smoothScrollTo(-UNIT);
                    return true;
                }

                if (isBeingDragged || isPullDown()) {
                    isBeingDragged = false;
                    isTob = false;

                    if (state != PULL_HOVER) {
                        smoothScrollTo(0);
                    }
                    return true;
                }
                isTob = false;
                break;
            }
        }

        return false;
    }

    @Override
    public final boolean onInterceptTouchEvent(MotionEvent event) {
        mCurrentScrollY = getScrollY();

        final int action = event.getAction();

        if (action == MotionEvent.ACTION_DOWN && state != PULL_HOVER) {
            isBeingDragged = false;
        }


        if ((action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) && state != PULL_HOVER) {
            isBeingDragged = false;
            return false;
        }

        if (action == MotionEvent.ACTION_UP && state == PULL_HOVER) {//响应点击
            return false;
        }


        if (action != MotionEvent.ACTION_DOWN && isBeingDragged && state != PULL_HOVER) {
            return true;
        }

        //快速下拉松手后,还在 scroll 过程中,down,上推。
        if (action == MotionEvent.ACTION_DOWN && mCurrentScrollY != -UNIT && mCurrentScrollY != 0) {
            isBeingDragged = true;
            return true;
        }

        switch (action) {
            case MotionEvent.ACTION_MOVE: {
                final float y = event.getY();
                final float x = event.getX();

                final float dis = y - mInitialMotionY;
                final float mbsDis = Math.abs(dis);

                final float disX = x - initialMotionX;
                final float mbsDisX = Math.abs(disX);

                final float dy = y - lastMotionY;
                final float dx = x - lastMotionX;
                final float yDiff = Math.abs(dy);
                final float xDiff = Math.abs(dx);
                if (state == PULL_HOVER) {
                    if (mbsDis >= mTouchSlop * 0.6f /*&& mbsDisX <= mbsDis*/) {
                        lastMotionY = y;
                        lastMotionX = x;
                        currentMode = PULL_HOVER_REFRESH;
                        return true;
                    } else {
                        return false;
                    }
                }

                if (dy >= 0.0001f && mbsDis > mTouchSlop && yDiff > 0.8 * xDiff) {
                    if (state != PULL_HOVER && isReadyForPullDown()) {
                        lastMotionY = y;
                        lastMotionX = x;
                        isBeingDragged = true;
                        headerLayout.initData();
                        return isBeingDragged;
                    }
                }

                lastMotionY = y;
                lastMotionX = x;
                return false;//此时不应该拦截。
            }
            case MotionEvent.ACTION_DOWN: {
                lastMotionY = mInitialMotionY = event.getY();
                lastMotionX = initialMotionX = event.getX();
                if (state == PULL_HOVER) {
                    return false;
                } else if (isReadyForPullDown()) {
                    reset(false);
                    lastMotionY = mInitialMotionY = event.getY();
                    lastMotionX = initialMotionX = event.getX();
                    isBeingDragged = false;
                }
                break;
            }
        }
        return isBeingDragged;
    }
    public final int getHeaderHeight() {
        return UNIT;
    }

    protected boolean isReadyForPullDown() {
        if (mGridBookShelf == null) return /*this.getScrollY()*/mCurrentScrollY == 0;
        if (mGridBookShelf instanceof GridView) {
            GridView gridView = mGridBookShelf;
            int position = gridView.getFirstVisiblePosition();
            if (position != 0) {
                return false;
            }
            View item = gridView.getChildAt(position);//首行一半
            //-1
            return item != null && item.getTop() - gridView.getPaddingTop() == 0;
        }
        return mGridBookShelf.getScrollY() == 0;
    }

    protected boolean isPullDown() {
        return mCurrentScrollY < 0;
    }

    /**
     * 签到位是否处理关闭状态
     * @return
     */
    protected boolean isClose() {
        return getScrollY() == 0;
    }


    public final void smoothScrollTo(int y) {
        if (null != currentSmoothScrollRunnable) {
            currentSmoothScrollRunnable.stop();
        }

        if (mCurrentScrollY != y) {
            this.currentSmoothScrollRunnable = new SmoothScrollRunnable(handler, mCurrentScrollY, y);
            handler.post(currentSmoothScrollRunnable);
        }
    }

    public void init(Context context) {
//        mActivity = (ActivityBase) context;
        mMoveSlop = Util.dipToPixel2(context, 600);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        currentMode = MODE_PULL_DOWN_TO_REFRESH;
//        UNIT = BookSHUtil.getSignHeight();
        // 保证移动之后书封距离Title 6dp(书封内部paddingTop 30dp,在 ViewGridBookShelf 已经向上移了 12dp)
        UNIT = getResources().getDimensionPixelSize(R.dimen.sign_layout_height) + Util.dipToPixel2(getContext(),12);

LayoutParams lp = (LayoutParams) getLayoutParams();
 lp.topMargin = -UNIT - getResources().getDimensionPixelOffset(R.dimen.bookshelf_default_top_padding);


    }

一开始没有仔细看堆栈,他这个堆栈被分成了两截。后面的一截说明了原因,因为是你的自定义View 初始化方法里面,getLayoutParams,在这里面去拿,肯定是null, 后面你又设置了 lp.topMargin.导致空指针。

总结:

1.堆栈一定要看全。
2.自定义view 类加载失败,一般就是你类写的有问题。

你可能感兴趣的:(Android)