扩展类<unknown>时出错 - 运行时异常

时间:2015-09-01 18:12:38

标签: android xml runtimeexception

有人知道可能是随机发生的错误的来源,而无法确定明确的情况吗?

java.lang.RuntimeException: Unable to start activity ComponentInfo {com.xxx/com.xxx.activities.SplashActivity}: android.view.InflateException: Binary XML file line #38: Error inflating class <unknown>

布局中的片段发布在下面:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dark_gray">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:orientation="vertical">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/xl" />

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="sans-serif-light"
        android:gravity="center"
        android:padding="10dp"
        android:text="xxx"
        android:textColor="#FFF"
        android:textSize="24sp" />

</LinearLayout>

<RelativeLayout
    android:id="@+id/welcomeContent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.xxx.utils.ParallaxViewPager // line 38
        android:id="@+id/parallaxviewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg_parallax">

com.xxx.utils.ParallaxViewPager 存在,我可以非常随机地捕获错误。

public class ParallaxViewPager extends ViewPager {

public static final int FIT_WIDTH = 0;
public static final int FIT_HEIGHT = 1;
public static final float OVERLAP_FULL = 1f;
public static final float OVERLAP_HALF = 0.5f;
public static final float OVERLAP_QUARTER = 0.25f;
private static final float CORRECTION_PERCENTAGE = 0.01f;
public Bitmap bitmap;
private Rect source, destination;
private int scaleType;
private int chunkWidth;
private int projectedWidth;
private float overlap;
private OnPageChangeListener secondOnPageChangeListener;
private TextView[] dots;
private ScrollerCustomDuration mScroller = null;

float mStartDragX;
OnSwipeOutListener mListener;

public ParallaxViewPager(Context context) {
    super(context);
    init();
}

public ParallaxViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();

    postInitViewPager();
}

public void setScrollDurationFactor(double scrollFactor) {
    mScroller.setScrollDurationFactor(scrollFactor);
}

public void setOnSwipeOutListener(OnSwipeOutListener listener) {
    mListener = listener;
}

private void init() {
    source = new Rect();
    destination = new Rect();
    scaleType = FIT_HEIGHT;
    overlap = OVERLAP_HALF;

    setOnPageChangeListener(new OnPageChangeListener() {
        @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if (position < 3) {
                if (bitmap != null) {
                    source.left = (int) Math.floor((position + positionOffset - CORRECTION_PERCENTAGE) * chunkWidth);
                    source.right = (int) Math.ceil((position + positionOffset + CORRECTION_PERCENTAGE) * chunkWidth + projectedWidth);
                    destination.left = (int) Math.floor((position + positionOffset - CORRECTION_PERCENTAGE) * getWidth());
                    destination.right = (int) Math.ceil((position + positionOffset + 1 + CORRECTION_PERCENTAGE) * getWidth());
                    invalidate();
                }

                if (secondOnPageChangeListener != null) {
                    secondOnPageChangeListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
                }
            }
        }

        @Override public void onPageSelected(int position) {
            if (secondOnPageChangeListener != null) {
                secondOnPageChangeListener.onPageSelected(position);
            }

            for (int i = 0; i < 3; i++) {
                dots[i].setTextColor(getResources().getColor(android.R.color.darker_gray));
            }
            if (position < 3) {
                dots[position].setTextColor(getResources().getColor(R.color.tw__solid_white));
            }

            if (position == 3) {
                mListener.onSwipeOutAtEnd();
            }
        }

        @Override public void onPageScrollStateChanged(int state) {
            if (secondOnPageChangeListener != null) {
                secondOnPageChangeListener.onPageScrollStateChanged(state);
            }
        }
    });
}

@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    destination.top = 0;
    destination.bottom = h;
    if (getAdapter() != null && bitmap != null)
        calculateParallaxParameters();
}

private void calculateParallaxParameters() {
    if (bitmap.getWidth() < getWidth() && bitmap.getWidth() < bitmap.getHeight() && scaleType == FIT_HEIGHT) {
        Log.w(ParallaxViewPager.class.getName(), "Invalid bitmap bounds for the current device, parallax effect will not work.");
    }

    final float ratio = (float) getHeight() / bitmap.getHeight();
    if (ratio != 1) {
        switch (scaleType) {
            case FIT_WIDTH:
                source.top = (int) ((bitmap.getHeight() - bitmap.getHeight() / ratio) / 2);
                source.bottom = bitmap.getHeight() - source.top;
                chunkWidth = (int) Math.ceil((float) bitmap.getWidth() / (float) getAdapter().getCount());
                projectedWidth = chunkWidth;
                break;
            case FIT_HEIGHT:
            default:
                source.top = 0;
                source.bottom = bitmap.getHeight();
                projectedWidth = (int) Math.ceil(getWidth() / ratio);
                chunkWidth = (int) Math.ceil((bitmap.getWidth() - projectedWidth) / (float) getAdapter().getCount() * overlap);
                break;
        }
    }
}

