一、主窗口:
系统默认情况下,主窗口为非 全屏,有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次,全部执行完后图片变化
三、摇动功能
代码:
l 变量声明:
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;
l onCreate函数中的代码:
myThrowDice=new throwdice();
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mSensorManager.registerListener(myThrowDice ,mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_GAME);
l 功能实现:
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()函数。