1. 程式人生 > >[安卓開發基礎] 9 事件處理

[安卓開發基礎] 9 事件處理

<Android從入門到精通 專案案例版 第9章>

9.1事件處理種類:

事件處理過程:事件源,事件事件監聽器

 

 

基於監聽:setOnClickListener   按鍵 監聽

 

基於回撥的事件處理,重寫方法:

public class IntentActivity extends AppCompatActivity {
     Button  
btn_start;
   
//滑鼠右鍵----Generate---Overate Method----nTouchEvent  
     //  nTouchEvent  觸控 螢幕
    //  onKeyDown  onKeyUp    單擊物理按鈕
   

@Override
   
public boolean onTouchEvent(MotionEvent event) {
        Toast.makeText(IntentActivity.
this,"觸控",Toast.LENGTH_SHORT).show();
        return super
.onTouchEvent(event);


   
}

   
@Override
   
public boolean onKeyDown(int keyCode, KeyEvent event) {
        Toast.makeText(IntentActivity.
this,"按下",Toast.LENGTH_SHORT).show();
        return super
.onKeyDown(keyCode, event);
   
}

   
@Override
   
public boolean onKeyUp(int keyCode, KeyEvent event) {
        Toast.makeText(IntentActivity.
this,"擡起",Toast.LENGTH_SHORT).show();
        return super
.onKeyUp(keyCode, event);
   
}

例項:按按鍵連續按兩次 超過兩秒 Toast提示 “再按一次退出程式”按 返回鍵 提示:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
   
if(keyCode==KeyEvent.KEYCODE_BACK){
       
if((System.currentTimeMillis()-exitTime)>2000){
            Toast.makeText(IntentActivity.
this,"再按一次退出程式",Toast.LENGTH_SHORT).show();
           
exitTime=System.currentTimeMillis();
       
}else{
            finish()
;
       
}
      
return  true;
   
}
   
return super.onKeyDown(keyCode, event);
}

 

觸控式螢幕事件處理

 單擊事件:

 

長按事件:長按兩秒會呼叫

例如:長按按鍵

btn_start.setOnLongClickListener(new View.OnLongClickListener() {
   
@Override
   
public boolean onLongClick(View view) {

        Toast.makeText(IntentActivity.
this,"長按",Toast.LENGTH_SHORT).show();

        return false;
   
}
})
;

 

程式碼:

btn_start.setOnLongClickListener(new View.OnLongClickListener() {
       
@Override
       
public boolean onLongClick(View view) {

          
// Toast.makeText(IntentActivity.this,"長按",Toast.LENGTH_SHORT).show();
          
registerForContextMenu(view);//註冊選單
          
openContextMenu(view);//開啟選單

           
return false;
       
}
    })
;

}
//新增選單
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
   
super.onCreateContextMenu(menu, v, menuInfo);
   
menu.add("收藏");
   
menu.add("刪除");
}
//新增獲取選單
@Override
public boolean onContextItemSelected(MenuItem item) {


    Toast.makeText(IntentActivity.
this,"選擇了"+item,Toast.LENGTH_SHORT).show();
    return super
.onContextItemSelected(item);
}

觸控事件:

快捷鍵,alt+回車 顯示建構函式

例項程式碼:

建立  HatView類 繼承View,Paint paint類  new建立物件 不能寫在  OnDraw 方法裡面,因為 onDraw 方法會重複呼叫否則會出現如下問題:

相關問題連結:https://blog.csdn.net/bzb123321/article/details/81298014?utm_source=blogxgwz1

 

>警告提示
Avoid object allocations during draw/layout operations (preallocate and reuse instead) less... (Ctrl+F1) 
You should avoid allocating objects during a drawing or layout operation. These are called frequently, so a smooth UI can be interrupted by garbage collection pauses caused by the object allocations.  The way this is generally handled is to allocate the needed objects up front and to reuse them for each drawing operation.  Some methods allocate memory on your behalf (such as Bitmap.create), and these should be handled in the same way.

> 提示 已經很清楚 就是 避免在例項化操作(提前分配並在draw和layout的時候 直接使用)

例項化操作會阻礙 垃圾回收機制 ,使 介面卡頓。
--------------------- 
作者:打碼人bzb 
來源:CSDN 
原文:https://blog.csdn.net/bzb123321/article/details/81298014 
版權宣告:本文為博主原創文章,轉載請附上博文連結!

-------------------------

package com.event.Touch;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

import com.zengjx.androidbaseproject.R;

/**
 * Created by zengjx on 2018/12/20.
 */

public class HatView   extends View{
    public     float bitmapX;
    public     float  bitmapY;//帽子顯示的座標
    Paint paint = new Paint(); //建立Paint物件
    Bitmap   bitmap;
    Context mcontext;
    public HatView(Context context) {
        super(context);
        mcontext=context;
        bitmapX=65;
        bitmapY=0;
        bitmap  = BitmapFactory.decodeResource(this.getResources(),R.drawable.hat);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

     //   Paint paint2= new Paint(); //建立Paint物件
       paint.setDither(true);

        canvas.drawBitmap(bitmap,bitmapX,bitmapY,paint);
        if(bitmap.isRecycled()){//判斷圖片是否回收
            bitmap.recycle();//強制回收
        }
    }


    @Override
    public boolean performClick() {
        return super.performClick();
    }
}

//avtivity:

package com.zengjx.androidbaseproject;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

import com.event.Touch.HatView;

public class TouchEventActivity extends AppCompatActivity {
 HatView hat ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_touch_event);
        hat=  new HatView(TouchEventActivity.this); // 建立並例項化HatView類
        RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativelayout); // 獲取相對局管理器

        // 為帽子新增觸控事件監聽
        hat.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                hat.bitmapX = event.getX()-88; // 設定帽子顯示位置的X座標
                hat.bitmapY = event.getY()-33; // 設定帽子顯示位置的Y座標
                hat.invalidate(); // 重繪hat元件
                return true;
            }
        });
        relativeLayout.addView(hat); //將hat新增到佈局管理器中
    }


}  單擊事件與觸控事件的區別:

 會先響應觸控事件,如果觸控事件返回 true 則 單擊事件不會響應。如果觸控事件返回 false 則 單擊事件不會響應。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.touch_key);
    button=findViewById(R.id.btn_touchkey);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Log.i("touch","單擊事件") ;
        }
    });

    button.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            Log.i("touch","觸控事件") ;
            switch (motionEvent.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.i("touch","按下") ;
                    break;
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                    Log.i("touch","擡起") ;
                    button.performClick();
                    break;
            }
            Log.i("touch","返回 flase") ;
            return false;
        }




    });


}
//但是日誌資訊:觸控離開 還是會有 單擊事件

警告:setOnTouchListener

Custom view `Button` has setOnTouchListener called on it but does not override performClick less... (Ctrl+F1) 
If a View that overrides onTouchEvent or uses an OnTouchListener does not also 
implement performClick and call it when clicks are detected, the View may not handle 
accessibility actions properly. Logic handling the click actions should ideally 
be placed in View#performClick 
as some accessibility services invoke performClick when a click action should occur.

相關 部落格:https://blog.csdn.net/qq_32916805/article/details/78567651