1. 程式人生 > >appwidget 視窗小部件onTouch事件及手勢識別

appwidget 視窗小部件onTouch事件及手勢識別

android原始碼有關視窗小部件的所支援的東西確實很少,用起來也很別手,2.2版的視窗小部件應該也只是用作一種被動的顯示。其連最基本的手勢事件也不支援。當然,HTC已經實現了小部件的onTouch事件,並根據手勢做動作。

     斷斷續續的研究RemoteView幾周的時間,總算實現了小部件的onTouch,並使其識別手勢。簡單分享:

方法一,提供一個較笨的只能實現部分簡單功能的方法:

      在framework層自己寫一個View,使其繼承自所要響應onTouch方法的控制元件,並實現手勢操作

package android.widget;  
import android.content.Context;  
import android.util.AttributeSet;  
import android.util.Log;  
import android.view.GestureDetector;  
import android.view.MotionEvent;  
import android.widget.TextView;  
import android.widget.RemoteViews.RemoteView;  
@RemoteView  
public class TouchTextView extends TextView {  
    private GestureDetector mGestureDetector = null;  
    public TouchTextView(Context context, AttributeSet attrs) {       
        super(context, attrs);        
        mGestureDetector = new GestureDetector(context, new LearnGestureListener());          
    }  
      
      
    public boolean onTouchEvent(MotionEvent event) {  
        return mGestureDetector.onTouchEvent(event);  
    }  
    class LearnGestureListener extends GestureDetector.SimpleOnGestureListener {  
        @Override  
        public boolean onSingleTapUp(MotionEvent ev) {  
            Log.d("DEBUG","onSingleTapUp");  
            return true;  
        }  
        @Override  
        public void onShowPress(MotionEvent ev) {  
            Log.d("DEBUG","onShowPress");  
        }  
        @Override  
        public void onLongPress(MotionEvent ev) {  
            Log.d("DEBUG","onLongPress");  
        }  
        @Override  
        public boolean onScroll(MotionEvent e1, MotionEvent e2,  
                float distanceX, float distanceY) {  
            Log.d("DEBUG","onScroll");  
            return true;  
        }  
        @Override  
        public boolean onDown(MotionEvent ev) {  
            Log.d("DEBUG","onDownd");  
            return true;  
        }  
        @Override  
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
                float velocityY) {  
            Log.d("DEBUG","onFling");  
            return true;  
        }  
        public boolean onDoubleTap(MotionEvent event){  
            Log.d("DEBUG","onDoubleTap");  
            return true;  
        }  
    }        
}  
利用此辦法,即可實現手勢識別,但缺點很嚴重,就是想要響應的所有手勢事件都必須在framework層實現,這樣很笨,也很麻煩,但確實也算一種方法吧。使用時在xml檔案中直接定義即可
 <TouchTextView
        android:id="@+id/note_widget"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

方法二,在RemoteView中新增一個setOnTouchPendingIntent事件

      當然,我最初的想法也是如此,不過新增這個onTouch事件確實耗費了好一段時間,而且由於在本地編譯整個工程,每次編譯都要1個多小時,很是頭疼,還好最終總算是實現了。

     提供思路:在RemoteView中仿照setOnClickPendingIntent事件寫一個setOnTouchPendingIntent事件,並將event傳遞出來,在onReceive中接受。定義手勢,重寫手勢中的onScroll等方法,通過mGestureDetector.onTouchEvent(event);    去響應即可

響應手勢的方法說明:  
GestureDetector mGestureDetector = new GestureDetector(context, new LearnGestureListener());  
mGestureDetector.onTouchEvent(event);  
class LearnGestureListener extends GestureDetector.SimpleOnGestureListener {  
        @Override  
        public boolean onSingleTapUp(MotionEvent ev) {  
            Log.d("DEBUG","onSingleTapUp");  
            return true;  
        }  
    。。。//重寫手勢對應的其他方法  
}