要实现的效果如下:
这个是什么相信知道安卓版本彩蛋的同学就知道了,刚开始在低分辨率是有用的,但是到了高分辨率就会报 内存溢出 的错
这是res/anim/lollipopshow.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="@drawable/anim0" android:duration="150" />
<item android:drawable="@drawable/anim1" android:duration="150" />
<item android:drawable="@drawable/anim2" android:duration="100" />
<item android:drawable="@drawable/anim3" android:duration="100" />
<item android:drawable="@drawable/anim4" android:duration="100" />
<item android:drawable="@drawable/anim5" android:duration="100" />
<item android:drawable="@drawable/anim6" android:duration="100" />
<item android:drawable="@drawable/anim7" android:duration="100" />
<item android:drawable="@drawable/anim8" android:duration="100" />
<item android:drawable="@drawable/anim9" android:duration="100" />
</animation-list>
就10张图片,感觉都不大,但就是报错了T_T,后来上网查了查,改了改,就OK了
这是改后的
public class VersionEggSwitch extends Activity {
private static final String LOG_TAG = "VersionEggSwitch";
private static boolean DEBUG = true;// false;
private static final int NEXT_IMG = 0;
private ImageView mNextImg;
private ImageView mBgImage;
private int loopIndex = 0;
private SwitchHandler mHandler;
private AnimationDrawable animationDrawable;
private FrameLayout mlollipop_main = null;
private WallpaperManager mWm;
private int[] image_resource;
private int[] image_duration;
private int MaxNum = 10;
private int initCount = 0;
private boolean canClicked = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.d(LOG_TAG, "onCreate()");
// 隐藏标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 隐藏状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.lollipop_main);
mlollipop_main = (FrameLayout) findViewById(R.id.lollipop_main);
Set_lollipop_main_Background();
image_resource = new int[MaxNum];
image_duration = new int[MaxNum];
mHandler = new SwitchHandler();
mBgImage = (ImageView) findViewById(R.id.egg_bg);
// mBgImage.setImageResource(0);
// mBgImage.setImageResource(R.anim.lollipopshow);
getFrameAndDuration(this, R.anim.lollipopshow);
// animationDrawable = (AnimationDrawable) mBgImage.getDrawable();
// // animationDrawable.start();
mNextImg = (ImageView) findViewById(R.id.bgswitch);
mNextImg.setOnClickListener(new ButtonListener());
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if(!hasFocus) return;
loadBitmap(mBgImage, image_resource, image_duration);
Log.d(LOG_TAG, "onWindowFocusChanged();hasFocus=" + hasFocus);
if (animationDrawable != null) {
animationDrawable.start();
}
int duration = 0;
for (int i = 0; i < animationDrawable.getNumberOfFrames(); i++) {
duration += animationDrawable.getDuration(i);
}
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
// 此处调用第二个动画播放方法
if (animationDrawable != null) {
animationDrawable.stop();
animationDrawable = null; // 这句话为解决内存溢出的关键,开始没有添加
}
// mlollipop_main.removeView(mBgImage);
canClicked = true;
mBgImage.setImageResource(0);
mBgImage.setImageResource(R.drawable.loop0);
System.gc();
}
}, duration);
super.onWindowFocusChanged(hasFocus);
}
public class ButtonListener implements OnClickListener {
public void onClick(View v) {
if (!canClicked) {
return;
}
mHandler.sendEmptyMessage(NEXT_IMG);
}
}
public class SwitchHandler extends Handler {
public void handleMessage(Message paramMessage) {
if (paramMessage.what == NEXT_IMG) {
UpdateCurrentBackground();
}
}
}
private void Set_lollipop_main_Background() {
Log.d(LOG_TAG, "Set_lollipop_main_Background()");
mWm = WallpaperManager.getInstance(this);
mlollipop_main.setBackgroundDrawable(mWm.getDrawable());
}
private void UpdateCurrentBackground() {
Bitmap swBitmap = null;
if (loopIndex > 5) {
loopIndex = loopIndex % 6;
}
switch (loopIndex) {
case 0:
swBitmap = readBitMap(this, R.drawable.loop0);
mBgImage.setImageBitmap(swBitmap);
loopIndex++;
break;
case 1:
swBitmap = readBitMap(this, R.drawable.loop1);
mBgImage.setImageBitmap(swBitmap);
loopIndex++;
break;
case 2:
swBitmap = readBitMap(this, R.drawable.loop2);
mBgImage.setImageBitmap(swBitmap);
loopIndex++;
break;
case 3:
swBitmap = readBitMap(this, R.drawable.loop3);
mBgImage.setImageBitmap(swBitmap);
loopIndex++;
break;
case 4:
swBitmap = readBitMap(this, R.drawable.loop4);
mBgImage.setImageBitmap(swBitmap);
loopIndex++;
break;
case 5:
swBitmap = readBitMap(this, R.drawable.loop5);
mBgImage.setImageBitmap(swBitmap);
loopIndex++;
break;
// case 6:
// mBgImage.setImageResource(R.drawable.loop6);
// loopIndex++;
// break;
default:
break;
}
}
/**
* 以最省内存的方式读取本地资源的图片
*
* @param context
* @param resId
* @return
*/
public static Bitmap readBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;
// 设置该属性可获得图片的长宽等信息,但是避免了不必要的提前加载动画
opt.inJustDecodeBounds = false;
// 获取资源图片
InputStream is = context.getResources().openRawResource(resId);
Bitmap bitmap = BitmapFactory.decodeStream(is, null, opt);
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onStop() {
super.onStop();
System.gc(); // 提醒系统及时回收
Log.d(LOG_TAG, "onStop()");
}
private void getFrameAndDuration(final Context context, final int animId) {
// TODO get every frame and its duration
new Thread(new Runnable() {
@Override
public void run() {
XmlResourceParser parser = context.getResources()
.getXml(animId);
try {
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
} else if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("item")) {
// byte[] bytes = null;
int duration = 1000;
for (int i = 0; i < parser.getAttributeCount(); i++) {
Log.d(LOG_TAG,
"getFrameAndDuration() attr="
+ parser.getAttributeName(i)
+ " value="
+ parser.getAttributeValue(i));
if (parser.getAttributeName(i).equals(
"drawable")) {
String imgStr = parser
.getAttributeValue(i)
.substring(1, 11);
int resId = Integer.parseInt(imgStr);
image_resource[initCount] = resId;
} else if (parser.getAttributeName(i)
.equals("duration")) {
duration = parser.getAttributeIntValue(
i, 1000);
image_duration[initCount] = duration;
}
}
initCount++;
}
} else if (eventType == XmlPullParser.END_TAG) {
} else if (eventType == XmlPullParser.TEXT) {
}
eventType = parser.next();
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e2) {
// TODO: handle exception
e2.printStackTrace();
}
}
}).start();
}
private void loadBitmap(ImageView imageView, int[] resIds, int[] interval) {
AnimationDrawable clipDrawable = new AnimationDrawable();
for (int i = 0; i < resIds.length; i++) {
clipDrawable.addFrame(new BitmapDrawable(readBitMap(this, resIds[i])), interval[i]);
}
clipDrawable.setOneShot(true);
animationDrawable = clipDrawable;
imageView.setImageDrawable(animationDrawable);
}
}
可以用了, 但感觉好像挺麻烦的, 而且有种东拼西凑的感觉, 如果有更好的方法,或这些代码有什么问题,麻烦告诉我。
参考: