کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

مدیریت رخدادهای تک لمسی و چند لمسی در اندروید

 مدیریت رخدادهای تک لمسی و چند لمسی در اندروید مدیریت رخدادهای تک لمسی و چند لمسی در اندروید

این مبحث آموزشی شما را با رابط برنامه سازی کاربردی touch در اپلیکیشن های اندروید آشنا می سازد .

مدیریت رخدادهای تک لمسی و چند لمسی در اندروید فهرست محتوا

1. قابلیت لمس در اندروید

  • مبانی touch در اندروید
  • رخداد single touch
  • رخداد multi touch
  • آموزش کلاس GestureDetector

2. تمرین : مثالی از Singletouch

  • ترسیم با استفاده از قابلیت لمس
  • Tracking (ردیابی)

3. تمرین ایجاد view با قابلیت multitouch

4. آموزش : ایجاد activity (ScaleGestureDetector)

مدیریت رخدادهای تک لمسی و چند لمسی در اندروید قابلیت لمس در اندروید

مبانی touch در اندروید

کلاس استاندارد View در اندروید از رخدادهای مربوط به touch (لمس صفحه نمایش)پشتیبانی می کند . شما می توانید به رویدادهای touch در View ها و Activity های خود واکنش نشان دهید . اندروید قادر است از چندین pointer (اشاره گر) به طور همزمان پشتیبانی کند, به طور مثال انگشت هایی که با صفحه نمایش تماس و تعامل (interaction) دارند .


مدیریت رویداد touch در اندروید

کلاس پایه (base class) ی که از قابلیت لمس پشتیبانی می کند MotionEvent می باشد, کلاس نام برده به واسطه ی تابع onTouchEvent() به Views ارسال می گردد . جهت واکنش نشان دادن به رخدادهای touch باید متد onTouchEvent() را بازنویسی (override) کرد .
کلاس MotionEvent حامل اطلاعات مربوط به رخدادهای touch می باشد برای مثال می توان از تعداد اشاره گرها, مختصات X/Y و همچنین اندازه و مقدار فشار هر اشاره گر سخن گفت .
چنانچه رویداد touch توسط view (نما) مدیریت شود, در آن صورت متد ذکر شده true باز می گرداند . سعی اندروید بیشتر بر یافتن آن view ی است که از همه کاملتر (deepest view) بوده و به منظور مدیریت رویدادهای touch, true برمی گرداند . اگر view مورد نظر جزئی از view دیگر بود (مقصود همان view پدر می باشد), در آن صورت نما یا view پدر با بازگرداندن true از متد onInterceptTouchEvent() می تواند صاحب این رویداد شود . این کار رخداد MotionEvent.ACTION_CANCEL را به view ی می فرستد که پیشتر (سابقاً) رویدادهای touch را دریافت کرده بود .
به منظور واکنش نشان دادن به رویدادهای touch در activity, یک OnTouchListener ویژه ی View های مربوطه ثبت کنید .

رخداد single touch

اگر تنها یک ورودی مورد استفاده قرار گرفت, در آن صورت می توانید توابع getY () و getX () را جهت دریافت موقعیت فعلی انگشت بکار ببرید . از طریق متد getAction() می توان عملیاتی که پیاده یا انجام شده را دریافت کرد . کلاس MotionEvent با ارائه ی ثابت (constant) های ذیل نوع عملیات (action) اجراشده را شناسایی یا تعیین می کند .

جدول 1. رخدادهای touch


رخداد
توصیف
MotionEvent.ACTION_DOWN
Touch جدیدی آغاز گردیده
MotionEvent.ACTION_MOVE
انگشت در حال حرکت می باشد
MotionEvent.ACTION_UP
انگشت به سمت بالا حرکت کرد
MotionEvent.ACTION_CANCEL
رویداد جاری لغو شده و چیز دیگری کنترل رخداد مربوط به لمس را به دست گرفته است
MotionEvent.ACTION_POINTER_DOWN
Pointer down (multi-touch) / اشاره گر پایین است
MotionEvent.ACTION_POINTER_UP
Pointer up (multi-touch) / اشاره گر بالا است

