2015年3月28日 星期六

如何使用ProgressDialog之二



原文出處:http://givemepass.blogspot.tw/2012/08/progressdialog.html

如何使用ProgressDialog當中, 我們假設一個程式在執行,

會跳出一個ProgressDialog來顯示程式正在執行,

讓使用者不會以為程式當機。




但是實際上, 我們並不知道程式何時才會執行完成,

假設我們在下載一個檔案, 結果網路斷掉, 那麼ProgressDialog還是一直顯示著,

使用者還是會不耐煩的,




因此, 我們需要一個方式, 來計算還剩下多少時間,

這時候, AsyncTask是一個很方便的工具,

他可以幫你去除一些煩人的執行緒問題。












在官方網站有給一個很詳細的範例, 並且使用真正的網路下載來判斷進度,

但是為了理解這個流程, 因此我用假的進度來模擬整個步驟。




首先建立一個專案, 剛開始只是一個很簡單的Activity,public class ProgressbarDemoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_progressbar_demo); } }





接下來就是建立我們的AsyncTask,

從官網的範例可以知道,

http://developer.android.com/reference/android/os/AsyncTask.html




在這之前, 我們可以看到網站上說明,

必須先繼承AsyncTask,private class MyTask extends AsyncTask<Void, Void, Void> { ... }





然後我們必須實作四個方法, 分別是onPreExecute() doInBackground(Params...) onProgressUpdate(Progress...) onPostExecute(Result)








而這四個方法傳入的參數, 必須和繼承AsyncTask後面的泛型型態是相同的,

先來解釋這四個方法的意義,

第一個方法onPreExecute()可以從名稱知道, 他是在進行一些初始化的工作。




第二個方法是doInBackground()會傳入一個參數, 這個參數的數量是不定的,

也就是說, 你可以傳入零到數個參數也不是問題, 從官網的例子來看,

當宣告這個類別的物件時候, 只要呼叫execute這個方法,

傳入你想下載的網址, 就可以開始使用它了。


new DownloadFilesTask().execute(url1, url2, url3);


官網的範例是傳入三個下載的位置。




第三個方法是onProgressUpdate(), 它一樣會傳入一些參數, 也是不定數量的,

而這個方法通常是在執行onInBackground的時候, 才會去呼叫它,

只要執行publishProgress()這個方法,

就會呼叫onProgressUpdate(), 利用這個方法, 就可以讓程式顯示目前進度為何。




最後一個方法是onPostExecute(), 這個用來接收結果,

通常你在onProgressUpdate()回傳的結果, 就會當參數傳到這個方法,

不過你要注意型態, 才不會沒有傳入。




現在來看一下範例怎麼寫的。public class TestAsyncTask extends AsyncTask<URL, Integer, String> { private Context mContext; private ProgressDialog mDialog; public TestAsyncTask(Context mContext) { this.mContext = mContext; } protected void onPreExecute() { mDialog = new ProgressDialog(mContext); mDialog.setMessage("Loading..."); mDialog.setCancelable(false); mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mDialog.show(); } protected String doInBackground(URL... urls) { // TODO Auto-generated method stub int progress =0; while(progress<=100){ try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } publishProgress(Integer.valueOf(progress)); progress++; } return "ok"; } @Override protected void onProgressUpdate(Integer... progress) { // TODO Auto-generated method stub mDialog.setProgress(progress[0]); } protected void onPostExecute(String result) { if(result.equals("ok")){ mDialog.dismiss(); } } }


我用顏色將傳入的參數, 與泛型的參數對應起來,

這樣就可以很清楚知道哪些參數是什麼功用,

雖然從型態就可以了解是如何對應的,

但是萬一我們的型態設定為相同的話, 有可能會造成錯亂,

所以還是了解一下位置比較妥當。


protected void onPreExecute() { mDialog = new ProgressDialog(mContext); mDialog.setMessage("Loading..."); mDialog.setCancelable(false); mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); mDialog.show(); }





一開始先加入一個ProgressbarDialog用來計算我們的進度,

紅色那行一定要加入, 這樣才可以看到進度。


protected String doInBackground(URL... urls) { // TODO Auto-generated method stub int progress =0; while(progress<=100){ try { Thread.sleep(50); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } publishProgress(Integer.valueOf(progress)); progress++; } return "ok"; }


為了模擬檔案傳輸速度, 所以故意設定0.05秒就睡一下,

這樣才不會一下子就跑完了,

這邊可以參考官網真正的下載檔案, 然後設定progressbar的進度。


@Override protected void onProgressUpdate(Integer... progress) { // TODO Auto-generated method stub mDialog.setProgress(progress[0]); }


呼叫publishProgress方法就會自動去呼叫onProgressUpdate方法,

然後利用ProgressbarDialog的方法去設定進度。


protected void onPostExecute(String result) { if(result.equals("ok")){ mDialog.dismiss(); } }


當onInBackground結束, 並且return結果的時候, 就會呼叫onPostExecute方法,

這時候我們將dialog消滅, 就可以回到原本的畫面了。





public class ProgressbarDemoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_progressbar_demo); new TestAsyncTask(this).execute(); } }


記得加上這一行, 才能呼叫AsyncTask類別。







2015年3月26日 星期四

String.Format() 方法及參數說明



原文:http://tc.wangchao.net.cn/it/detail_59002.html

JDK1.5中,String類新增了一個很有用的靜態方法String.format():

  format(Locale l, String format, Object... args) 使用指定的語言環境、格式字符串和參數返回一個格式化字符串。

  format(String format, Object... args) 使用指定的格式字符串和參數返回一個格式化字符串。

  舉幾個這個方法實用的例子(注釋是輸出結果):

  CODE:

  long now = System.currentTimeMillis();

  String s = String.format("%tR", now); // "15:12"

  CODE:

  // Current month/day/year

  Date d = new Date(now);

  s = String.format("%tD", d); // "07/13/04"

  CODE:

  s = String.format("%,d", Integer.MAX_VALUE); // "2,147,483,647"

  CODE:

  s = String.format("%05d", 123); // "00123"

  是不是很方便,讓人動心啊?哈哈,還有更多的效果!

  其實format函數有些類似c語言中printf函數,一些格式字符串與 C 類似,但已進行了某些定制,以適應 Java 語言,並且利用了其中一些特性。此方法提供了對布局對齊和排列的支持,以及對數值、字符串和日期/時間數據的常規格式和特定于語言環境的輸出的支持。支持諸如 byte、BigDecimal 和 Calendar 等常見 Java 類型。

  産生格式化輸出的每個方法都需要格式字符串 和參數列表。格式字符串是一個 String,它可以包含固定文本以及一個或多個嵌入的格式說明符。請考慮以下示例:

  Calendar c = ...;

  String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);

  格式字符串是 format 方法的第一個參數。它包含三個格式說明符 "%1$tm"、"%1$te" 和 "%1$tY",它們指出應該如何處理參數以及在文本的什麽地方插入它們。格式字符串的其余部分是包括 "Dukes Birthday: " 和其他任何空格或標點符號的固定文本。 參數列表由傳遞給位于格式字符串之後的方法的所有參數組成。在上述示例中,參數列表的大小爲 1,由新對象 Calendar 組成。

  1.常規類型、字符類型和數值類型的格式說明符的語法如下:%[argument_index$][flags][width][.precision]conversion

  可選的 argument_index 是一個十進制整數,用于表明參數在參數列表中的位置。第一個參數由 "1quot; 引用,第二個參數由 "2quot; 引用,依此類推。

  可選的 flags 是修改輸出格式的字符集。有效標志的集合取決于轉換類型。

  可選 width 是一個非負十進制整數,表明要向輸出中寫入的最少字符數。

  可選 precision 是一個非負十進制整數,通常用來限制字符數。特定行爲取決于轉換類型。

  所需的 conversion 是一個表明應該如何格式化參數的字符。給定參數的有效轉換集合取決于參數的數據類型。

  2.用來表示日期和時間類型的格式說明符的語法如下:

  %[argument_index$][flags][width]conversion

  可選的 argument_index、flags 和 width 的定義同上。

  所需的 conversion 是一個由兩字符組成的序列。第一個字符是 't' 或 'T'。第二個字符表明所使用的格式。這些字符類似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的字符。

  3.與參數不對應的格式說明符的語法如下:

  %[flags][width]conversion

  可選 flags 和 width 的定義同上。

  所需的 conversion 是一個表明要在輸出中所插內容的字符。

  轉換

  轉換可分爲以下幾類:

  1. 常規 - 可應用于任何參數類型

  2. 字符 - 可應用于表示 Unicode 字符的基本類型:char、Character、byte、Byte、short 和 Short。當 Character.isValidCodePoint(int) 返回 true 時,可將此轉換應用于 int 和 Integer 類型

  3. 數值

   1. 整數 - 可應用于 Java 的整數類型:byte、Byte、short、Short、int、Integer、long、Long 和 BigInteger

   2. 浮點 - 可用于 Java 的浮點類型:float、Float、double、Double 和 BigDecimal

  4. 日期/時間 - 可應用于 Java 的、能夠對日期或時間進行編碼的類型:long、Long、Calendar 和 Date。

  5. 百分比 - 産生字面值 '%' ('\u0025')

  6. 行分隔符 - 産生特定于平台的行分隔符

  下表總結了受支持的轉換。由大寫字符(如 'B'、'H'、'S'、'C'、'X'、'E'、'G'、'A' 和 'T')表示的轉換與由相應的小寫字符的轉換等同,根據流行的 Locale 規則將結果轉換爲大寫形式除外。後者等同于 String.toUpperCase() 的以下調用.

  轉換 參數類別 說明

  'b', 'B' 常規 如果參數 arg 爲 null,則結果爲 "false"。如果 arg 是一個 boolean 值或 Boolean,則結果爲 String.valueOf() 返回的字符串。否則結果爲 "true"。

  'h', 'H' 常規 如果參數 arg 爲 null,則結果爲 "null"。否則,結果爲調用 Integer.toHexString(arg.hashCode()) 得到的結果。

  's', 'S' 常規 如果參數 arg 爲 null,則結果爲 "null"。如果 arg 實現 Formattable,則調用 arg.formatTo。否則,結果爲調用 arg.toString() 得到的結果。

  'c', 'C' 字符 結果是一個 Unicode 字符

  'd' 整數 結果被格式化爲十進制整數

  'o' 整數 結果被格式化爲八進制整數

  'x', 'X' 整數 結果被格式化爲十六進制整數

  'e', 'E' 浮點 結果被格式化爲用計算機科學記數法表示的十進制數

  'f' 浮點 結果被格式化爲十進制數

  'g', 'G' 浮點 根據精度和舍入運算後的值,使用計算機科學記數形式或十進制格式對結果進行格式化。

  'a', 'A' 浮點 結果被格式化爲帶有效位數和指數的十六進制浮點數

  't', 'T' 日期/時間 日期和時間轉換字符的前綴。請參閱日期/時間轉換。

  '%' 百分比 結果爲字面值 '%' ('\u0025')

  'n' 行分隔符 結果爲特定于平台的行分隔符

  任何未明確定義爲轉換的字符都是非法字符,並且都被保留,以供將來擴展使用。

  日期/時間轉換

  以下日期和時間轉換的後綴字符是爲 't' 和 'T' 轉換定義的。這些類型相似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定義的類型。提供其他轉換類型是爲了訪問特定于 Java 的功能(如將 'L' 用作秒中的毫秒)。

  以下轉換字符用來格式化時間:

  'H' 24 小時制的小時,被格式化爲必要時帶前導零的兩位數,即 00 - 23。

  'I' 12 小時制的小時,被格式化爲必要時帶前導零的兩位數,即 01 - 12。

  'k' 24 小時制的小時,即 0 - 23。

  'l' 12 小時制的小時,即 1 - 12。

  'M' 小時中的分鍾,被格式化爲必要時帶前導零的兩位數,即 00 - 59。

  'S' 分鍾中的秒,被格式化爲必要時帶前導零的兩位數,即 00 - 60 ("60" 是支持閏秒所需的一個特殊值)。

  'L' 秒中的毫秒,被格式化爲必要時帶前導零的三位數,即 000 - 999。

  'N' 秒中的毫微秒,被格式化爲必要時帶前導零的九位數,即 000000000 - 999999999。

  'p' 特定于語言環境的 上午或下午 標記以小寫形式表示,例如 "am" 或 "pm"。使用轉換前綴 'T' 可以強行將此輸出轉換爲大寫形式。

  'z' 相對于 GMT 的 RFC 822 格式的數字時區偏移量,例如 -0800。

  'Z' 表示時區縮寫形式的字符串。Formatter 的語言環境將取代參數的語言環境(如果有)。

  's' 自協調世界時 (UTC) 1970 年 1 月 1 日 00:00:00 至現在所經過的秒數,即 Long.MIN_VALUE/1000 與 Long.MAX_VALUE/1000 之間的差值。

  'Q' 自協調世界時 (UTC) 1970 年 1 月 1 日 00:00:00 至現在所經過的毫秒數,即 Long.MIN_VALUE 與 Long.MAX_VALUE 之間的差值。

  以下轉換字符用來格式化日期:

  'B' 特定于語言環境的月份全稱,例如 "January" 和 "February"。

  'b' 特定于語言環境的月份簡稱,例如 "Jan" 和 "Feb"。

  'h' 與 'b' 相同。

  'A' 特定于語言環境的星期幾全稱,例如 "Sunday" 和 "Monday"

  'a' 特定于語言環境的星期幾簡稱,例如 "Sun" 和 "Mon"

  'C' 除以 100 的四位數表示的年份,被格式化爲必要時帶前導零的兩位數,即 00 - 99

  'Y' 年份,被格式化爲必要時帶前導零的四位數(至少),例如,0092 等于格裏高利曆的 92 CE。

  'y' 年份的最後兩位數,被格式化爲必要時帶前導零的兩位數,即 00 - 99。

  'j' 一年中的天數,被格式化爲必要時帶前導零的三位數,例如,對于格裏高利曆是 001 - 366。

  'm' 月份,被格式化爲必要時帶前導零的兩位數,即 01 - 13。

  'd' 一個月中的天數,被格式化爲必要時帶前導零兩位數,即 01 - 31

  'e' 一個月中的天數,被格式化爲兩位數,即 1 - 31。

  以下轉換字符用于格式化常見的日期/時間組合。

  'R' 24 小時制的時間,被格式化爲 "%tH:%tM"

  'T' 24 小時制的時間,被格式化爲 "%tH:%tM:%tS"。

  'r' 12 小時制的時間,被格式化爲 "%tI:%tM:%tS %Tp"。上午或下午標記 ('%Tp') 的位置可能與語言環境有關。

  'D' 日期,被格式化爲 "%tm/%td/%ty"。

  'F' ISO 8601 格式的完整日期,被格式化爲 "%tY-%tm-%td"。

  'c' 日期和時間,被格式化爲 "%ta %tb %td %tT %tZ %tY",例如 "Sun Jul 20 16:17:00 EDT 1969"。

  任何未明確定義爲轉換的字符都是非法字符,並且都被保留,以供將來擴展使用。

  標志

  下表總結了受支持的標志。y 表示該標志受指示參數類型支持。

  標志 常規 字符 整數 浮點 日期/時間 說明

  '-' y y y y y 結果將是左對齊的。

  '#' y1 - y3 y - 結果應該使用依賴于轉換類型的替換形式

  '+' - - y4 y - 結果總是包括一個符號

  ' ' - - y4 y - 對于正值,結果中將包括一個前導空格

  '0' - - y y - 結果將用零來填充

  ',' - - y2 y5 - 結果將包括特定于語言環境的組分隔符

  '(' - - y4 y5 - 結果將是用圓括號括起來的負數

  1 取決于 Formattable 的定義。

  2 只適用于 'd' 轉換。

  3 只適用于 'o'、'x' 和 'X' 轉換。

  4 對 BigInteger 應用 'd'、'o'、'x' 和 'X' 轉換時,或者對 byte 及 Byte、short 及 Short、int 及 Integer、long 及 Long 分別應用 'd' 轉換時適用。

  5 只適用于 'e'、'E'、'f'、'g' 和 'G' 轉換。

  任何未顯式定義爲標志的字符都是非法字符,並且都被保留,以供擴展使用。

  寬度 寬度是將向輸出中寫入的最少字符數。對于行分隔符轉換,不適用寬度,如果提供寬度,則會抛出異常。

  精度 對于常規參數類型,精度是將向輸出中寫入的最多字符數。

  對于浮點轉換 'e'、'E' 和 'f',精度是小數點分隔符後的位數。如果轉換是 'g' 或 'G',那麽精度是舍入計算後所得數值的所有位數。如果轉換是 'a' 或 'A',則不必指定精度。

  對于字符、整數和日期/時間參數類型轉換,以及百分比和行分隔符轉換,精度是不適用的;如果提供精度,則會抛出異常。

  參數索引 參數索引是一個十進制整數,用于表明參數在參數列表中的位置。第一個參數由 "1quot; 引用,第二個參數由 "2quot; 引用,依此類推。

  根據位置引用參數的另一種方法是使用 '<' ('\u003c') 標志,這將會重用以前格式說明符的參數。例如,以下兩條語句産生的字符相同:

  Calendar c = ...;

  String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);

  String s2 = String.format("Duke's Birthday: %1$tm %<$te,%<$tY", c);(王朝網路 wangchao.net.cn)

