canvas.drawLine (shang1_X+shangBitmap1.getWidth()/2-7,shang1_Y, shang1_X+shangBitmap1.getWidth()/2-7,shang1_Y+shangBitmap1.getHeight()-2, paint);
canvas.drawLine (shang1_X+shangBitmap1.getWidth()/2+7,shang1_Y, shang1_X+shangBitmap1.getWidth()/2+7,shang1_Y+shangBitmap1.getHeight()-2, paint);
//繪制左面方框中的刻度
canvas.drawLine(zuo1_X,zuo1_Y+zuoBitmap1.getHeight()/2-7,zuo1_X+zuoBitmap1.getWidth()-2,zuo1_Y+zuoBitmap1.getHeight()/2-7, paint);canvas.drawLine(zuo1_X,zuo1_Y+zuoBitmap1.getHeight()/2+7,zuo1_X+zuoBitmap1.getWidth()-2,zuo1_Y+zuoBitmap1.getHeight()/2+7, paint);
//繪制下面方框中的刻度
canvas.drawLine(xia1_X+xiaBitmap1.getWidth()/2-10,xia1_Y+xiaBitmap1.getHeight()/2-20,xia1_X+xiaBitmap1.getWidth()/2+20,xia1_Y+xiaBitmap1.getHeight()/2+10, paint);
canvas.drawLine(xia1_X+xiaBitmap1.getWidth()/2-20,xia1_Y+xiaBitmap1.getHeight()/2-10,xia1_X+xiaBitmap1.getWidth()/2+10,xia1_Y+xiaBitmap1.getHeight()/2+20, paint);
//中間圓圈中的刻度(小圓)
RectF oval = new RectF(zhong1_X+zhongBitmap1.getWidth()/2-10,zhong1_Y+zhongBitmap1.getHeight()/2-10,zhong1_X+zhongBitmap1.getWidth()/2+10,zhong1_Y+zhongBitmap1.getHeight()/2+10);
canvas.drawOval(oval, paint);//繪制基準線(圓)
}
在該方法中, 根據相應圖片的X、Y 坐標將圖片繪制到屏幕中, 在圖片的繪制過程中, 同樣動態根據相應圖片的寬和高計算需要繪制到的位置坐標, 以提高程序的可維護性與靈活性。
6 相關XML 文件的編寫
完成了用于顯示水平儀界面的自定義View 的Java 代碼開發之后, 就應該對布局XML 資源文件進行編寫, 以將之前開發的自定義View 添加到用戶界面中。打開項目中res/layout 目錄下的main.xml, 在其中編寫如下的xml 代碼:
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:id="@+id/mainView"
android:layout_width="fill_parent"
android:layout_height = "fill_parent"/>< ! -- 自定義
View-->
編寫完布局文件main.xml 后, 還需要開發字符串資源文件strings.xml.打開res/values 下的strings.xml 文件, 編寫如下的代碼:
水平儀
在該文件中只是對字符串app_name 進行了定義, 在開發Android 應用程序時, 將字符串資源統一定義到一個xml 文件中是一個很好的編程習慣。
編寫完上述的xml 資源文件后, 為了調試還需要為此應用程序添加網絡權限, 打開項目根目錄下的AndroidManifest.xml文件, 在"" 標簽之前加入下列代碼:
上述代碼的功能為此應用程序添加了訪問網絡的權限。
7 Activity 類的開發
完成了自定義View 以及XML 文件的開發后, 就可以對用戶界面對應的Activity 類進行開發, 首先開發該類的代碼框架,其代碼如下:
package wyf.ytl; //聲明所在包
import android.app.Activity; //引入相關類
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class SPYActivity extends Activity { //繼承Activity MainView mv; //主View
int k = 45; //靈敏度
//SensorManager mySensorManager;
//真機
SensorManagerSimulator mySensorManager; //測試時@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.main);//設置當前用戶界面
mv = (MainView) findViewById(R.id.mainView);
mySensorManager =SensorManagerSimulator.getSystemService(this,SENSOR_SERVICE); //測試時
mySensorManager.connectSimulator();//測試時
//mySensorManager = (SensorManager)
// getSystemService(SENSOR_SERVICE);//真機
}
private final SensorListener mSensorLisener =new SensorListener(){ //傳感器監聽
//器類
…//該處省略了部分代碼,將在后面進行介紹
};
@Override
protected void onResume(){ //添加監聽
mySensorManager.registerListener(mSensorLisener,SensorManager.SENSOR_ORIENTATION);
super.onResume();
}
@Override
protected void onPause() { //取消監聽
mySensorManager.unregisterListener (mSensorLisener);
super.onPause();
}
}
上述代碼中除了重寫了onCreate 方法外, 還重寫了onRe-sume 以及onPause 方法為mySensorManager 添加或刪除監聽,并且定義了傳感器監聽器類mSensorLisener.
在完成了Activity 類代碼框架的開發后就可以對其中傳感器的監聽類進行開發, 首先給出監聽器類的代碼框架:
private final SensorListener mSensorLisener =
new SensorListener(){//傳感器監聽器類
public void onSensorChanged(int sensor, float[] values){…//該處省略了部分代碼,將在后面進行介紹
}
@Override
public void onAccuracyChanged(int sensor, int accuracy){}
public boolean isContain(int x, int y){//判斷點是否在圓內
int tempx =(int) (x + mv.zhongBitmap2.getWidth()/2.0);
int tempy =(int) (y + mv.zhongBitmap2.getWidth()/2.0);
int ox = (int) (mv.zhong1_X+ mv.zhongBitmap1.getWidth()/2.0);
int oy = (int) (mv.zhong1_X+ mv.zhongBitmap1.getWidth()/2.0);
if(Math.sqrt((tempx-ox)*(tempx-ox)+(tempy-oy)*(tempy-oy))>(mv.zhongBitmap1.getWidth()/2.0-mv.zhongBitmap2.getWidth()/2.0)){//不在圓內return false;
}else{ //在圓內時
return true;
}
}
};
在傳感器監聽類中, onSensorChanged 方法用于監聽傳感器采樣值的變化, 例如手機姿態的改變等。上述代碼中的is-Contain 方法用于判斷界面中間的氣泡是否出界, 若出界則返回false.
完成了代碼框架的開發后, 便可以對傳感器的監聽方法onSensorChanged 進行開發了, 其詳細代碼如下:
public void onSensorChanged(int sensor, float[] values){
if(sensor == SensorManager.SENSOR_ORIENTATION){
double pitch = values[SensorManager.DATA_Y];
double roll = values[SensorManager.DATA_Z];
int x=0; int y=0;//臨時變量,算中間水泡坐標時用
int tempX=0; int tempY=0;//下面氣泡的臨時變量
//開始調整x 的值
if(Math.abs(roll)<=k){
mv.shang2_X = mv.shang1_X //上面的
+ (int)(((mv.shangBitmap1.getWidth()
-mv.shangBitmap2.getWidth())/2.0)
-(((mv.shangBitmap1.getWidth()
-mv.shangBitmap2.getWidth())/2.0)*roll)/k);
x = mv.zhong1_X //中間的
+ (int)(((mv.zhongBitmap1.getWidth()
-mv.zhongBitmap2.getWidth())/2.0)
-(((mv.zhongBitmap1.getWidth()
-mv.zhongBitmap2.getWidth())/2.0)*roll)/k);
}else if(roll>k){
mv.shang2_X=mv.shang1_X; x = mv.zhong1_X;
}else{
mv.shang2_X=mv.shang1_X+
mv.shangBitmap1.getWidth()
- mv.shangBitmap2.getWidth();
x = mv.zhong1_X+ mv.zhongBitmap1.getWidth()
- mv.zhongBitmap2.getWidth();
}
評論
查看更多