安卓基础学习 Day18|按键事件+手势操作(图片的放大、缩小、切换)
目錄
一、按鍵事件的概念
二、案例演示
1.提出要求
?2.主布局資源文件
3.主界面
一、觸摸事件的概述
觸摸分類
觸摸動作
觸摸監聽器
觸摸方法
觸點個數與坐標
二、單點觸摸
案例:移動米老鼠
提出要求
?主布局資源文件
主界面
?三、多點縮放
案例:縮放米老鼠
提出要求
??主布局資源文件
主界面
四、手勢切換照片?
1.手勢操作原理
2.安卓手勢類與接口
MotionEvent
GestureDetector
OnGestureListener
3.案例操作
1.提出要求
2. 下載喜歡的圖片并存放在res/mipmap中
3.主布局資源文件
?4.主界面
一、按鍵事件的概念
按鍵事件:用戶按下或者釋放手機鍵盤上的某個界面時產生的事件
監聽器是:View.OnKeyListener
事件處理方法是:onKey()
二、案例演示
1.提出要求
通過按上、下、左、右方向鍵來移動米老鼠。
?2.主布局資源文件
將布局設置為線性布局,并在里面插入一張圖片
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/root"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ImageViewandroid:id="@+id/iv_mickey"android:layout_width="100dp"android:layout_height="130dp"android:src="@mipmap/mickey"android:scaleType="fitXY" /></LinearLayout>效果
3.主界面
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.view.KeyEvent; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Toast;public class MainActivity extends AppCompatActivity {//聲明變量protected static final int STEP = 10;private ImageView ivMickey;private LinearLayout root;private LinearLayout.LayoutParams layoutParams;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//利用布局資源文件設置用戶界面setContentView(R.layout.activity_main);//通過資源索引獲取控件實例ivMickey = findViewById(R.id.iv_mickey);root = findViewById(R.id.root);//設置根布局可以獲取焦點root.setFocusable(true);//讓根布局獲取焦點root.requestFocus();//獲取圖像控件的布局參數layoutParams = (LinearLayout.LayoutParams) ivMickey.getLayoutParams();//給根布局注冊監聽器root.setOnKeyListener(new View.OnKeyListener() {@Overridepublic boolean onKey(View v, int keyCode, KeyEvent event) {switch (keyCode) {//根據按鍵修改圖像控件的布局參數case KeyEvent.KEYCODE_DPAD_UP://按上方按鍵//上邊界碰撞檢測if (ivMickey.getTop() >= 10) {layoutParams.topMargin = layoutParams.topMargin - STEP;} else {Toast.makeText(MainActivity.this, "碰到上邊界", Toast.LENGTH_SHORT).show();}break;case KeyEvent.KEYCODE_DPAD_DOWN://按下方按鍵layoutParams.topMargin = layoutParams.topMargin + STEP;break;case KeyEvent.KEYCODE_DPAD_LEFT://按左方按鍵layoutParams.leftMargin = layoutParams.leftMargin - STEP;break;case KeyEvent.KEYCODE_DPAD_RIGHT://按右方按鍵layoutParams.leftMargin = layoutParams.leftMargin + STEP;break;}//重新獲取圖像控件的布局參數ivMickey.setLayoutParams(layoutParams);return false;}});} }效果展示:
這里只有上邊緣的碰撞檢測,現在對剩下的三邊添加代碼進行碰撞檢測
switch (keyCode) {//根據按鍵修改圖像控件的布局參數case KeyEvent.KEYCODE_DPAD_UP://按上方按鍵//上邊界碰撞檢測if (ivMickey.getTop() >= 10) {layoutParams.topMargin = layoutParams.topMargin - STEP;} else {Toast.makeText(MainActivity.this, "碰到上邊界", Toast.LENGTH_SHORT).show();}break;case KeyEvent.KEYCODE_DPAD_DOWN://按下方按鍵//下邊界碰撞檢測if (ivMickey.getBottom() <= 1800) {layoutParams.topMargin = layoutParams.topMargin + STEP;} else {Toast.makeText(MainActivity.this, "碰到下邊界", Toast.LENGTH_SHORT).show();}break;case KeyEvent.KEYCODE_DPAD_LEFT://按左方按鍵//左邊界碰撞檢測if (ivMickey.getLeft() >= 0) {layoutParams.leftMargin = layoutParams.leftMargin - STEP;} else {Toast.makeText(MainActivity.this, "碰到左邊界", Toast.LENGTH_SHORT).show();}break;case KeyEvent.KEYCODE_DPAD_RIGHT://按右方按鍵//右邊界碰撞檢測if (ivMickey.getRight() <= 1100) {layoutParams.leftMargin = layoutParams.leftMargin + STEP;} else {Toast.makeText(MainActivity.this, "碰到右邊界", Toast.LENGTH_SHORT).show();}break;}?效果展示:
到邊緣會停止,但是由于吐司的時間導致顯示的比較慢?
一、觸摸事件的概述
按鍵事件:用戶觸摸手機屏幕的某個界面時產生的事件
觸摸分類
1.單點觸摸(滑動)
2.多點觸摸(放大、縮小)
觸摸動作
1.按下(MotionEvent.ACTION_DOWN)
2.移動(MotionEvent.ACTION_MOVE)
3.松開(MotionEvent.ACTION_UP)
觸摸監聽器
onTouchListener
觸摸方法
在onTouch()?方法里,我們可以根據不同動作編寫不同事件處理代碼。
觸點個數與坐標
單點觸摸,通過MotionEvent對象的getX()和getY()方法可以獲得觸摸點的坐標。
多點觸摸,通過getPointerCount()獲取觸點個數,然后通過getX(pointerIndex)與getY(pointerIndex)獲得某個觸點的坐標。
二、單點觸摸
案例:移動米老鼠
提出要求
?主布局資源文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/root"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ImageViewandroid:id="@+id/ivmickey"android:layout_width="100dp"android:layout_height="130dp"android:scaleType="fitXY"android:src="@mipmap/mickey" /></LinearLayout>主界面
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {//聲明變量protected static final String TAG = "move_mickey_by_touch";private ImageView ivMickey;private LinearLayout root;private LinearLayout.LayoutParams layoutParams;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//利用布局資源文件設置用戶界面setContentView(R.layout.activity_main);//通過資源索引獲取控件實例ivMickey = findViewById(R.id.ivmickey);root = findViewById(R.id.root);//設置根布局可以獲取焦點root.setFocusable(true);//讓根布局獲取焦點root.requestFocus();//獲取圖像控件的布局參數layoutParams = (LinearLayout.LayoutParams) ivMickey.getLayoutParams();//給根布局注冊觸摸監聽器,實現觸摸監聽器接口,編寫觸摸事件代碼root.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {//根據觸摸執行不同的操作switch (event.getAction()) {case MotionEvent.ACTION_DOWN: // 觸點按下Log.d(TAG, "ACTION_DOWN(" + event.getX() + "," + event.getY() + ")");break;case MotionEvent.ACTION_MOVE: //觸點移動Log.d(TAG, "ACTION_MOVE(" + event.getX() + "," + event.getY() + ")");break;case MotionEvent.ACTION_UP: // 觸點拿開Log.d(TAG, "ACTION_UP(" + event.getX() + "," + event.getY() + ")");break;}// 根據變化的觸點坐標來更新圖像控件的布局參數layoutParams.leftMargin = (int) event.getX();layoutParams.topMargin = (int) event.getY();//重新設置圖像控件的布局參數ivMickey.setLayoutParams(layoutParams);return true; // 只有設置為真,按下、移動、松開才會依次執行}});} }?打印顯示
效果展示
將觸點定位在米老鼠的中心
?三、多點縮放
案例:縮放米老鼠
提出要求
??主布局資源文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/root"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ImageViewandroid:id="@+id/ivmickey"android:layout_width="100dp"android:layout_height="130dp"android:scaleType="fitXY"android:src="@mipmap/mickey" /></LinearLayout>主界面
【首先判斷是一個觸點還是兩個觸點,獲取到兩個觸點的坐標,利用兩坐標的距離的變化,來判斷用戶想進行的操作是放大還是縮小,獲取到一個觸點就跟隨用戶移動】
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout;import java.lang.annotation.ElementType;public class MainActivity extends AppCompatActivity {private ImageView ivMickey; // 米老鼠圖像控件private LinearLayout root; // 線性根布局private LinearLayout.LayoutParams layoutParams; //線性布局布局參數private float x1, y1; // 第一個觸點的坐標private float x2, y2; // 第一個觸點的坐標private float next_x1, next_y1; // 第一個觸點下次的坐標private float next_x2, next_y2; // 第一個觸點下次的坐標private float distance; //兩個觸點之間的距離private float next_distance; //下一次兩個觸點之間的距離@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//利用布局資源文件設置用戶界面setContentView(R.layout.activity_main);//通過資源索引獲取控件實例ivMickey = findViewById(R.id.ivmickey);root = findViewById(R.id.root);//設置根布局可以獲取焦點root.setFocusable(true);//讓根布局獲取焦點root.requestFocus();//獲取圖像控件的布局參數layoutParams = (LinearLayout.LayoutParams) ivMickey.getLayoutParams();//給根布局注冊觸摸監聽器root.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent event) {//根據觸點個數執行不同的操作(兩個觸點縮放圖像,單個觸點移動圖像)if (event.getPointerCount() == 2) {//兩點觸摸//根據觸摸動作執行不同的動作switch (event.getAction()) {case MotionEvent.ACTION_DOWN://獲取第一個觸點的坐標x1 = event.getX(0);y1 = event.getY(0);//獲取第二個觸點的坐標x2 = event.getX(1);y2 = event.getY(1);//計算兩點之間的距離distance = (float) Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));break;case MotionEvent.ACTION_MOVE: // 觸點移動//獲取第一個觸點的坐標next_x1 = event.getX(0);next_y1 = event.getY(0);//獲取第二個觸點的坐標next_x2 = event.getX(1);next_y2 = event.getY(1);//計算兩點之間的距離next_distance = (float) Math.sqrt(Math.pow(next_x2 - next_x1, 2) + Math.pow(next_y2 - next_y1, 2));break;case MotionEvent.ACTION_UP: // 觸點松開break;}//修改圖像控件的布局參數if (next_distance > distance) {layoutParams.width = (int) (layoutParams.width * 1.05);layoutParams.height = (int) (layoutParams.height * 1.05);} else {layoutParams.width = (int) (layoutParams.width * 0.95);layoutParams.height = (int) (layoutParams.height * 0.95);}//坐標迭代x1 = next_x1;y1 = next_y1;x2 = next_x2;y2 = next_y2;//兩點之間的距離distance = distance = (float) Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));} else if (event.getPointerCount() == 1) {//單點觸摸if (event.getAction() == MotionEvent.ACTION_MOVE) {//修改圖像控件的布局參數(因為線性布局中的gravity設置的為center,所以要減去屏幕的一半尺寸)layoutParams.leftMargin = (int) (event.getX() - getWindowManager().getDefaultDisplay().getWidth() / 2);layoutParams.topMargin = (int) (event.getX() - getWindowManager().getDefaultDisplay().getWidth() / 2);}}//重新設置圖像控件的布局參數ivMickey.setX(event.getX() - ivMickey.getWidth()/2);ivMickey.setY(event.getY() - ivMickey.getHeight()/2);ivMickey.setLayoutParams(layoutParams);return true; // 只有設置為真,按下、移動、松開才會依次執行}});} }結果展示:(我這里電腦無法完成兩點觸摸,于是我將程序在手機上運行便出現了下面的效果)?
四、手勢切換照片?
1.手勢操作原理
在安卓系統中,每一次的手勢交互都會依照以下執行順序執行
(1)觸屏的一剎那,觸發一個MotionEvent事件。
(2)該事件被OnTouchListener監聽,在其onTouch()方法里獲得該MotionEvent對象。
(3)通過GestureDetector(手勢偵測器)將此MotionEvent對象移交給OnGestureListener。
(4)OnGestureListener監聽器獲得該事件對象,然后根據該對象封裝的信息,做出合適的處理。
上面這四個步驟的順序,可以說是手勢操作的原理
2.安卓手勢類與接口
MotionEvent
動作事件類,用于封裝手勢、觸摸筆、軌跡球等等的動作事件。其內部封裝了兩個重要的屬性X和Y,這兩個屬性分別用于記錄橫軸和縱軸的坐標。
GestureDetector
手勢偵測器,用于識別各種手勢。
OnGestureListener
手勢監聽器,是一個手勢交互的監聽接口,其中提供了多個抽象方法,并根據GestureDetector的手勢識別結果調用相對應的方法。
3.案例操作
1.提出要求
利用手勢切換圖片
?
2. 下載喜歡的圖片并存放在res/mipmap中
3.主布局資源文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/root"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@mipmap/img1"android:orientation="vertical"tools:context=".MainActivity"> </LinearLayout>?4.主界面
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.widget.LinearLayout;public class MainActivity extends AppCompatActivity {//聲明變量private GestureDetector detector;//手勢偵測器private int[] imgIds;//圖像資源標識符數組private int imgIndex;//圖像索引,反映在圖像資源標識符數組中的位置private LinearLayout root;//根線性布局private final static int IMG_COUNT = 13;//圖片總數private final static String TAG = "switchimagebyguesture";//定義程序標記@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//利用布局資源文件設置用戶界面setContentView(R.layout.activity_main);//通過資源標識符獲取控件實例root = findViewById(R.id.root);//初始化圖像標識數組imgIds = new int[IMG_COUNT];for (int i = 0; i < IMG_COUNT; i++) {imgIds[i] = getResources().getIdentifier("img" + (i + 1),//標識符名稱"mipmap",//定義圖片類型"net.lzt.switchimagebyguesture"//定義包名);}//實例化手勢檢測器(參數1:上下文 ,參數2:手勢監聽器對象)detector = new GestureDetector(new GestureDetector.OnGestureListener() {@Overridepublic boolean onDown(MotionEvent e) {Log.i(TAG, "onDown");return false;}@Overridepublic void onShowPress(MotionEvent e) {Log.i(TAG, "onShowPress");}@Overridepublic boolean onSingleTapUp(MotionEvent e) {Log.i(TAG, "onSingleTapUp");return false;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {Log.i(TAG, "onScroll");return false;}@Overridepublic void onLongPress(MotionEvent E) {Log.i(TAG, "onLongPress");}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {Log.i(TAG, "onFling");//手勢向左滑動20個像素,圖像切換到下一張if (e2.getX() < e1.getX() - 5) {if (imgIndex < IMG_COUNT - 1) {imgIndex++;} else {imgIndex = 0;}}//手勢向右滑動20個像素,圖像切換到上一張if (e2.getX() > e1.getX() + 5) {if (imgIndex > 0) {imgIndex--;} else {imgIndex = IMG_COUNT - 1;}}//要根據變換之后圖像索引更新布局的背景圖片root.setBackgroundResource(imgIds[imgIndex]);return false;}});}//將窗口的觸摸事件交給手勢偵測器來處理@Overridepublic boolean onTouchEvent(MotionEvent event) {return detector.onTouchEvent(event);} }效果展示
?
總結
以上是生活随笔為你收集整理的安卓基础学习 Day18|按键事件+手势操作(图片的放大、缩小、切换)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大连医科大学中山学院计算机科学与技术,大
- 下一篇: 5月6日—5月9日三年级课程新