ListView中getChildAt(index)的使用注意事项



原文:http://ahua186186.iteye.com/blog/1830180

1.原理

在很多時候ListView列表數據不需要全部刷新,只需刷新有數據變化的那一條,這時可以用getChildAt(index)獲取某個指定position的view,並對該view進行刷新。




注意:在ListView中,使用getChildAt(index)的取值,只能是當前可見區域(列表可滾動)的子項!




即取值範圍在>= ListView.getFirstVisiblePosition() && <= ListView.getLastVisiblePosition();

1)所以如果想獲取前部的將會出現返回Null值空指針問題;

2)getChildCount跟getCount獲取的值將會不一樣(數量多時);

3 )如果使用了getChildAt(index).findViewById(...)設置值的話,滾動列表時值就會改變了。

需要使用getFirstVisiblePosition()獲得第一個可見的位置,再用當前的position-它,再用getChildAt取值!即getChildAt(position - ListView。getFirstVisiblePosition()).findViewById(...)去設置值

2.如果想更新某一行數據,需要配合ListView的滾動狀態使用,一般不滾動時才加載更新數據




//全局變量,用來記錄ScrollView的滾動狀態,1表示開始滾動,2表示正在滾動,0表示停止滾動

偽代碼

ListView設置

public int scrollStates;

