Dice开发笔记——记我的第一个Android应用

本文介绍了一个简单的Android应用开发过程,该应用可以模拟掷骰子,并通过摇动手机触发功能。文章详细讲解了如何使用Java语言实现随机数生成、图片切换、声音播放和手机震动反馈等功能。


 

一、主窗口:

系统默认情况下,主窗口为非 全屏,有title,会根据重力翻转屏幕,且每次翻转会重画初始界面状态。

通过mainfest.xml文件里设置可固定屏幕方向,设置为全屏无title的。

在activity中加入以下代码

android:screenOrientation="portrait"

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

另外,感觉用xml文件来布局还是不太熟悉,特别是各种layout,感觉界面布局不如拖拽来的直接简单。当然我也知道熟悉后的各种好处,只是这里抱怨下。

 

二、主体功能:掷色子

代码:

    void shake_dice(){
    ImageButtonmyib=(ImageButton)findViewById(R.id.imageButton1);
MediaPlayer shakeVoice=MediaPlayer.create(getApplicationContext(),R.raw.dice_voice);//声音
    shakeVoice.start();
 
    mVibrator.vibrate(50);//震动
   
    //按键延时
    try {
        if(diceButtonAvailable){
            myib.setClickable(false);
            Thread.sleep(500);
            myib.setClickable(true);
        }
        else
            Thread.sleep(500);
       } catch (InterruptedException e) {
           // TODO Auto-generatedcatch block
           e.printStackTrace();
       }
   
       //产生随机数显示图片
       int mran=(int)(Math.random()*6+1);
       if(mran==1)
           myib.setImageResource(R.drawable.dice1);
       else if(mran==2)
           myib.setImageResource(R.drawable.dice2);
       else if(mran==3)
           myib.setImageResource(R.drawable.dice3);
       else if(mran==4)
           myib.setImageResource(R.drawable.dice4);
       else if(mran==5)
           myib.setImageResource(R.drawable.dice5);
       else if(mran==6)
           myib.setImageResource(R.drawable.dice6);
       else
           myib.setImageResource(R.drawable.face);
 
       myv.release();
 
    }
 
    public void clickImageButton(View theButton){
    shake_dice();
}
 

详细情况:

1、  生产随机数,匹配,重画ImageButton

2、声音:

MediaPlayer myv=MediaPlayer.create(getApplicationContext(),R.raw.dice_voice);
myv.start();//声音
    myv.release();

开始加入MediaPlayer,在多次摇色子后程序会崩溃,之后加入release后正常运行,估计是多次调用不断new出新的MediaPlayer导致“过载”了吧

3、  震动:

<uses-permission android:name="android.permission.VIBRATE"/>

    mVibrator.vibrate(50);//震动

   没什么好讲,调用一下,参数是震动时间,单位ms(震动还有多种重载函数,可实现变频震动)。

注意:要先在Manifest.xml文件中加入第一行代码,获得调用的权限。

4、  延时:

Thread.sleep(500);

   没有达到预想的效果,原想加上色子快速变化最后停下的效果,没有实现,估计得换个延时的方案

5、  按键无效:

myib.setClickable(false);

  sleep期间有点击n次的话,重设为true后会立即调用重复n次,全部执行完后图片变化

 

三、摇动功能

代码:

 

变量声明:

  

  private float x,y,z,last_x,last_y,last_z;
    private long lastUpdate=System.currentTimeMillis();
    // recordtimes of useful shakes for test
    private int mTimes;
   
    // 越小越灵敏
    private static final int SHAKE_THRESHOLD = 1800;
    private static final int START_SHAKE = 0;
    private SensorManager mSensorManager;
    private throwdice myThrowDice;
 

onCreate函数中的代码:

        myThrowDice=new throwdice();
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
    mSensorManager.registerListener(myThrowDice ,mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
              SensorManager.SENSOR_DELAY_GAME);
 


功能实现:

 

