3

わかりました。私はカスタムダイアログ(またはAndroidプログラミング)をあまり使用していないので、我慢してください。私は愚かな初心者の間違いを犯したと確信しています。

だから私は既存のアプリに取り入れようとしている単純なサイコロを振るアプリを持っていますが、本質的にはポップアップとしてそれをやりたいと思っています。これまでに見つけた解決策は、ダイアログクラスを拡張し、アプリのxmlをカスタムレイアウトとして使用することでした。これは実際には期待される出力を表示しますが、それを操作することはできません(つまり、画面にサイコロが表示されますが、サイコロを振ることはできません!)。

私が呼んでいるJavaクラスはこれです:

import java.io.IOException;
import java.util.Random;
import com.zeldar.scanner.R;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class RollDice extends Activity implements SensorEventListener {
    private final int rollAnimations = 50;
    private final int delayTime = 15;
    private Resources res;
    private final int[] diceImages = new int[] { R.drawable.d1, R.drawable.d2, R.drawable.d3, R.drawable.d4, R.drawable.d5, R.drawable.d6 };
    private Drawable dice[] = new Drawable[6];
    private final Random randomGen = new Random();
    @SuppressWarnings("unused")
    private int diceSum;
    private int roll[] = new int[] { 6, 6 };
    private ImageView die1;
    private ImageView die2;
    private LinearLayout diceContainer;
    private SensorManager sensorMgr; 
    private Handler animationHandler;
    private long lastUpdate = -1;
    private float x, y, z;
    private float last_x, last_y, last_z;
    private boolean paused = false;
    private static final int UPDATE_DELAY = 50;
    private static final int SHAKE_THRESHOLD = 400;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        paused = false;
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dice);
        setTitle(getString(R.string.app_name));
        res = getResources();
        for (int i = 0; i < 6; i++) {
            dice[i] = res.getDrawable(diceImages[i]);
        }
        diceContainer = (LinearLayout) findViewById(R.id.diceContainer);
        diceContainer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    rollDice();
                } catch (Exception e) {};
            }
        });
        die1 = (ImageView) findViewById(R.id.die1);
        die2 = (ImageView) findViewById(R.id.die2);
        animationHandler = new Handler() {
            public void handleMessage(Message msg) {
                die1.setImageDrawable(dice[roll[0]]);
                die2.setImageDrawable(dice[roll[1]]);
            }
        };
        sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
        boolean accelSupported = sensorMgr.registerListener(this,
                sensorMgr.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
        if (!accelSupported) sensorMgr.unregisterListener(this); //no accelerometer on the device
        rollDice();
    }

    private void rollDice() {
        if (paused) return;
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < rollAnimations; i++) {
                    doRoll();
                }
            }
        }).start();
        MediaPlayer mp = MediaPlayer.create(this, R.raw.roll);
        try {
            mp.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        mp.start();
    }

    private void doRoll() { // only does a single roll
        roll[0] = randomGen.nextInt(6);
        roll[1] = randomGen.nextInt(6);
        diceSum = roll[0] + roll[1] + 2; // 2 is added because the values of the rolls start with 0 not 1
        synchronized (getLayoutInflater()) {
            animationHandler.sendEmptyMessage(0);
        }
        try { // delay to alloy for smooth animation
            Thread.sleep(delayTime);
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void onResume() {
        super.onResume();
        paused = false;
    }

    public void onPause() {
        super.onPause();
        paused = true;
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        Sensor mySensor = event.sensor;
        if (mySensor.getType() == SensorManager.SENSOR_ACCELEROMETER) {
            long curTime = System.currentTimeMillis();
            if ((curTime - lastUpdate) > UPDATE_DELAY) {
                long diffTime = (curTime - lastUpdate);
                lastUpdate = curTime;
                x = event.values[SensorManager.DATA_X];
                y = event.values[SensorManager.DATA_Y];
                z = event.values[SensorManager.DATA_Z];
                float speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;
                if (speed > SHAKE_THRESHOLD) { //the screen was shaked
                    rollDice();
                }
                last_x = x;
                last_y = y;
                last_z = z;
            }
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        return; //this method isn't used
    }
}

そしてこれはレイアウトxmlです:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@+id/diceContainer"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/die1" 
        android:src="@drawable/d6"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginBottom="15dp"
        android:contentDescription="@string/content_dice" />

    <ImageView
        android:id="@+id/die2"
        android:src="@drawable/d6"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:contentDescription="@string/content_dice" />

</LinearLayout>

最後に、ダイアログの作成に使用している呼び出しは次のとおりです。

private Dialog rollDice;

rollDice = new Dialog(ScanActivity.this);
rollDice.setContentView(R.layout.dice);
rollDice.setTitle("Roll Dice");
rollDice.setCancelable(true);
rollDice.show();

To clarify: the most confusing part is that I'm not getting an error, either on compile or run time, it just pops up the window and won't let me do anything with it (except dismiss)!

4

1 に答える 1

1

I would suggest using an activity with a dialog theme if you are wanting something like a dialog. This will allow it to "pop-up" like a dialog but give you more flexibility and easier to manipulate, IMHO. Create a separate activity to open up and add this to your manifest for the activity

<activity android:theme="@android:style/Theme.Dialog">

Themes

There may be a better way to do this but I think this might work well for you.

于 2013-01-10T03:53:41.617 に答える