class OnScrollListenerImpl implements OnScrollListener{

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

scrollStates = scrollState;

}




@Override

public void onScroll(AbsListView view, int firstVisibleItem,

int visibleItemCount, int totalItemCount) {

int lastInScreen = firstVisibleItem + visibleItemCount;

}

listView.setOnScrollListener(new OnScrollListenerImpl());







Activity中

if(scrollStates==OnScrollListener. SCROLL_STATE_IDLE){




更新視圖數據

}

2015年3月25日 星期三

Android中的OnTouch事件和MotionEvent



原文:http://yizhi401.blog.51cto.com/6500239/1364958


要理解OnTouch機制,首先得明白有哪些OnTouch事件,常用的有這麼四種:






ACTION_DOWN


這個是OnTouchEvent事件的開始,任何事件都必須手指按下去才行。這個事件是一個從觸摸屏無觸摸狀態到有觸摸狀態的轉換。






ACTION_MOVE


緊接著的Move事件,可能有人會以為手指移動就會調用這個MOVE,但是經我測試並非如此,這個事件,只要手指在屏幕上,即使不動也會調用。






ACTION_UP


觸摸事件的結束,正常情況下,手指離開屏幕;觸摸屏從有觸摸狀態到無觸摸狀態的轉換。






ACTION_CANCEL


