私は初めての Android プロジェクトに取り組んでいました。これはライブ壁紙であり、ここにあるチュートリアル、例、さらにはコードを使用してなんとか作業を進めることができましたが、まだ完成に至っていない問題があります。ユーザーがホーム画面を切り替えたときに、画像を視差スクロールするライブ壁紙が必要です。
これが私のコードです::
package com.livewallpaper.mw3lwp;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.WindowManager;
public class ModernWarfare3LiveWallpaper extends WallpaperService {
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
return new CubeEngine();
}
class CubeEngine extends Engine {
private final Paint mPaint = new Paint();
private float mPosY;
private float mPosX;
//private float mPosYBackup;
private boolean mAnime = true;
private Matrix mMatrix = new Matrix();
public int bgcycle = 0;
public Bitmap myBg;
public int idx = 0;
private float mPixels;
private final Runnable mDrawAnim = new Runnable() {
public void run() {
drawFrame();
}
};
private boolean mVisible;
private static final int NUM_RES = 50;
//private final Bitmap[] mPics = new Bitmap[NUM_RES];
public int getScreenOrientation() {
Display screen= ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = getResources().getConfiguration().orientation;
// UNDEFINED
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//Configuration config = getResources().getConfiguration();
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//if height and widht of screen are equal then
// it is square orientation
if(screen.getWidth()==screen.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
}else{ //if widht is less than height than it is portrait
if(screen.getWidth() < screen.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else{ // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
//
// Query what the orientation currently really is.
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// The following message is only displayed once.
return orientation/*= 1*/; // Portrait Mode
}else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// The following message is only displayed once.
return orientation/*= 2*/; // Landscape mode
}
return orientation;
}
public void updateBG() {
idx += 1;
if (idx == NUM_RES) {idx = 0;}
Resources res = getResources();
int id = res.getIdentifier("n" + (idx + 1), "drawable", "com.livewallpaper.mw3lwp");
myBg = BitmapFactory.decodeResource(res, id);
}
CubeEngine() {
Resources res = getResources();
//for (int i = 0; i< NUM_RES; i++) {
int id = res.getIdentifier("n" + (idx + 1), "drawable", "com.livewallpaper.mw3lwp");
myBg = BitmapFactory.decodeResource(res, id);
// if (i==NUM_RES) i=0;
// }
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(false);
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawAnim);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawAnim);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//if landscape
if (getScreenOrientation() == 2){
super.onSurfaceChanged(holder, format, width, height);
float w = myBg.getWidth();
float h = myBg.getHeight();
float s = width / (float)w;
mMatrix.reset();
mMatrix.setScale(s, s);
mPosY = (height - (h * s)) / 2f;
//mPixels= 0;
//mPosYBackup= mPosY;
drawFrame();
}
//
//if portrait
else {
super.onSurfaceChanged(holder, format, width, height);
float w = myBg.getWidth();
float h = myBg.getHeight();
float s = height / (float)h;
mMatrix.reset();
mMatrix.setScale(s, s);
//mMatrix.postScale(s, s, 0, 0);
// mPosY = 0f;
mPosX= (width - (w * s)) / 2f;
drawFrame();
}
//
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mDrawAnim);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
// Agregado recien
//if landscape
if (getScreenOrientation() == 2){
super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
//mPosY= mPosYBackup;
drawFrame();
}
//if portrait
else{
super.onOffsetsChanged(xOffset, yOffset, xStep, yStep, xPixels, yPixels);
mPixels = xPixels;
//mPosY=0f;
drawFrame();
}
// Fin Agregado
}
@Override
public void onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
mAnime = !mAnime;
}
super.onTouchEvent(event);
}
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
// draw something
drawAnim(c);
//drawTouchPoint(c);
}
} finally {
if (c != null) holder.unlockCanvasAndPost(c);
}
// Reschedule the next redraw
mHandler.removeCallbacks(mDrawAnim);
if (mVisible && mAnime) {
mHandler.postDelayed(mDrawAnim, 0);
}
}
void drawAnim(Canvas c) {
// if portrait
if(getScreenOrientation() == 1){
c.save();
//if (this.isPreview()) {
//c.translate(/*(float)*/mPosX, 0f);
//}
// MY PROBLEM HEREEEEE!!!! IM NOT USING BOTH
c.translate(/*(float)*/mPosX, 0f);
c.translate((float)mPixels, 0f);
updateBG();
c.drawBitmap(myBg, mMatrix, mPaint);
//c.drawBitmap(myBg, 0, 0, mPaint);
if (mAnime) ++idx;
if (idx == NUM_RES) idx = 0;
c.restore();
}
//end if portrait
// if landscape
if(getScreenOrientation() == 2){
c.save();
c.translate(0, mPosY);
updateBG();
c.drawBitmap(myBg, mMatrix, mPaint);
if (mAnime) ++idx;
if (idx == NUM_RES) idx = 0;
c.restore();
}
// end if landscape
//c.drawBitmap(mPics[idx], mMatrix, mPaint);
}
}
}
}
エラーがどこにあると思われるかを「MY PROBLEM IS HEREEE!!!」で指摘しました。コードで。事は canvas.translate(); にあります。
c.translate(mPosX, 0f); を使用する場合 onSurfacedChanged から取得した mPosX では、壁紙の画像の中央部分が希望どおりに表示されますが、背景全体をスクロールすることはできません。
c.translate((float)mPixels, 0f); を使用する場合 ここで、mPixels は onOffSetChanged から取得され、壁紙の左側の部分/ゾーンのみが表示されます。
最後に、mPosX の名前を mPixels に変更すると、c.translate((float)mPixels, 0f); onSurfacedChanged と onOffSetChanged の両方から値を取得します。最初の実行では機能しません。最初に壁紙が中央に表示され、次に壁紙の左側部分のみが表示されるようになります。Eclipseでもう一度実行して電話で再度設定すると、中央のホーム画面の画像の中央部分と、ホーム画面を切り替えるときに背景をスクロールして、希望どおりに機能します。ただし、最初の実行では機能しないため、apk としてエクスポートすると機能しなくなります。
ホーム画面を切り替えるときに、ライブ壁紙の画像を中央に表示してスクロールするのを手伝ってくれる人はいますか。前もって感謝します。