class throwdiceimplements SensorEventListener {
    @Override
    public voidonAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub
    }
 
    @Override
    public voidonSensorChanged(SensorEvent event) {
        doOnSensorChangedJob(event.sensor.getType(), event.values);
    }
 
    private voiddoOnSensorChangedJob(int sensor, float[] values) {
        if (sensor == Sensor.TYPE_ACCELEROMETER) {
            long curTime = System.currentTimeMillis();
            // 测100毫秒速度
            if ((int)(curTime - lastUpdate) > 100) {
               long diffTime =(curTime - lastUpdate);
               x =values[SensorManager.DATA_X];
               y =values[SensorManager.DATA_Y];
               z =values[SensorManager.DATA_Z];
               TextViewmytv1=(TextView)findViewById(R.id.textView1);
               TextViewmytv2=(TextView)findViewById(R.id.textView2);
               TextViewmytv3=(TextView)findViewById(R.id.textView3);
               mytv1.setText(x+"");
               mytv2.setText(y+"");
               mytv3.setText(z+"");
               float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime *10000;
               // Log.i("Throw", "Throw at speed " +speed);
               if ((int)speed > SHAKE_THRESHOLD) {
                   shake_dice();
                   // 检测到摇晃后执行的代码
                  
                   Messagemsg = mHandler.obtainMessage();
                   msg.what = START_SHAKE;
                   // Bundle data = new Bundle();
                   // data.putLong("lastUpdate", lastUpdate);
                   // data.putLong("curTime", curTime);
                   // data.putFloat("speed", speed);
                   // msg.setData(data);
                   mHandler.removeMessages(START_SHAKE);
                   mHandler.sendMessageDelayed(msg,300);
                  
               }
               last_x = x;
               last_y = y;
               last_z = z;
               lastUpdate = curTime;
            }
        }
    }
    }
 
    @Override
    protected void onStop() {
       mSensorManager.unregisterListener(myThrowDice);
       super.onStop();
    }
 
    private Handler mHandler = new Handler() {
       @Override
       public void handleMessage(Message msg) {
           switch (msg.what) {
           case START_SHAKE:
              // Bundle b = msg.getData();
              // if (b != null){
              //Log.i("Throw",
              // "Throw atlastUpdate " + b.getLong("lastUpdate"));
              //Log.i("Throw", "Throw at curTime " +b.getLong("curTime"));
              //Log.i("Throw", "Throw at speed " +b.getFloat("speed"));
              // }
              Toast.makeText(getBaseContext(), "摇一摇", Toast.LENGTH_SHORT).show();
              if (mTimes > 100) {
                  mTimes = 0;
              }
              mTimes++;
              Log.i("Throw", "" + mTimes);
              break;
           default:
              break;
           }
           super.handleMessage(msg);
       }
    };


 

总结:

1、onCreate函数中listener注册后,在重载onStop函数中要记得注销,否则程序退出后仍会继续监听。

2、onAccuracyChanged(Sensor sensor, int accuracy)函数只要机身重力变化就会调用。

3、onSensorChanged(SensorEvent event)开始没有反应,加上3个TextView之后竟然就可以了,不知道什么原因。

4、最后一段代码只是为了方便测试

 

四、布局及各类资源

布局:

布局用了xml文件,

Manifest.xml文件中是程序的各个Activity的属性。

Main.xml是主Activity的各种布局属性。

String.xml中是程序中用到的字符串。通过增加不同语言的string.xml可以使程序达到国际化效果。

背景透明效果:  android:background="#00000000"

锁定屏幕方向(垂直):android:screenOrientation="portrait"

全屏显示:android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

 

资源:

图片资源存放在drawable开头的各个文件夹中,每个图片要提供三种大小的同名图片,以适应不同分辨率的机子(三个一样也不会报错)。

声音资源在raw文件夹。

 

五、menu

  

  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
       // TODO Auto-generatedmethod stub
       menu.add(1, 1, 1, R.string.touch_able);
       menu.add(1, 2, 2, R.string.about);
       menu.add(1, 3, 3, R.string.exit);
       return super.onCreateOptionsMenu(menu);
    }
   
    @Override
    public boolean onOptionsItemSelected(MenuItemitem){
    switch(item.getItemId()){
    case 1:
        diceButtonAvailable=!diceButtonAvailable;
        ImageButtonmyib=(ImageButton)findViewById(R.id.imageButton1);
        myib.setClickable(diceButtonAvailable);
        if(diceButtonAvailable)
            item.setTitle(R.string.touch_able);
        else
            item.setTitle(R.string.touch_unable);
        return true;
    case 2:
        //弹窗信息
        return true;
    case 3:
        finish();
        return true;
    default:
        return false;
    }
}

 

1、menu.add四个参数为:组号,排序号,ID(唯一),显示字符。

2、退出用finish()函数。

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值