這個不是獨特的觸摸事件,而是由系統來判定的,一般認為你的手指從屏幕上你要點擊的區域移出來,就cancel掉了。很簡單的例子,你點擊一個按鈕,點擊的時候,按鈕變顏色,只要你的手指不拿開,按鈕不會變回原來的顏色。這時候你手指拿開了,按鈕顏色變回去,你就觸發了ACTION_UP的事件;或者你的手指移出按鈕區域了,按鈕顏色也變回去,這時候你觸發了ACTION_CANCEL事件,你點擊按鈕的方法也不會被觸發。






我們知道,android中的View是按照一個View Hierarchy來組織的。而且,在設定onTouch事件的時候,觸摸的順序也是走的這個View Hierarchy從上往下傳遞,叫做dispatch。






ViewGroup裡面有一個方法決定了這個ViewGroup的dispatch方式:






OnInterceptTouchEvent(MotionEvent ev)






這個方法由系統自己調用,但是在寫自己的ViewGroup的時候,可以復寫,工作過程和返回值說明如下:






Implement this method to intercept all touch screen motion events. This allows you to watch events as they are dispatched to your children, and take ownership of the current gesture at any point.


Using this function takes some care, as it has a fairly complicated interaction withView.onTouchEvent(MotionEvent) , and using it requires implementing that method as well as this one in the correct way. Events will be received in the following order:


You will receive the down event here.


The down event will be handled either by a child of this view group, or given to your own onTouchEvent() method to handle; this means you should implement onTouchEvent() to return true, so you will continue to see the rest of the gesture (instead of looking for a parent view to handle it). Also, by returning true from onTouchEvent(), you will not receive any following events in onInterceptTouchEvent() and all touch processing must happen in onTouchEvent() like normal.


For as long as you return false from this function, each following event (up to and including the final up) will be delivered first here and then to the target's onTouchEvent().


If you return true from here, you will not receive any following events: the target view will receive the same event but with the action ACTION_CANCEL , and all further events will be delivered to your onTouchEvent() method and no longer appear here.





Parameters



ev

The motion event being dispatched down the hierarchy.


Returns


Return true to steal motion events from the children and have them dispatched to this ViewGroup through onTouchEvent(). The current target will receive an ACTION_CANCEL event, and no further messages will be delivered here.










簡單來說,任何觸摸事件最初都是從這裡開始,也就是MotionEvent.ACTION_DOWN。如果這個方法返回true了,那麼這個onTouchEvent就不會被分配到子View了,而是在這個ViewGroup的OnTouchEvent事件裡面處理,而子View則會收到一個ACTION_CANCEL,從而結束其onTouchEvent方法的調用。


所以可以簡單記住,如果這個方法返回true,那麼就是說不要繼續dispatch事件了,所有後續的OnTouchEvent都留在這個ViewGroup裡面處理,子View獲得一個ACTION_CANCEL事件後就結束了。


如果這個方法返回false,那麼就是說ViewGroup不截斷onTouch事件,分發到相應的子View裡面處理。










子View處理onTouch事件的時候,需要有一個boolean型的返回值;這個返回值的實際意義其實是,該觸摸事件是否在這個onTouch方法裡面被消耗掉了。如果返回true,那麼就是被消耗掉了,該touch事件不會被繼續處理。如果返回false,就是說沒消耗掉,touch事件繼續被處理。






被處理?被誰處理?被這個子View的parent處理。就是說,Parent View不是把OnTouch事件分發到子View就沒事兒了,還要看看子View有沒有對這個事件處理,如果子View沒處理,他還得自己處理。所以綜上而言,一個MotionEvent首先是從ParentView到子View,然後還有可能再從子View返回到ParentView那邊去處理,是一個來回的過程。


是不是要從ParentView分發到子View,就看ParentView中OnInterceptTouchEvent事件的返回值;是不是要從子View返回到ParentView,就看子View的OnTouch事件返回值。






注意:一定不要把子View的onTouch事件返回值理解成是否要處理onTouch的後續事件。每一個MotionEvent都是獨立處理的,不會影響到其後續事件。






舉例子來說:ListView裡面有很多Item


這時候,如果我們點擊一個Item,那麼這個點擊事件首先被ListView接收,onInterceptTouchEvent返回false,分發到子View.然後子View來處理這個Touch事件。


這個時候,如果你的手指上下移動了(而不是左右),那麼這個手勢的含義就不是點擊而是你要滑動ListView了,所以這個時候,ListView的onInterceptTouchEvent就會返回true,你點擊的那個Item就收到了一個ACTION_CANCEL事件,以後你手指無論怎麼移動,都和Item沒關係,放到了ListView的OnTouch事件裡面處理了。所以這個時候你在子View裡面就不會監聽到ACTION_UP事件,要想找到這個事件,你得到ListView的OnTouch事件裡面去找了。

2015年3月24日 星期二