/**
 * Sets the background from a resource file.
 *
 * @param resid
 */
@Override public void setBackgroundResource(int resid) {
    bitmap = BitmapFactory.decodeResource(getResources(), resid);
}

/**
 * Sets the background from a Drawable.
 *
 * @param background
 */
@Override public void setBackground(Drawable background) {
    bitmap = ((BitmapDrawable) background).getBitmap();
}

/**
 * Deprecated.
 * Sets the background from a Drawable.
 *
 * @param background
 */
@Override public void setBackgroundDrawable(Drawable background) {
    bitmap = ((BitmapDrawable) background).getBitmap();
}

/**
 * Sets the background from a bitmap.
 *
 * @param bitmap
 * @return The ParallaxViewPager object itself.
 */
public ParallaxViewPager setBackground(Bitmap bitmap) {
    this.bitmap = bitmap;
    return this;
}

/**
 * Sets how the view should scale the background. The available choices are:
 * <ul>
 * <li>FIT_HEIGHT - the height of the image is resized to matched the height of the View, also stretching the width to keep the aspect ratio. The non-visible part of the bitmap is divided into equal parts, each of them sliding in at the proper position.</li>
 * <li>FIT_WIDTH - the width of the background image is divided into equal chunks, each taking up the whole width of the screen.</li>
 * </ul>
 *
 * @param scaleType
 * @return
 */
public ParallaxViewPager setScaleType(final int scaleType) {
    if (scaleType != FIT_WIDTH && scaleType != FIT_HEIGHT)
        throw new IllegalArgumentException("Illegal argument: scaleType must be FIT_WIDTH or FIT_HEIGHT");
    this.scaleType = scaleType;
    return this;
}

/**
 * Sets the amount of overlapping with the setOverlapPercentage(final float percentage) method. This is a number between 0 and 1, the smaller it is, the slower is the background scrolling.
 *
 * @param percentage
 * @return The ParallaxViewPager object itself.
 */
public ParallaxViewPager setOverlapPercentage(final float percentage) {
    if (percentage <= 0 || percentage >= 1)
        throw new IllegalArgumentException("Illegal argument: percentage must be between 0 and 1");
    overlap = percentage;
    return this;
}

/**
 * Recalculates the parameters of the parallax effect, useful after changes in runtime.
 *
 * @return The ParallaxViewPager object itself.
 */
public ParallaxViewPager invalidateParallaxParameters() {
    calculateParallaxParameters();
    return this;
}

@Override protected void onDraw(Canvas canvas) {
    if (bitmap != null)
        canvas.drawBitmap(bitmap, source, destination, null);
}

public void addOnPageChangeListener(OnPageChangeListener listener) {
    secondOnPageChangeListener = listener;
}

public TextView[] getDots() {
    return dots;
}

public void setDots(TextView[] dots) {
    this.dots = dots;
}

private void postInitViewPager() {
    try {
        Class<?> viewpager = ViewPager.class;
        Field scroller = viewpager.getDeclaredField("mScroller");
        scroller.setAccessible(true);
        Field interpolator = viewpager.getDeclaredField("sInterpolator");
        interpolator.setAccessible(true);

        mScroller = new ScrollerCustomDuration(getContext(),
                (Interpolator) interpolator.get(null));
        scroller.set(this, mScroller);
    } catch (Exception e) {
        Log.e("MyPager", e.getMessage());
    }
}

class ScrollerCustomDuration extends Scroller {
    private double mScrollFactor = 2;

    public ScrollerCustomDuration(Context context) {
        super(context);
    }

    public ScrollerCustomDuration(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    public ScrollerCustomDuration(Context context,
                                  Interpolator interpolator, boolean flywheel) {
        super(context, interpolator, flywheel);
    }

    /**
     * Set the factor by which the duration will change
     */
    public void setScrollDurationFactor(double scrollFactor) {
        mScrollFactor = scrollFactor;
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy,
                            int duration) {
        super.startScroll(startX, startY, dx, dy,
                (int) (duration * mScrollFactor));
    }

}

public interface OnSwipeOutListener {
    public void onSwipeOutAtEnd();
}}

感谢您的意见。

0 个答案:

没有答案