2013-01-10 54 views
3

好了,多包涵,因为我还没有自定义对话框(或Android编程的一切真的)这么多的工作,我敢肯定,我犯了一个愚蠢的错误初学者。无法与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(); 

澄清:最令人困惑的部分是,我没有收到错误,无论是在编译或运行时,它只是弹出e窗口,不会让我对它做任何事情(除了解雇)!

回答

1

我建议,如果你想有点像一个对话框使用的活动与对话的主题。这将允许它像对话框一样“弹出”,但给你更多的灵活性和更容易操作,恕我直言。创建一个单独的活动,以开拓和添加到您的清单对活动

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

Themes

可能有更好的方法来做到这一点,但我认为这可能会为你工作。

+0

这实际上伟大的工作,谢谢! 我得到一个NullException与线103(mp.start),但我现在评论整个“MediaPlayer的”节出去(这只是扮演一个骰子滚动的声音 - 不要)和性能达到! –

+0

听起来不那么惊讶;)很高兴我能帮忙! – codeMagic