2
我總是得到異常,當我嘗試用運動圖像android.view.InflateException不能刪除
日誌
07-20 20:38:32.393: D/dalvikvm(13148): Late-enabling CheckJNI
07-20 20:38:32.538: E/Trace(13148): error opening trace file: No such file or directory (2)
07-20 20:38:32.713: D/AbsListView(13148): Get MotionRecognitionManager
07-20 20:38:32.738: D/AndroidRuntime(13148): Shutting down VM
07-20 20:38:32.738: W/dalvikvm(13148): threadid=1: thread exiting with uncaught exception (group=0x40edf2a0)
07-20 20:38:32.743: E/AndroidRuntime(13148): FATAL EXCEPTION: main
07-20 20:38:32.743: E/AndroidRuntime(13148): java.lang.RuntimeException: Unable to start activity ComponentInfo{example.example.actionbar/example.example.actionbar.Main}: android.view.InflateException: Binary XML file line #20: Error inflating class example.example.actionbar
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2110)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.ActivityThread.access$700(ActivityThread.java:140)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.os.Handler.dispatchMessage(Handler.java:99)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.os.Looper.loop(Looper.java:137)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.ActivityThread.main(ActivityThread.java:4921)
07-20 20:38:32.743: E/AndroidRuntime(13148): at java.lang.reflect.Method.invokeNative(Native Method)
07-20 20:38:32.743: E/AndroidRuntime(13148): at java.lang.reflect.Method.invoke(Method.java:511)
07-20 20:38:32.743: E/AndroidRuntime(13148): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
07-20 20:38:32.743: E/AndroidRuntime(13148): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
07-20 20:38:32.743: E/AndroidRuntime(13148): at dalvik.system.NativeStart.main(Native Method)
07-20 20:38:32.743: E/AndroidRuntime(13148): Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class example.example.actionbar
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:698)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
07-20 20:38:32.743: E/AndroidRuntime(13148): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:313)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.Activity.setContentView(Activity.java:1924)
07-20 20:38:32.743: E/AndroidRuntime(13148): at example.example.actionbar.Main.onCreate(Main.java:49)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.Activity.performCreate(Activity.java:5206)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
07-20 20:38:32.743: E/AndroidRuntime(13148): ... 11 more
07-20 20:38:32.743: E/AndroidRuntime(13148): Caused by: java.lang.ClassNotFoundException: example.example.actionbar
07-20 20:38:32.743: E/AndroidRuntime(13148): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
07-20 20:38:32.743: E/AndroidRuntime(13148): at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
07-20 20:38:32.743: E/AndroidRuntime(13148): at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.createView(LayoutInflater.java:552)
07-20 20:38:32.743: E/AndroidRuntime(13148): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
07-20 20:38:32.743: E/AndroidRuntime(13148): ... 22 more
AlphaForegroundColorSpan.java
package example.example.actionbar;
import android.graphics.Color;
import android.os.Parcel;
import android.text.TextPaint;
import android.text.style.ForegroundColorSpan;
public class AlphaForegroundColorSpan extends ForegroundColorSpan {
private float mAlpha;
public AlphaForegroundColorSpan(int color) {
super(color);
}
public AlphaForegroundColorSpan(Parcel src) {
super(src);
mAlpha = src.readFloat();
}
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeFloat(mAlpha);
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(getAlphaColor());
}
public void setAlpha(float alpha) {
mAlpha = alpha;
}
public float getAlpha() {
return mAlpha;
}
private int getAlphaColor() {
int foregroundColor = getForegroundColor();
return Color.argb((int) (mAlpha * 255), Color.red(foregroundColor), Color.green(foregroundColor), Color.blue(foregroundColor));
}
}
KenBurnsView運行沒有動作條.java
package example.example.actionbar;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import java.util.Random;
/**
* Created by f.laurent on 21/11/13.
*/
public class KenBurnsView extends FrameLayout {
private static final String TAG = "KenBurnsView";
private final Handler mHandler;
private int[] mResourceIds;
private ImageView[] mImageViews;
private int mActiveImageIndex = -1;
private final Random random = new Random();
private int mSwapMs = 10000;
private int mFadeInOutMs = 400;
private float maxScaleFactor = 1.5F;
private float minScaleFactor = 1.2F;
private Runnable mSwapImageRunnable = new Runnable() {
@Override
public void run() {
swapImage();
mHandler.postDelayed(mSwapImageRunnable, mSwapMs - mFadeInOutMs*2);
}
};
public KenBurnsView(Context context) {
this(context, null);
}
public KenBurnsView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public KenBurnsView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mHandler = new Handler();
}
public void setResourceIds(int... resourceIds) {
mResourceIds = resourceIds;
fillImageViews();
}
private void swapImage() {
Log.d(TAG, "swapImage active=" + mActiveImageIndex);
if(mActiveImageIndex == -1) {
mActiveImageIndex = 1;
animate(mImageViews[mActiveImageIndex]);
return;
}
int inactiveIndex = mActiveImageIndex;
mActiveImageIndex = (1 + mActiveImageIndex) % mImageViews.length;
Log.d(TAG, "new active=" + mActiveImageIndex);
final ImageView activeImageView = mImageViews[mActiveImageIndex];
activeImageView.setAlpha(0.0f);
ImageView inactiveImageView = mImageViews[inactiveIndex];
animate(activeImageView);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(mFadeInOutMs);
animatorSet.playTogether(
ObjectAnimator.ofFloat(inactiveImageView, "alpha", 1.0f, 0.0f),
ObjectAnimator.ofFloat(activeImageView, "alpha", 0.0f, 1.0f)
);
animatorSet.start();
}
private void start(View view, long duration, float fromScale, float toScale, float fromTranslationX, float fromTranslationY, float toTranslationX, float toTranslationY) {
view.setScaleX(fromScale);
view.setScaleY(fromScale);
view.setTranslationX(fromTranslationX);
view.setTranslationY(fromTranslationY);
ViewPropertyAnimator propertyAnimator = view.animate().translationX(toTranslationX).translationY(toTranslationY).scaleX(toScale).scaleY(toScale).setDuration(duration);
propertyAnimator.start();
Log.d(TAG, "starting Ken Burns animation " + propertyAnimator);
}
private float pickScale() {
return this.minScaleFactor + this.random.nextFloat() * (this.maxScaleFactor - this.minScaleFactor);
}
private float pickTranslation(int value, float ratio) {
return value * (ratio - 1.0f) * (this.random.nextFloat() - 0.5f);
}
public void animate(View view) {
float fromScale = pickScale();
float toScale = pickScale();
float fromTranslationX = pickTranslation(view.getWidth(), fromScale);
float fromTranslationY = pickTranslation(view.getHeight(), fromScale);
float toTranslationX = pickTranslation(view.getWidth(), toScale);
float toTranslationY = pickTranslation(view.getHeight(), toScale);
start(view, this.mSwapMs, fromScale, toScale, fromTranslationX, fromTranslationY, toTranslationX, toTranslationY);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
startKenBurnsAnimation();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacks(mSwapImageRunnable);
}
private void startKenBurnsAnimation() {
mHandler.post(mSwapImageRunnable);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View view = inflate(getContext(), R.layout.view_kenburns, this);
mImageViews = new ImageView[2];
mImageViews[0] = (ImageView) view.findViewById(R.id.image0);
mImageViews[1] = (ImageView) view.findViewById(R.id.image1);
}
private void fillImageViews() {
for (int i = 0; i < mImageViews.length; i++) {
mImageViews[i].setImageResource(mResourceIds[i]);
}
}
}
Main.java
package example.example.actionbar;
import java.util.ArrayList;
import android.R.string;
import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.RectF;
import android.text.Spannable;
import android.text.SpannableString;
import android.util.TypedValue;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
public class Main extends Activity {
private static final String TAG = "NoBoringActionBarActivity";
private int mActionBarTitleColor;
private int mActionBarHeight;
private int mHeaderHeight;
private int mMinHeaderTranslation;
private ListView mListView;
private KenBurnsView mHeaderPicture;
private ImageView mHeaderLogo;
private View mHeader;
private View mPlaceHolderView;
private AccelerateDecelerateInterpolator mSmoothInterpolator;
private RectF mRect1 = new RectF();
private RectF mRect2 = new RectF();
private AlphaForegroundColorSpan mAlphaForegroundColorSpan;
private SpannableString mSpannableString;
private TypedValue mTypedValue = new TypedValue();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSmoothInterpolator = new AccelerateDecelerateInterpolator();
mHeaderHeight = getResources().getDimensionPixelSize(R.dimen.header_height);
mMinHeaderTranslation = -mHeaderHeight + getActionBarHeight();
mListView = (ListView) findViewById(R.id.listview);
mHeader = findViewById(R.id.header);
mHeaderPicture = (KenBurnsView) findViewById(R.id.header_picture);
mHeaderPicture.setResourceIds(R.drawable.picture0, R.drawable.picture1);
mHeaderLogo = (ImageView) findViewById(R.id.header_logo);
mActionBarTitleColor = getResources().getColor(R.color.actionbar_title_color);
mSpannableString = new SpannableString(getString(R.string.noboringactionbar_title));
mAlphaForegroundColorSpan = new AlphaForegroundColorSpan(mActionBarTitleColor);
setupActionBar();
setupListView();
}
private void setupListView() {
ArrayList<String> FAKES = new ArrayList<String>();
for (int i = 0; i < 1000; i++) {
FAKES.add("entry " + i);
}
mPlaceHolderView = getLayoutInflater().inflate(R.layout.view_header_placeholder, mListView, false);
mListView.addHeaderView(mPlaceHolderView);
mListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, FAKES));
mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int scrollY = getScrollY();
//sticky actionbar
mHeader.setTranslationY(Math.max(-scrollY, mMinHeaderTranslation));
//header_logo --> actionbar icon
float ratio = clamp(mHeader.getTranslationY()/mMinHeaderTranslation, 0.0f, 1.0f);
interpolate(mHeaderLogo, getActionBarIconView(), mSmoothInterpolator.getInterpolation(ratio));
//actionbar title alpha
//getActionBarTitleView().setAlpha(clamp(5.0F * ratio - 4.0F, 0.0F, 1.0F));
//---------------------------------
//better way thanks to @cyrilmottier
setTitleAlpha(clamp(5.0F * ratio - 4.0F, 0.0F, 1.0F));
}
});
}
private void setTitleAlpha(float alpha) {
mAlphaForegroundColorSpan.setAlpha(alpha);
mSpannableString.setSpan(mAlphaForegroundColorSpan, 0, mSpannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
getActionBar().setTitle(mSpannableString);
}
public static float clamp(float value, float min, float max) {
return Math.max(min,Math.min(value, max));
}
private void interpolate(View view1, View view2, float interpolation) {
getOnScreenRect(mRect1, view1);
getOnScreenRect(mRect2, view2);
float scaleX = 1.0F + interpolation * (mRect2.width()/mRect1.width() - 1.0F);
float scaleY = 1.0F + interpolation * (mRect2.height()/mRect1.height() - 1.0F);
float translationX = 0.5F * (interpolation * (mRect2.left + mRect2.right - mRect1.left - mRect1.right));
float translationY = 0.5F * (interpolation * (mRect2.top + mRect2.bottom - mRect1.top - mRect1.bottom));
view1.setTranslationX(translationX);
view1.setTranslationY(translationY - mHeader.getTranslationY());
view1.setScaleX(scaleX);
view1.setScaleY(scaleY);
}
private RectF getOnScreenRect(RectF rect, View view) {
rect.set(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
return rect;
}
public int getScrollY() {
View c = mListView.getChildAt(0);
if (c == null) {
return 0;
}
int firstVisiblePosition = mListView.getFirstVisiblePosition();
int top = c.getTop();
int headerHeight = 0;
if (firstVisiblePosition >= 1) {
headerHeight = mPlaceHolderView.getHeight();
}
return -top + firstVisiblePosition * c.getHeight() + headerHeight;
}
private void setupActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setIcon(R.drawable.ic_transparent);
//getActionBarTitleView().setAlpha(0f);
}
private ImageView getActionBarIconView() {
return (ImageView) findViewById(android.R.id.home);
}
/*private TextView getActionBarTitleView() {
int id = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
return (TextView) findViewById(id);
}*/
public int getActionBarHeight() {
if (mActionBarHeight != 0) {
return mActionBarHeight;
}
getTheme().resolveAttribute(android.R.attr.actionBarSize, mTypedValue, true);
mActionBarHeight = TypedValue.complexToDimensionPixelSize(mTypedValue.data, getResources().getDisplayMetrics());
return mActionBarHeight;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
ParallaxImageView.java
package example.example.actionbar;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.ImageView;
/**
* Created by f.laurent on 21/11/13.
* antoine-merle.com inspiration
*/
public class ParallaxImageView extends ImageView {
private int mCurrentTranslation;
public ParallaxImageView(Context context) {
super(context);
}
public ParallaxImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ParallaxImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setCurrentTranslation(int currentTranslation) {
mCurrentTranslation = currentTranslation;
invalidate();
}
@Override
public void draw(Canvas canvas) {
canvas.save();
canvas.translate(0, -mCurrentTranslation/2) ;
super.draw(canvas);
canvas.restore();
}
}
main.xml中
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NoBoringActionBarActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
<FrameLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height">
<example.example.actionbar
android:id="@+id/header_picture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/picture0" />
<ImageView
android:id="@+id/header_logo"
android:layout_width="@dimen/header_logo_size"
android:layout_height="@dimen/header_logo_size"
android:layout_gravity="center"
android:src="@drawable/ic_header_logo" />
</FrameLayout>
</FrameLayout>
view_header_placeholder.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height"
android:orientation="vertical">
</LinearLayout>
view_kenburns.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/image0"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/image1"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
風格,v14.xml
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
<item name="android:windowBackground">@null</item>
<item name="android:actionBarStyle">@style/MyActionBarTheme</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
<style name="MyActionBarTheme" parent="@android:style/Widget.ActionBar">
<item name="android:background">@null</item>
<item name="android:displayOptions">homeAsUp|showHome|showTitle</item>
<item name="android:titleTextStyle">@style/AppTheme</item>
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:textColor">@android:color/white</item>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>