本文實(shí)例講述了Android編程常用技巧。分享給大家供大家參考,具體如下:
1. 登錄的時(shí)候,如果輸入有誤,則輸入框左右震動(dòng),表示輸入有誤
在res下準(zhǔn)備一個(gè)anim文件夾,里面包含兩個(gè)文件,main_login_shake.xml 和 main_login_cycle_7.xml,
其中,main_login_shake.xml如下:
1
2
3
4
5
6
7
|
<? 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,代碼如下:
1
2
|
<? xml version = "1.0" encoding = "utf-8" ?> < cycleInterpolator xmlns:android = "http://schemas.android.com/apk/res/android" android:cycles = "7" /> |
這兩段代碼的意思就是在1秒鐘之類,x坐標(biāo)從0到10晃動(dòng)7次
看java代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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. 當(dāng)一個(gè)Activity中很多地方需要使用到對話框,可以如下操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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. 標(biāo)準(zhǔn)的adapter的格式,以后就按照這樣的形式寫
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
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
2
3
4
5
6
7
8
9
10
|
// 方法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; |
打印結(jié)果:width:320.0,height:480.0,screenWidth:320,screenHeight:480
dpi值的是屏幕上每英寸的像素點(diǎn)。如果一個(gè)160dpi的屏幕,1dp=1px。假如我現(xiàn)在有一個(gè)480*800,160dp的屏,那么他的實(shí)際面積要比480*800,240dp的屏面積大,但是清晰度卻不如后面這個(gè)屏。
如果有些實(shí)體手機(jī)在做測試的時(shí)候發(fā)現(xiàn)得到的分辨率比實(shí)際的分辨率小很多,那么這里得到的是dp單位的像素值,可以通過dp的密度值來轉(zhuǎn)換,如下:
480*800的手機(jī)(WVGA)density=240。
轉(zhuǎn)換公式如下:
1
2
|
pixs =dips * (density/ 160 ) dips=(pixs* 160 )/density |
480*800單位是px。而320*533單位是dp
5,資源的一些應(yīng)用
* 不同的layout
Android手機(jī)屏幕大小不一,有480x320,640x360,800x480.怎樣才能讓App自動(dòng)適應(yīng)不同的屏幕呢? 其實(shí)很簡單,只需要在res目錄下創(chuàng)建不同的layout文件夾,比如:layout-640x360,layout-800x480,所有的layout文件在編譯之后都會(huì)寫入R.java里,而系統(tǒng)會(huì)根據(jù)屏幕的大小自己選擇合適的layout進(jìn)行使用。
* hdpi、mdpi、ldpi
前的版本中,只有一個(gè)drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三個(gè),這三個(gè)主要是為了支持多分辨率。
* drawable- hdpi、drawable- mdpi、drawable-ldpi的區(qū)別:
drawable-hdpi里面存放高分辨率的圖片,如WVGA (480x800),FWVGA (480x854)
drawable-mdpi里面存放中等分辨率的圖片,如HVGA (320x480)
drawable-ldpi里面存放低分辨率的圖片,如QVGA (240x320)
系統(tǒng)會(huì)根據(jù)機(jī)器的分辨率來分別到這幾個(gè)文件夾里面去找對應(yīng)的圖片。在開發(fā)程序時(shí)為了兼容不同平臺(tái)不同屏幕,建議各自文件夾根據(jù)需求均存放不同版本圖片。
* 屏幕方向
橫屏豎屏自動(dòng)切換
可以在res目錄下建立layout-port和layout-land兩個(gè)目錄,里面分別放置豎屏和橫屏兩種布局文件,這樣在手機(jī)屏幕方向變化的時(shí)候系統(tǒng)會(huì)自動(dòng)調(diào)用相應(yīng)的布局文件,避免一種布局文件無法滿足兩種屏幕顯示的問題。
* 禁用自動(dòng)切換
只需要在AndroidManifest.xml文件中加入android:screenOrientation屬性限制。
Android:screenOrientation="landscape" //是限制此頁面橫屏顯示
Android:screenOrientation="portrait" //是限制此頁面數(shù)豎屏顯示
* 字體自適應(yīng)大小
方法1:
首先根據(jù)不同分辨率獲取不同字體大小。
在RES里創(chuàng)建
values-480x320/strings.xml 里面設(shè)置<dimen name="Text_size">30px</dimen>
和
values-800x400/strings.xml 里面設(shè)置<dimen name="Text_size">40px</dimen>
分別代表480X320 和 800X400分辨率情況下 字號為30px和40px;
在java文件中這樣調(diào)用
方法2:
在視圖的 onsizechanged里獲取視圖寬度,一般情況下默認(rèn)寬度是320,所以計(jì)算一個(gè)縮放比率rate = (float) w/320 w是實(shí)際寬度
然后在設(shè)置字體尺寸時(shí) paint.setTextSize((int)(8*rate)); 8是在分辨率寬為320 下需要設(shè)置的字體大小實(shí)際字體大小 = 默認(rèn)字體大小 x rate
希望本文所述對大家Android程序設(shè)計(jì)有所幫助。