1. 程式人生 > >Android學習筆記:練習中用到的一些技巧總結

Android學習筆記:練習中用到的一些技巧總結

1,登入的時候,如果輸入有誤,則輸入框左右震動,表示輸入有誤

        在res下準備一個anim資料夾,裡面包含兩個檔案,main_login_shake.xml 和 main_login_cycle_7.xml,

        其中,main_login_shake.xml如下:      

<?xml version="1.0" encoding="utf-8"?>

<translate 
		xmlns:android="http://schemas.android.com/apk/res/android" 
		android:fromXDelta="0" 
		android:toXDelta="10" 
		android:duration="1000" 
		android:interpolator="@anim/main_login_cycle_7" />
        上面檔案中引用了main_login_cycle_7.xml,程式碼如下:
<?xml version="1.0" encoding="utf-8"?>

<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />
        這兩段程式碼的意思就是在1秒鐘之類,x座標從0到10晃動7次

        看java程式碼:

shakeanim = AnimationUtils.loadAnimation(this,R.anim.main_login_shake);
btn_login.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					boolean ready = true;
					String username=et_username.getText().toString();
					String password=et_password.getText().toString();
					if (!username.matches("^\\w{1,}+$")) {
						ready = false;
						et_username.startAnimation(shakeanim);
					}
					if (!password.matches("^\\w{1,}+$")) {
						ready = false;
						et_password.startAnimation(shakeanim);
					}
					if(selectClinic==null){
						ready = false;
						et_clinic.startAnimation(shakeanim);
					}
					if (ready) {
						loginStart(username,password,Long.parseLong(selectClinic.get("id").toString()),Integer.parseInt(selectClinic.get("type_id").toString()));
					}
				}
			});

2,當一個Activity中很多地方需要使用到對話方塊,可以如下操作:

showDialog(R.id.wait_edit_arriveltime);
showDialog(R.id.wait_edit_yuyuedata);
showDialog(R.id.wait_edit_close);
。。。。。。
protected Dialog onCreateDialog(int id) {
		Dialog dialog = null;
		switch (id) {
		case R.id.wait_edit_yuyuedata:
			 DatePickerDialog.OnDateSetListener dateListener = new DatePickerDialog.OnDateSetListener() { 
                 @Override 
                 public void onDateSet(DatePicker datePicker,int year, int month, int dayOfMonth) { 
                	 wait_edit_yuyuedata.setText(dayOfMonth + "/"+(month+1)+"/"+year); 
                 } 
             }; 
             dialog = new DatePickerDialog(this, dateListener, Integer.parseInt(app.getAppointedDate().split("/")[2]), Integer.parseInt(app.getAppointedDate().split("/")[1]), Integer.parseInt(app.getAppointedDate().split("/")[0])); 
             break;
		case R.id.wait_edit_arriveltime:
			TimePickerDialog.OnTimeSetListener timeListener = new TimePickerDialog.OnTimeSetListener() {
				
				@Override
				public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
					wait_edit_arriveltime.setText(hourOfDay+":"+minute);
				}
			};
			dialog = new TimePickerDialog(this, timeListener, Integer.parseInt(app.getEstimateArriveTime().split(":")[0]), Integer.parseInt(app.getEstimateArriveTime().split(":")[1]), true);
			break;
		case R.id.wait_edit_close:
			AlertDialog.Builder builder = new AlertDialog.Builder(EditWaitActivity.this);
			builder.setTitle("您要確定放棄編輯嗎?");
			builder.setPositiveButton("確定",new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface arg0, int arg1) {
					EditWaitActivity.this.finish();
				}});
			builder.setNegativeButton("取消",new DialogInterface.OnClickListener() {
				
				public void onClick(DialogInterface dialog,int whichButton) {

				}
			});
			builder.show();
			break;
		default:
			break;
		}
		return dialog;
	}



3,標準的adapter的格式,以後就按照這樣的形式寫
public class MyAdapter extends BaseAdapter{
	
	Context context;
	PageRecord<Appointment> data;
	private ViewHolder tempHolder;
	private View tempView;
	public MyAdapter(Context context,PageRecord<Appointment> data){
		this.context = context;
		this.data = data;
	}
	
	public View getView(int position, View convertView, ViewGroup parent) {
		final ViewHolder holder;
		Appointment app = data.getResultSet().get(position);
		if(convertView==null){
			convertView=LayoutInflater.from(context).inflate(R.layout.item, null);
			holder=new ViewHolder(convertView);
			convertView.setTag(holder);
		}else{
			holder=(ViewHolder) convertView.getTag();
		}
		tempHolder = holder;
		tempView = convertView;
		holder.setData(app);
		return convertView;
	}

	public long getItemId(int position) {
		return position;
	}

	public Object getItem(int position) {
		return data.getResultSet().get(position);
	}

	public int getCount() {
		return data.getResultSet()==null?0:data.getResultSet().size();
	}
	
