好吧,忍受我吧,因为我没有那么多地使用自定义对话框(或者Android编程),我相信我犯了一个愚蠢的初学者错误。
所以我有一个简单的掷骰子的应用程序,我试图融入到我现有的应用程序,但我想做的基本上是一个弹出窗口。到目前为止,我找到的解决方案是扩展一个dialog类,并将应用程序中的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();

澄清一下:最让人困惑的是,无论是在编译时还是运行时,我都没有收到错误,它只是弹出窗口,不让我对它做任何事情(除了关闭)!

最佳答案

如果你想要对话之类的东西,我建议使用对话主题的活动。这将允许它像对话框一样“弹出”,但给你更多的灵活性和更容易操作,imho。创建一个单独的活动以打开并将其添加到活动的清单中
<activity android:theme="@android:style/Theme.Dialog">
Themes
也许有更好的方法可以做到这一点,但我认为这可能对你有好处。

关于java - 无法与Android自定义对话框进行交互,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14250404/

10-12 00:27
查看更多