日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Android觸屏textview及l(fā)istview對(duì)比驗(yàn)證

觸摸屏做出動(dòng)作已經(jīng)成為主流手機(jī)的操作規(guī)范,但是你想過怎么開發(fā)觸摸屏手機(jī)的手勢(shì)操作嗎?本文將向各位介紹Android觸摸屏手機(jī)開發(fā)的textview及l(fā)istview對(duì)比驗(yàn)證。

創(chuàng)新互聯(lián)建站是一家專業(yè)提供無極企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站制作、成都網(wǎng)站建設(shè)、HTML5建站、小程序制作等業(yè)務(wù)。10年已為無極眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。

View可以通過onTouchEvent收到觸摸屏幕事件

我們可以通過View.setOnTouchListener()設(shè)置事件監(jiān)聽器

或者override onTouchEvent()來攔截這些事件

在攔截函數(shù)中判斷觸摸點(diǎn)的軌跡及運(yùn)動(dòng)速度就可以判斷出是什么手勢(shì)。

Android系統(tǒng)提供了GestureDetector來方便手勢(shì)的判斷,即:在攔截函數(shù)中每次touchevent都把事件作為參數(shù)調(diào)用GestureDetector.onTouchEvent(),當(dāng)有手勢(shì)被識(shí)別出后,就會(huì)通知調(diào)用者。

為了能通知到調(diào)用者,GestureDetector在構(gòu)造時(shí)要求傳入一個(gè)實(shí)現(xiàn)了OnGestureListener接口的對(duì)象,通過此對(duì)象就可以接收到各種手勢(shì)通知了。

首先,用textview來實(shí)驗(yàn):

用一個(gè)ViewFlipper放置兩個(gè)Textview,當(dāng)手指在屏幕上左右移動(dòng)時(shí)進(jìn)行進(jìn)行切換。

由于textview本身不會(huì)處理touchevent,而是會(huì)將其繼續(xù)上傳,所以textview布局時(shí)layout_width及l(fā)ayout_height沒有影響。

如果touch事件發(fā)生在textview上會(huì)繼續(xù)上傳到viewflipper;如果發(fā)生在viewflipper上那么就直接處理。

所以我們應(yīng)該攔截發(fā)生在ViewFlipper上的touchEvent,并進(jìn)行處理。

代碼如下,在onCreate中完成界面布局及事件攔截函數(shù)設(shè)置:

Java代碼

 
 
 
  1. //創(chuàng)建一個(gè)ViewFlipper    
  2.         mVf = new ViewFlipper(this);    
  3.         //ViewFlipper打開長(zhǎng)點(diǎn)擊支持。如果不打開,無法收到長(zhǎng)時(shí)間點(diǎn)擊,那么手勢(shì)判斷就無從進(jìn)行。    
  4.         mVf.setLongClickable(true);    
  5.         //攔截ViewFlipper的touch事件,并使用GestureDetector.onTouchEvent來處理    
  6.         mVf.setOnTouchListener(new OnTouchListener() {              
  7.             @Override    
  8.             public boolean onTouch(View v, MotionEvent event) {    
  9.                 return mVfDetector.onTouchEvent(event);    
  10.             }    
  11.         });    
  12.             
  13.         //添加一個(gè)textview。textview不能setLongClickable(true),    
  14.         //如果設(shè)置了那么發(fā)生在textview上的touch事件就無法傳給viewflipper,    
  15.         //無法被手勢(shì)識(shí)別對(duì)象處理了。    
  16.         TextView tv = new TextView(this);    
  17.         tv.setText("TextView 1");    
  18.         tv.setBackgroundColor(0xffffffff); //設(shè)置一個(gè)白色背景,方便看到textview區(qū)域    
  19.         mVf.addView(tv,new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));    
  20.             
  21.         //再添加一個(gè)textview    
  22.         TextView tv2 = new TextView(this);    
  23.         tv2.setText("TextView 2");    
  24.         tv2.setBackgroundColor(0xffffffff);    
  25.         mVf.addView(tv2,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));    
  26.                    
  27.         //將viewFlipper作為Activity的主view顯示    
  28.         setContentView(mVf);   

在監(jiān)聽器中用到了GestureDetector對(duì)象,其是一個(gè)類成員對(duì)象,用如下代碼創(chuàng)建:

Java代碼

 
 
 
  1. private GestureDetector mVfDetector = new GestureDetector(new OnGestureListener() {    
  2.         //手指在屏幕上移動(dòng)距離小于此值不會(huì)被認(rèn)為是手勢(shì)    
  3.         private static final int SWIPE_MIN_DISTANCE = 120;    
  4.         //手指在屏幕上移動(dòng)速度小于此值不會(huì)被認(rèn)為手勢(shì)    
  5.         private static final int SWIPE_THRESHOLD_VELOCITY = 200;    
  6.             
  7.         //手勢(shì)識(shí)別函數(shù),到此函數(shù)被系統(tǒng)回調(diào)時(shí)說明系統(tǒng)認(rèn)為發(fā)生了手勢(shì)事件,    
  8.         //我們可以做進(jìn)一步判定。    
  9.         @Override    
  10.         public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {    
  11.             //如果第1個(gè)坐標(biāo)點(diǎn)大于第二個(gè)坐標(biāo)點(diǎn),說明是向左滑動(dòng)    
  12.             //滑動(dòng)距離以及滑動(dòng)速度是額外判斷,可根據(jù)實(shí)際情況修改。    
  13.             if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE &&     
  14. Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {    
  15.                 //left    
  16.                 Log.i("GestureDemo", "ViewFlipper left");    
  17.                 mVf.showNext();    
  18.                 return true;    
  19.             }else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE &&     
  20. Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {    
  21.                 //right    
  22.                 Log.i("GestureDemo", "ViewFlipper right");    
  23.                 mVf.showPrevious();     
  24.                 return true;    
  25.             }    
  26.             return false;    
  27.         }    
  28.                 ... ...    
  29.                 ... ...    
  30.          });    
  31. }   

#p#

我們將前文中添加第二個(gè)textview的改為添加Listview,代碼如下:

Java代碼

 
 
 
  1.    
  2.  
  3. ListView lv = new ListView(this);    
  4. lv.setBackgroundColor(0xff808080);    
  5. final String[] items = {"one", "two", "three"};    
  6. lv.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, items));    
  7. mVf.addView(lv,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));    

執(zhí)行ap,滑動(dòng)屏幕切換到第二屏,可以看到第二屏被換成了一個(gè)ListView,并且沒有填充完整個(gè)屏幕,這時(shí)如果在底部非ListView區(qū)域向左滑動(dòng),仍然可以切換到***屏,但是在Listview區(qū)域滑動(dòng)就沒有效果了,因?yàn)閠ouch事件被Listview處理了,ViewFlipper無法收到touch事件也就無法進(jìn)行手勢(shì)判斷。

我們給ListView也增加一個(gè)touch事件監(jiān)聽器,代碼如下:

Java代碼

 
 
 
  1.    
  2.  
  3. lv.setOnTouchListener(new OnTouchListener() {               
  4.     @Override    
  5.     public boolean onTouch(View v, MotionEvent event) {    
  6.         return mVfDetector.onTouchEvent(event);    
  7.     }    
  8. });    

此時(shí)在ListView上滑動(dòng)也能實(shí)現(xiàn)屏幕切換了。

我們?cè)俳oListview增加響應(yīng)點(diǎn)擊事件的處理,代碼如下:

Java代碼

 
 
 
  1.    
  2.  
  3. lv.setOnItemClickListener(new OnItemClickListener() {    
  4.     @Override    
  5.     public void onItemClick(AdapterView > arg0, View arg1,     
  6.         int arg2, long arg3) {    
  7.         new AlertDialog.Builder(MainActivity.this)    
  8.             .setMessage(items[arg2])    
  9.             .create()    
  10.             .show();                    
  11.     }    
  12. });    

當(dāng)點(diǎn)擊Listview的條目的時(shí)候,就會(huì)彈出窗口顯示點(diǎn)擊了哪一項(xiàng),此時(shí)的代碼可參見附件1。

截止到此時(shí),似乎Listview支持左右滑動(dòng)的操作完成了,但實(shí)際上仍有兩個(gè)問題:

首先就是滑動(dòng)時(shí),Listview有時(shí)會(huì)有條目被高亮,這個(gè)問題倒還不是太嚴(yán)重。

再次就是ContextMenu每次滑動(dòng)都會(huì)被激活,我們可以通過代碼驗(yàn)證,創(chuàng)建ListView的代碼稍作修改:

