15.阻止觸控竊賊
15.1 問題
應用程式檢視中設計了巢狀的觸控互動,這些互動不能很好地作用於觸控層次結構 的標準流程,在此層次結構中,較高層的容器檢視透過子檢視進行竊取來直接處理觸控事件。
15.2 解決方案
(API Level 1)
ViewGroup是框架中所有佈局和容器的基類,它為此提供了描述性命名方法requestDisallowTouchIntercept()。在任何容器檢視上設定此標誌會指示框架,在當前手勢持續期間,我們更希望它們不會攔截進入其子檢視的事件。
15.3 實現機制
為展示此方法的實際使用,我們建立了一個示例,其中兩個互相競爭的可觸控檢視位於同一位置。外部包含檢視是ListView,它透過滾動內容響應指示垂直拖動的觸控事件。在ListView內部是作為頭部新增的ViewPager,它響應水平拖動觸控事件以在頁面之間輕掃。就其本質來說,該例帶來了一個問題,水平輕掃在垂直方向上遠距離變化的ViewPager的嘗試會為了支援ListView滾動而被取消,因為ListView會監控和攔截這些事件。人們無法在垂直或水平運動過程中進行拖動,因此這就產生了可用性問題。
為建立此例,首先需要宣告一個維度資源(參見以下程式碼),程式碼清單給出了完整的Activity。
res/values/dimens.xml
<?xml version="1.0" encoding="utf-8"?><resources> <dimen name="header_height">150dp</dimen></resources>
管理觸控攔截的Activity
public class DisallowActivity extends Activity implements ViewPager.OnPageChangeListener { private static final String[] ITEMS = { "Row One", "Row Two", "Row Three", "Row Four", "Row Five", "Row Six", "Row Seven", "Row Eight", "Row Nine", "Row Ten" }; private ViewPager mViewPager; private ListView mListView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a header view of horizontal swiping items mViewPager = new ViewPager(this); // As a ListView header, ViewPager must be given a fixed height mViewPager.setLayoutParams(new ListView.LayoutParams( ListView.LayoutParams.MATCH_PARENT, getResources().getDimensionPixelSize(R.dimen.header_height)) ); // Listen for paging state changes to disable parent touches mViewPager.setOnPageChangeListener(this); mViewPager.setAdapter(new HeaderAdapter(this)); // Create a vertical scrolling list mListView = new ListView(this); // Add the pager as the list header mListView.addHeaderView(mViewPager); // Add list items mListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, ITEMS)); setContentView(mListView); } /* OnPageChangeListener Methods */ @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { // While the ViewPager is scrolling, disable the ScrollView touch // intercept so it cannot take over and try to vertical scroll. // This flag must be set for each gesture you want to override. boolean isScrolling = state != ViewPager.SCROLL_STATE_IDLE; mListView.requestDisallowInterceptTouchEvent(isScrolling); } private static class HeaderAdapter extends PagerAdapter { private Context mContext; public HeaderAdapter(Context context) { mContext = context; } @Override public int getCount() { return 5; } @Override public Object instantiateItem(ViewGroup container, int position) { // Create a new page view TextView tv = new TextView(mContext); tv.setText(String.format("Page %d", position + 1)); tv.setBackgroundColor((position % 2 == 0) ? Color.RED : Color.GREEN); tv.setGravity(Gravity.CENTER); tv.setTextColor(Color.BLACK); // Add as the view for this position, and return as the object for // this position container.addView(tv); return tv; } @Override public void destroyItem(ViewGroup container, int position, Object object) { View page = (View) object; container.removeView(page); } @Override public boolean isViewFromObject(View view, Object object) { return (view == object); } } }
在此Activity中,作為根檢視的ListView包含一個基本介面卡,用於顯示字串條目的靜態列表。同樣在onCreate()方法中,建立ViewPager例項並作為頭部檢視新增到列表中。我們將在本章後面更詳細地討論ViewPager的工作方式,此處只需要知道我們正在建立一個帶有自定義PagerAdapter的簡單ViewPager,它顯示了一些彩色檢視作為其頁面,以供使用者在這些頁面直接輕掃。
建立ViewPager之後,構造並應用一組ListView.LayoutParams來控制ViewPager如何作為頭部顯示。必須執行該操作,因為ViewPager自身沒有內在的內容大小,並且列表不能很好地作用於沒有明確高度的檢視。透過維度資源應用固定的高度,從而可以輕鬆獲得適當縮放的dp值,該值與裝置無關。這比完全透過Java程式碼全面構造dp值要簡單很多。
此例的關鍵之處在於Activity實現的onPageChangeListener(該回撥在後面會用於與ViewPager)。當使用者與ViewPager互動並左右輕掃時,就會觸發此回撥。在onPageScrollStateChanged()方法內部,我們傳遞一個指示ViewPager是否空閒、
Activity正在滾動或在滾動後停到某個頁面的值。這是控制父ListView的觸控攔截行為的最佳位置。當ViewPager的滾動狀態不是空閒時,我們不希望ListView竊取Viewager正在使用的觸控事件,因此在requestDisallowTouchIntercept()中設定相應的標誌。
連續觸發該值還要另一個原因。在原始解決方案中提及,該標誌對當前手勢有效。這意味著每次新的ACTION_DOWN事件發生時,我們需要再次設定該標誌。沒有新增觸控偵聽器來查詢特定的事件,我們基於子檢視的滾動行為連續設定該標誌,這就獲得了相同的效果。
作者:Jennyni1122
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2558/viewspace-2821795/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 15. 監控磁碟IO使用率
- wpf 觸控 觸控後無法開啟pupup
- Unity觸控式螢幕觸控事件定義Unity事件
- JS觸控事件JS事件
- 觸控檯燈
- ScrollView 觸控事件View事件
- 筆記本觸控板手勢大全 觸控板快捷手勢筆記
- Mac如何防止觸控板誤觸?關閉MacBook系列筆記本觸控板的方法Mac筆記
- 家賊難防,Ubiquiti前僱員竊取公司資料並實施勒索UI
- 低功耗抗干擾2路觸控檢測晶片,2通道2鍵觸控觸控IC-VK3702DM晶片
- archlinux 觸控板手勢配置Linux
- win10觸控板快捷操作_win10觸控板手勢設定Win10
- 高抗干擾 低功耗VK36E4-4通道/四觸控觸控晶片,4按鍵觸控檢測晶片晶片
- 如何阻止:hover、:active等滑鼠行為狀態的觸發?
- 觸控板觸控式螢幕禁止手指縮放,這麼處理才行
- Jetpack Compose(7)——觸控反饋Jetpack
- 觸控事件獲取座標事件
- Flutter:如何響應觸控事件Flutter事件
- 設定單點觸控splitMotionEvents
- 通訊錄觸控下拉demo
- 安全快報 | 特斯拉進入系統存風險:竊賊可偷走你的汽車
- 華碩win10插入滑鼠時觸控板禁用觸控板的具體教程Win10
- 觸控遊戲CEO賈晨及管理團隊全資收購觸控遊戲遊戲
- Himax 10.36寸 incell觸控除錯除錯
- 觸控板增強神器:Bettertouchtool for MacMac
- 觸控板和滑鼠增強Middle
- 觸控板增強工具:Bettertouchtool MacMac
- Scrollow for mac(觸控板手勢工具)1.6.4Mac
- Touch Bar Piano for mac觸控鋼琴Mac
- Bettertouchtool for Mac觸控板增強工具Mac
- linux 取消筆記本觸控鍵Linux筆記
- Android 觸控式螢幕驅動Android
- Android觸控事件傳遞機制Android事件
- 「技術乾貨」工業觸控式螢幕之觸控式螢幕分類(連載)
- 新鮮出爐:appium2.0+ 單點觸控和多點觸控新的解決方案APP
- win10觸控板如何校準_windows10怎樣校準觸控式螢幕Win10Windows
- win10觸控板怎麼關閉_win10關閉觸控板的步驟Win10
- 超強抗干擾單鍵觸控/電容式觸控IC-VK3601 SOT23-6單通道直接輸出/觸控感應方案原廠