	public void setData(PageRecord<Appointment> data){
		this.data = data;
		this.notifyDataSetChanged();
		tempView.invalidate();
	}
	
	/**
	 * 重新繪製
	 * @param app
	 */
	public void redraw(Appointment app){
		tempHolder.timeView.setText(app.getAppointedDate()+" "+app.getEstimateArriveTime());
		tempHolder.nameView.setText(app.getPatient().getNameEN());
		tempHolder.doctorView.setText(app.getMo().getNameEN());
		tempView.invalidate();
	}
	
	private class ViewHolder{
		private TextView timeView;
		private TextView nameView;
		private TextView doctorView;
		public ViewHolder(View convertView){
			timeView = (TextView) convertView.findViewById(R.id.yuyuetime);
			nameView = (TextView) convertView.findViewById(R.id.yuyuename);
			doctorView = (TextView) convertView.findViewById(R.id.doctorname);
		}
		public void setData(Appointment app){
			timeView.setText(app.getAppointedDate()+" "+app.getEstimateArriveTime());
			nameView.setText(app.getPatient().getNameEN());
			doctorView.setText(app.getMo().getNameEN());
		}
	}
}

4,獲取螢幕解析度的兩種方法

// 方法1 Android獲得螢幕的寬和高     
       WindowManager windowManager = getWindowManager();    
       Display display = windowManager.getDefaultDisplay();    
       int screenWidth = display.getWidth();    
       int screenHeight  = display.getHeight();    
// 方法2    
       DisplayMetrics dm = new DisplayMetrics();  
       getWindowManager().getDefaultDisplay().getMetrics(dm);  
       float width=dm.widthPixels*dm.density;   
       float height=dm.heightPixels*dm.density;   

列印結果:width:320.0,height:480.0,screenWidth:320,screenHeight:480

dpi值的是螢幕上每英寸的畫素點。如果一個160dpi的螢幕,1dp=1px。假如我現在有一個480*800,160dp的屏,那麼他的實際面積要比480*800,240dp的屏面積大,但是清晰度卻不如後面這個屏。

如果有些實體手機在做測試的時候發現得到的解析度比實際的解析度小很多,那麼這裡得到的是dp單位的畫素值,可以通過dp的密度值來轉換,如下:

480*800的手機(WVGA)density=240。
轉換公式如下:
pixs =dips * (density/160)
dips=(pixs*160)/density
480*800單位是px。而320*533單位是dp

5,資源的一些應用

    *    不同的layout

      Android手機螢幕大小不一,有480x320,640x360,800x480.怎樣才能讓App自動適應不同的螢幕呢? 其實很簡單,只需要在res目錄下建立不同的layout資料夾,比如:layout-640x360,layout-800x480,所有的layout檔案在編譯之後都會寫入R.java裡,而系統會根據螢幕的大小自己選擇合適的layout進行使用。


    *    hdpi、mdpi、ldpi

      前的版本中,只有一個drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三個,這三個主要是為了支援多解析度。

    *    drawable- hdpi、drawable- mdpi、drawable-ldpi的區別:

drawable-hdpi裡面存放高解析度的圖片,如WVGA (480x800),FWVGA (480x854)
drawable-mdpi裡面存放中等解析度的圖片,如HVGA (320x480)
drawable-ldpi裡面存放低解析度的圖片,如QVGA (240x320)
系統會根據機器的解析度來分別到這幾個資料夾裡面去找對應的圖片。在開發程式時為了相容不同平臺不同螢幕,建議各自資料夾根據需求均存放不同版本圖片。

    *    螢幕方向
橫屏豎屏自動切換

      可以在res目錄下建立layout-port和layout-land兩個目錄,裡面分別放置豎屏和橫屏兩種佈局檔案,這樣在手機螢幕方向變化的時候系統會自動呼叫相應的佈局檔案,避免一種佈局檔案無法滿足兩種螢幕顯示的問題。

    *    禁用自動切換

只需要在AndroidManifest.xml檔案中加入android:screenOrientation屬性限制。

Android:screenOrientation="landscape"  //是限制此頁面橫屏顯示

Android:screenOrientation="portrait"      //是限制此頁面數豎屏顯示

    *    字型自適應大小
方法1:

首先根據不同解析度獲取不同字型大小。 
在RES裡建立
values-480x320/strings.xml 裡面設定<dimen name="Text_size">30px</dimen>
和 
values-800x400/strings.xml 裡面設定<dimen name="Text_size">40px</dimen>

分別代表480X320 和 800X400解析度情況下 字號為30px和40px;

在java檔案中這樣呼叫

int sizeOfText = (int) this.getResources().getDimension(R.dimen.Text_size);

方法2:

在檢視的 onsizechanged裡獲取檢視寬度,一般情況下預設寬度是320,所以計算一個縮放比率rate = (float) w/320   w是實際寬度
然後在設定字型尺寸時 paint.setTextSize((int)(8*rate));   8是在解析度寬為320 下需要設定的字型大小實際字型大小 = 預設字型大小 x  rate