Java代碼

 
 
 
  1.    
  2.  
  3. //使Listview長(zhǎng)一些    
  4. final String[] items = {"one", "two", "three", "four", "five", "six", "sevent", "eight", "nine"};     
  5. registerForContextMenu(lv);    

另外Activity的代碼增加:

Java代碼

 
 
 
  1. @Override    
  2. public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {    
  3.         menu.add("Menu 1");    
  4.         menu.add("Menu 2");    
  5.         menu.add("Menu 3");    
  6.     super.onCreateContextMenu(menu, v, menuInfo);    
  7. }   

當(dāng)我們?cè)贚istView的某一項(xiàng)上長(zhǎng)按時(shí)就會(huì)彈出菜單,但是當(dāng)滑動(dòng)時(shí),即使屏幕切換到了***屏,此菜單仍然會(huì)彈出。

為了解決上面的問題,我嘗試了以下辦法:

1.在ListView的touch事件監(jiān)聽函數(shù)中始終返回true,吃掉所有事件,這樣的修改導(dǎo)致不能相應(yīng)點(diǎn)擊,ListView不能上下滑動(dòng),此路不通。

2.在GestureDetector的fling函數(shù)中向ListView發(fā)送一個(gè)MotionEvent.ACTION_CANCEL事件,總是空指針異常,懷疑是因?yàn)閠ouch事件沒有被ListView處理過,其內(nèi)部成員狀態(tài)異常,于是我從ListView繼承實(shí)現(xiàn)了一個(gè)ListView,在onTouchEvent中呼叫super.onTouchEvent,但是發(fā)送MotionEvent.ACTION_CANCEL事件時(shí)仍然是空指針異常,再次失敗。

3.GestureDetector的onDown函數(shù)返回true,吃掉down事件,此時(shí)點(diǎn)擊時(shí)沒有高亮項(xiàng)了,切換時(shí)contextmenu也不被trigger了,但是長(zhǎng)按也無法彈出contextmenu了。

為了能彈出contextMenu,那么就要在GestureDetector的onLongPress函數(shù)中調(diào)用ListView.showContextMenuForChild()來彈出菜單。

那么GestureDetector就與ViewFlipper的不通用了。

所以我重新由ListView繼承實(shí)現(xiàn)了一個(gè)類,這個(gè)類自身綁定了一個(gè)GestureDetector:

Java代碼

 
 
 
  1.    
  2.  
  3. @Override    
  4. public boolean onDown(MotionEvent e) {    
  5.     return true;    //吃掉Down事件    
  6. }    
  7. @Override    
  8. public void onLongPress(MotionEvent e) {        
  9.     System.out.println("Listview long press");    
  10.     int position = pointToPosition((int)e.getX(), (int)e.getY());                   
  11.     if( position != ListView.INVALID_POSITION) {    
  12.         View child = getChildAt(position - getFirstVisiblePosition());    
  13.         if(child != null) GestureListView.this.showContextMenuForChild(child);    
  14.     }    
  15. }    

另外為了能夠顯示contextmenu時(shí)在哪一項(xiàng)上激活的,在Activity增加函數(shù):

Java代碼

 
 
 
  1. @Override    
  2. public boolean onContextItemSelected(MenuItem item) {    
  3.     AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();    
  4.     System.out.println("View " + info.position + " context menu activited.");    
  5.     return super.onContextItemSelected(item);    
  6. }   

從LogCat即可看到打印輸出。

此時(shí)此ListView可以響應(yīng)手勢(shì)、可以響應(yīng)點(diǎn)擊、可以彈出菜單,基本的功能已經(jīng)滿足,另外再微調(diào)一下ondown函數(shù),當(dāng)點(diǎn)擊時(shí)可以高亮一下。

【編輯推薦】

  1. Android開發(fā):系統(tǒng)自動(dòng)實(shí)現(xiàn)開機(jī)啟動(dòng)
  2. Android開發(fā):自由選擇TextView的文字
  3. Android開發(fā):如何實(shí)現(xiàn)TCP和UDP傳輸

新聞標(biāo)題:Android觸屏textview及l(fā)istview對(duì)比驗(yàn)證
網(wǎng)站URL:http://www.dlmjj.cn/article/dpojedo.html