رخداد multi touch

قابلیت لمس چند قسمت از صفحه نمایش از ویرایش 2.0 در اندروید کاربردی شده و در نسخه ی 2.2 این سیستم عامل بهبود یافت . MotionEvent.ACTION_POINTER_DOWN و MotionEvent.ACTION_POINTER_UP به محض تماس انگشت دوم با صفحه نمایش فرستاده می شوند . ویژه ی تماس اولین انگشت که با صفحه نمایش برخورد می کند, رخدادهای MotionEvent.ACTION_DOWN و MotionEvent.ACTION_UP بکار برده می شوند .
تابع getPointerCount() در کلاس MotionEvent به برنامه نویس این امکان را می دهد که از تعداد انگشت های در حال تماس با صفحه نمایش آگاهی پیدا کند . تمامی رخدادها و موقعیت های اشاره گر ها در نمونه (instance) ی کلاس MotionEvent مشمول هستند که برنامه نویس در متد onTouch() آن ها را دریافت می کند .
به منظور ردیابی رخدادهای touch از چندین اشاره گر شما باید از توابع MotionEvent.getActionIndex() و MotionEvent.getActionMasked() جهت شناسایی شاخص اشاره گر و رویدادی که برای این اشاره گر رخ داده بهره بگیرید .
Pointer index (شاخص اشاره گر) فوق ممکن است در طول زمان تغییر کند, برای مثال زمانی که یک انگشت از سطح صفحه نمایش برداشته می شود. نوع پایای یک اشاره گر در واقع pointer id است که توسط متد getPointerId(pointerIndex) مشتق از شئ MotionEvent مشخص می شود . استفاده از آن در تکه کد زیر نمایش داده شده :

   
@Override
public boolean onTouchEvent(MotionEvent event) {
 
    // get pointer index from the event object
    int pointerIndex = event.getActionIndex();
 
    // get pointer ID
    int pointerId = event.getPointerId(pointerIndex);
 
    // get masked (not specific to a pointer) action
    int maskedAction = event.getActionMasked();
 
    switch (maskedAction) {
 
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_POINTER_DOWN: {
      // TODO use data
      break;
    }
    case MotionEvent.ACTION_MOVE: { // a pointer was moved
      // TODO use data
      break;
    }
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_POINTER_UP:
    case MotionEvent.ACTION_CANCEL: {
      // TODO use data
      break;
    }
    }
    invalidate();
 
    return true;
}               
                 
مدیریت رویداد touch در اندروید نکته:

استفاده از امکان Multitouch در شبیه ساز ممکن نیست . برای این منظور باید از یک دستگاه اندروید به عنوان وسیله ی که ورودی دریافت می کند (input device) بهره جست .

آموزش کلاس GestureDetector

اندروید با ارائه ی کلاس GestureDetector امکان استفاده از MotionEvents و ایجاد رخدادهای مربوط به حرکات و gesture های پیشرفته تر و تخصیص گوش فراخوان ویژه آن ها را برای برنامه نویس فراهم می کند .
به طور مثال کلاس ScaleGestureDetector قابلیت مشخص کردن حرکت از پیش تعریف شده ی بزرگنمایی و کوچک نمایی شئ به وسیله ی دو انگشت را فراهم می کند .

 مدیریت رخدادهای تک لمسی و چند لمسی در اندروید تمرین : مثالی از Singletouch

ترسیم با استفاده از قابلیت لمس

Singletouch را با یک View سفارشی نمایش می دهیم.
برای این منظور پروژه ی com.vogella.android.touch.single را ایجاد کرده و activity آن را SingleTouchActivity را نام گذاری کنید . حال کلاس SingleTouchEventView را مشابه زیر ایجاد کنید . کلاس مذکور View (نمایی) را پیاده سازی می کند که از قابلیت singletouch پشتیبانی می کند .

 
package de.vogella.android.touch.single;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
 
public class SingleTouchEventView extends View {
  private Paint paint = new Paint();
  private Path path = new Path();
 