滑輪控件的研究五、ViewConfiguration的簡單介紹

  1. 原文:http://blog.csdn.net/lonelyroamer/article/details/7568129
  2. /** 
  3.  * 包含了方法和標準的常量用來設置UI的超時、大小和距離 
  4.  */  
  5. public  class  ViewConfiguration {  
  6.     // 設定水平滾動條的寬度和垂直滾動條的高度,單位是像素px  
  7.     private  static  final  int  SCROLL_BAR_SIZE =  10 ;  
  8.   
  9.     //定義滾動條逐漸消失的時間,單位是毫秒  
  10.     private  static  final  int  SCROLL_BAR_FADE_DURATION =  250 ;  
  11.   
  12.     // 默認的滾動條多少秒之後消失,單位是毫秒  
  13.     private  static  final  int  SCROLL_BAR_DEFAULT_DELAY =  300 ;  
  14.   
  15.     // 定義邊緣地方褪色的長度  
  16.     private  static  final  int  FADING_EDGE_LENGTH =  12 ;  
  17.   
  18.     //定義子控件按下狀態的持續事件  
  19.     private  static  final  int  PRESSED_STATE_DURATION =  125 ;  
  20.       
  21.     //定義一個按下狀態轉變成長按狀態的轉變時間  
  22.     private  static  final  int  LONG_PRESS_TIMEOUT =  500 ;  
  23.       
  24.     //定義用戶在按住適當按鈕,彈出全局的對話框的持續時間  
  25.     private  static  final  int  GLOBAL_ACTIONS_KEY_TIMEOUT =  500 ;  
  26.       
  27.     //定義一個touch事件中是點擊事件還是一個滑動事件所需的時間,如果用戶在這個時間之內滑動,那麼就認為是一個點擊事件  
  28.     private  static  final  int  TAP_TIMEOUT =  115 ;  
  29.       
  30.     /** 
  31.      * Defines the duration in milliseconds we will wait to see if a touch event  
  32.      * is a jump tap. If the user does not complete the jump tap within this interval, it is 
  33.      * considered to be a tap.  
  34.      */  
  35.     //定義一個touch事件時候是一個點擊事件。如果用戶在這個時間內沒有完成這個點擊,那麼就認為是一個點擊事件  
  36.     private  static  final  int  JUMP_TAP_TIMEOUT =  500 ;  
  37.   
  38.     //定義雙擊事件的間隔時間  
  39.     private  static  final  int  DOUBLE_TAP_TIMEOUT =  300 ;  
  40.       
  41.     //定義一個縮放控制反饋到用戶界面的時間  
  42.     private  static  final  int  ZOOM_CONTROLS_TIMEOUT =  3000 ;  
  43.   
  44.     /** 
  45.      * Inset in pixels to look for touchable content when the user touches the edge of the screen 
  46.      */  
  47.     private  static  final  int  EDGE_SLOP =  12 ;  
  48.       
  49.     /** 
  50.      * Distance a touch can wander before we think the user is scrolling in pixels 
  51.      */  
  52.     private  static  final  int  TOUCH_SLOP =  16 ;  
  53.       
  54.     /** 
  55.      * Distance a touch can wander before we think the user is attempting a paged scroll 
  56.      * (in dips) 
  57.      */  
  58.     private  static  final  int  PAGING_TOUCH_SLOP = TOUCH_SLOP *  ;  
  59.       
  60.     /** 
  61.      * Distance between the first touch and second touch to still be considered a double tap 
  62.      */  
  63.     private  static  final  int  DOUBLE_TAP_SLOP =  100 ;  
  64.       
  65.     /** 
  66.      * Distance a touch needs to be outside of a window's bounds for it to 
  67.      * count as outside for purposes of dismissing the window. 
  68.      */  
  69.     private  static  final  int  WINDOW_TOUCH_SLOP =  16 ;  
  70.   
  71.    //用來初始化fling的最小速度,單位是每秒多少像素  
  72.     private  static  final  int  MINIMUM_FLING_VELOCITY =  50 ;  
  73.       
  74.     //用來初始化fling的最大速度,單位是每秒多少像素  
  75.     private  static  final  int  MAXIMUM_FLING_VELOCITY =  4000 ;  
  76.   
  77.     //視圖繪圖緩存的最大尺寸,以字節表示。在ARGB888格式下,這個尺寸應至少等於屏幕的大小  
  78.     @Deprecated  
  79.     private  static  final  int  MAXIMUM_DRAWING_CACHE_SIZE =  320  *  480  *  ;  // HVGA screen, ARGB8888  
  80.   
  81.     //flings和scrolls摩擦力度大小的係數  
  82.     private  static  float  SCROLL_FRICTION =  .015f;  
  83.   
  84.     /** 
  85.      * Max distance to over scroll for edge effects 
  86.      */  
  87.     private  static  final  int  OVERSCROLL_DISTANCE =  ;  
  88.   
  89.     /** 
  90.      * Max distance to over fling for edge effects 
  91.      */  
  92.     private  static  final  int  OVERFLING_DISTANCE =  ;  
  93.   
  94. }