  public SingleTouchEventView(Context context, AttributeSet attrs) {
    super(context, attrs);
 
    paint.setAntiAlias(true);
    paint.setStrokeWidth(6f);
    paint.setColor(Color.BLACK);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
  }
 
  @Override
  protected void onDraw(Canvas canvas) {
    canvas.drawPath(path, paint);
  }
 
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    float eventX = event.getX();
    float eventY = event.getY();
 
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
      path.moveTo(eventX, eventY);
      return true;
    case MotionEvent.ACTION_MOVE:
      path.lineTo(eventX, eventY);
      break;
    case MotionEvent.ACTION_UP:
      // nothing to do
      break;
    default:
      return false;
    }
 
    // Schedules a repaint.
    invalidate();
    return true;
  }
} 
               
                 

اکنون View ایجاد شده را به activity خود اضافه کنید .

     
package de.vogella.android.touch.single;
 
import android.app.Activity;
import android.os.Bundle;
 
public class SingleTouchActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new SingleTouchEventView(this, null));
  }
}          
                

در صورت اجرای برنامه متوجه خواهی شد که می توان با استفاده از یک انگشت روی صفحه نمایش دستگاه نقاشی کرد (یا در محیط شبیه ساز با استفاده از موس ترسیم را انجام داد) .
کدنویسی خود را گونه ای اصلاح کنید که بتوانید طرح کلی (layout) خود را بر اساس XML تعریف کنید . به منظور استفاده از view خود در تعریف طرح کلی مبتنی بر XML, باید حتماً از کل اسم کلاس (منظور اسم کلاس که دربردارنده ی اطلاعات پکیج باشد) استفاد کنید .

Tracking (ردیابی)

کدی به نمونه ترسیم خود اضافه کنید که موقعیت جاری انگشت را توسط یک دایره نشان دهد . به منظور ترسیم یک دایره شما می توانید تابع addCircle(x, y, 50, Path.Direction.CW) را روی یک Path فراخوانی کرده یا المان canvas را به طور مستقیم بکار ببرید .
مطمئن شوید که فقط موقعیت فعلی با استفاده از دایره برجسته (هایلات) می شود . دایره ی مورد نظر باید به محض اینکه انگشت پایین رفته و با صفحه تماس برقرار کرده نمایش داده شود و به مجرد بالا رفتن انگشت و قطع تماس آن با صفحه ناپدید شود .

مدیریت رویداد touch در اندروید

مدیریت رخدادهای تک لمسی و چند لمسی در اندرویدتمرین ایجاد view با قابلیت multitouch

در این تمرین به ساخت view ی می پردازیم که قابلیت پشتیبانی از تماس چندین انگشت با نما یا صفحه نمایش را داشته باشد, همچنین امکان ردیابی آن ها را برای کاربر فراهم بیاورد. بر روی شبیه ساز باید singletouch را با استفاده از موس شبیه سازی کنید .
پروژه ی اندرویدی به نام com.vogella.android.multitouch ایجاد کرده, سپس به ساخت activity پروژه به نام MainActivity بپردازید .
کلاس MultitouchView را مشابه مثال زیر ایجاد کنید .

package com.vogella.android.multitouch;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.MotionEvent;
import android.view.View;
 
public class MultitouchView extends View {
 
  private static final int SIZE = 60;
 
  private SparseArray mActivePointers;
  private Paint mPaint;
  private int[] colors = { Color.BLUE, Color.GREEN, Color.MAGENTA,
      Color.BLACK, Color.CYAN, Color.GRAY, Color.RED, Color.DKGRAY,
      Color.LTGRAY, Color.YELLOW };
 
  private Paint textPaint;
 
 
  public MultitouchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView();
  }
 
  private void initView() {
    mActivePointers = new SparseArray();
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    // set painter color to a color you like
    mPaint.setColor(Color.BLUE);
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    textPaint.setTextSize(20);
  }
 
  @Override
  public boolean onTouchEvent(MotionEvent event) {
 
    // get pointer index from the event object
    int pointerIndex = event.getActionIndex();
 
    // get pointer ID
    int pointerId = event.getPointerId(pointerIndex);
 
    // get masked (not specific to a pointer) action
    int maskedAction = event.getActionMasked();
 
    switch (maskedAction) {
 
    case MotionEvent.ACTION_DOWN:
    case MotionEvent.ACTION_POINTER_DOWN: {
      // We have a new pointer. Lets add it to the list of pointers
 
      PointF f = new PointF();
      f.x = event.getX(pointerIndex);
      f.y = event.getY(pointerIndex);
      mActivePointers.put(pointerId, f);
      break;
    }
    case MotionEvent.ACTION_MOVE: { // a pointer was moved
      for (int size = event.getPointerCount(), i = 0; i < size; i++) {
        PointF point = mActivePointers.get(event.getPointerId(i));
        if (point != null) {
          point.x = event.getX(i);
          point.y = event.getY(i);
        }
      }
      break;
    }
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_POINTER_UP:
    case MotionEvent.ACTION_CANCEL: {
      mActivePointers.remove(pointerId);
      break;
    }
    }
    invalidate();
 
    return true;
  }
 
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
 
    // draw all pointers
    for (int size = mActivePointers.size(), i = 0; i < size; i++) {
      PointF point = mActivePointers.valueAt(i);
      if (point != null)
        mPaint.setColor(colors[i % 9]);
      canvas.drawCircle(point.x, point.y, SIZE, mPaint);
    }
    canvas.drawText("Total pointers: " + mActivePointers.size(), 10, 40 , textPaint);
  }
 
} 

حال این view را به activity خود اضافه کنید .



       

                 
RelativeLayout> 

Activity تولید شده می تواند به همان شکل خود باقی بماند .

package com.vogella.android.multitouch;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
 
public class MainActivity extends Activity {
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
 
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
  }
 
} 

پس از اجرای برنامه خواهی دید که می توان با انگشت خود روی صفحه نمایش ترسیم انجام داد . البته لازم است بررسی کنید دستگاه مربوطه از چه تعداد اشاره گر بر روی صفحه نمایش به طور همزمان پشتیبانی می کند .

Multitouch تمرین

مدیریت رخدادهای تک لمسی و چند لمسی در اندرویدآموزش : ایجاد activity (ScaleGestureDetector)

پروژه ی جدیدی ایجاد کرده و نام آن را de.vogella.android.touch.scaledetector انتخاب کنید, سپس یک activity ویژه ی پروژه ی مزبور به نام ScaleDetectorTestActivity ایجاد کنید .
اکنون کلاسی درست مشابه نمونه ی زیر ایجاد کنید .

package de.vogella.android.touch.scaledetector;
 
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
 
public class ImageViewWithZoom extends View {
  private Drawable image;
  private float scaleFactor = 1.0f;
  private ScaleGestureDetector scaleGestureDetector;
 
  public ImageViewWithZoom(Context context) {
    super(context);
    image = context.getResources().getDrawable(R.drawable.icon);
    setFocusable(true);
    image.setBounds(0, 0, image.getIntrinsicWidth(),
        image.getIntrinsicHeight());
    scaleGestureDetector = new ScaleGestureDetector(context,
        new ScaleListener());
  }
 
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // Set the image bounderies
    canvas.save();
    canvas.scale(scaleFactor, scaleFactor);
    image.draw(canvas);
    canvas.restore();
  }
 
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    scaleGestureDetector.onTouchEvent(event);
    invalidate();
    return true;
  }
 
  private class ScaleListener extends
      ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {
      scaleFactor *= detector.getScaleFactor();
 
      // don't let the object get too small or too large.
      scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f));
 
      invalidate();
      return true;
    }
  }
} 

این View را به activity نام برده اضافه کنید .

package de.vogella.android.touch.scaledetector;
 
import android.app.Activity;
import android.os.Bundle;
 
public class ScaleDetectorTestActivity extends Activity {
  
/** Called when the activity is first created. */
 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new ImageViewWithZoom(this));
  }
} 

پس از اجرای برنامه خواهی دید که می توان با استفاده از دو انگشت به طور همزمان (حرکت / multitouch) تصویر را بزرگ و کوچک کنید .

1394/08/07 7111 3039
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...