è©Šäœ
ã¿ããã¹ã¯ãªãŒã³ããã«ãã¿ãããããã³ãžã§ã¹ãã£ã䜿çšããäŸã«ã€ããŠã¯ãåçŽãªã°ã©ãã£ãã¯ãšãã£ã¿ãŒãå®è£ ããããšã«ããŸããã ç§ãã¡ã®ã°ã©ãã£ãã¯ãšãã£ã¿ãŒã¯ã©ãããã¹ãã§ããïŒ æãåºããŠæãè¿ã¥ããè·é¢ãå€æŽã§ããå°ããªã©ã°ã®ãã£ã³ãã¹ã ãŸãããã£ã³ãã¹ã®ãã©ãã°ãšæç»ãæ··åããªãããã«ãé·ãã¿ããã®ããã«ã¢ãŒãã®å€æŽãå®è£ ããå¿ èŠããããŸãã ããã«ã¯ãªãã¯ãããšãè²éžæãŠã£ã³ããŠã衚瀺ã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ããŒã¹
éå§ããã«ã¯ãEclipseã§Androidã¢ããªã±ãŒã·ã§ã³ãããžã§ã¯ããäœæããŸãã ãã®ãããžã§ã¯ãã§ã¯ãæ°ããSDKã®æ©èœã䜿çšããªããããããšãã°ãAPI 8 ïŒAndroid 2.2ïŒãMinimum Required SDKãšããŠã€ã³ã¹ããŒã«ã§ããŸãã MainActivity ïŒååšããªãå Žåã¯äœæããå¿ èŠããããŸãïŒãã®ãã©ãŒã ã«ããããããããŸãïŒ
import android.os.Bundle; import android.app.Activity; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new ApplicationView(this)); } }
ãããã£ãŠãViewãç¶æ¿ããApplicationViewã¯ã©ã¹ãäœæããå¿ èŠããããŸãã
import android.view.View; import android.content.Context; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Canvas; public class ApplicationView extends View { Paint paint = new Paint(); // , static float density; public ApplicationView(Context context) { super(context); density = getResources().getDisplayMetrics().density; this.setBackgroundColor(Color.GRAY); // paint.setStrokeWidth(5*density); // 5dp } @Override protected void onDraw(Canvas canvas) { } }
次ã«ããã£ã³ãã¹ã®è¡šç€ºæ¹æ³ãç解ããå¿ èŠããããŸãã ãã£ã³ãã¹ãäœæããã«ã¯ãããããããããããªãã·ã§ã³ã«æž¡ããŸãã ãã®å Žåããã£ã³ãã¹ã«äœããæç»ãããšãããããããã«è¡šç€ºãããŸãã ãŸãããã£ã³ãã¹ã®å¯å€äœçœ®ãšãã£ã³ãã¹ãŸã§ã®è·é¢ãå¿ èŠã§ãã ApplicationViewã¯ã©ã¹ã«ããã€ãã®å€æ°ãè¿œå ããŸãã
Canvas canvas; // Bitmap image; // float zoom = 500; // Point position = new Point(50, 50); //
ã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã§ããã£ã³ãã¹ãšãã®ã³ã³ãã³ããåæåããçœè²ã§ãã€ã³ãããŸãã
image = Bitmap.createBitmap(500, 500, Config.ARGB_4444); // canvas = new Canvas(image); // canvas.drawColor(Color.WHITE); //
onDrawã¡ãœããã§è¡šç€ºããŸãïŒ
canvas.translate(position.x, position.y); // canvas.scale(zoom / 500, zoom / 500); // canvas.drawBitmap(image, 0, 0, paint); //
ããã§ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãç°è²ã®èæ¯ã«çœãæ£æ¹åœ¢ã衚瀺ãããŸãã
è¯ããã
å
šç»é¢è¡šç€ºã«ãã暪åããè¿œå ããããšã§ãã¢ããªã±ãŒã·ã§ã³ãæ¹åã§ããŸãã ãããè¡ãã«ã¯ãã¢ã¯ãã£ããã£ã®ãã©ã¡ãŒã¿ãŒãå€æŽããå¿
èŠããããŸãã
ãŸãããã«ã¹ã¯ãªãŒã³ã®å Žåã¯ãã¹ã¿ã€ã«ãã¡ã€ã«ãå€æŽããŸãã API 10以äžïŒå€/ styles.xmlïŒã®å Žå ïŒ
API 11以äžïŒvalues-v11 / styles.xmlïŒã®å Žå ïŒ
API 14 ïŒå€/ styles-v14.xmlïŒã®å Žå ïŒ
<activity android:name=".MainActivity" android:label="@string/title_activity_main" android:screenOrientation="landscape">
ãŸãããã«ã¹ã¯ãªãŒã³ã®å Žåã¯ãã¹ã¿ã€ã«ãã¡ã€ã«ãå€æŽããŸãã API 10以äžïŒå€/ styles.xmlïŒã®å Žå ïŒ
<resources> <style name="AppTheme" parent="android:Theme.Light.NoTitleBar.Fullscreen" /> </resources>
API 11以äžïŒvalues-v11 / styles.xmlïŒã®å Žå ïŒ
<resources> <style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen" /> </resources>
API 14 ïŒå€/ styles-v14.xmlïŒã®å Žå ïŒ
<resources> <style name="AppTheme" parent="android:Theme.DeviceDefault.Light.NoActionBar.Fullscreen" /> </resources>
ã¿ããã¹ã¯ãªãŒã³ã§ã®ä»äºã®å®çŸ
onTouchEventã¡ãœããããªãŒããŒã©ã€ãããŠãã¿ããã¹ã¯ãªãŒã³ãšã®å¯Ÿè©±ãéå§ããå¿ èŠããããŸãïŒã¿ããã¹ã¯ãªãŒã³ã®æäœã®è©³çŽ°ã«ã€ããŠã¯ã ãã¡ããã芧ãã ãã ïŒ ã
ArrayList<Finger> fingers = new ArrayList<Finger>(); // , @Override public boolean onTouchEvent(MotionEvent event) { int id = event.getPointerId(event.getActionIndex()); // int action = event.getActionMasked(); // if(action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) fingers.add(event.getActionIndex(), new Finger(id, (int)event.getX(), (int)event.getY())); else if(action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP) fingers.remove(fingers.get(event.getActionIndex())); // , else if(action == MotionEvent.ACTION_MOVE){ for(int n = 0; n < fingers.size(); n++){ // fingers.get(n).setNow((int)event.getX(n), (int)event.getY(n)); } //checkGestures(); invalidate(); } return true; }
æãã¿ãããããšãFingerã¿ã€ãã®ãªããžã§ã¯ããæã®ãªã¹ãã«è¿œå ãããŸãã æãæã¡äžãããšããã®ãªããžã§ã¯ããåé€ãããæã移åãããšããã¹ãŠã®ãªããžã§ã¯ãã®åº§æšãæŽæ°ãããŸãã ãã®çµæãæã®ãªã¹ãã«ã¯ãçŸåšããã³ä»¥åã®åº§æšãšã®ãã¹ãŠã®ã¿ãããå«ãŸããŸãã æã®ã¯ã©ã¹ïŒ
import android.graphics.Point; public class Finger { public int ID; // public Point Now; public Point Before; boolean enabled = false; // public Finger(int id, int x, int y){ ID = id; Now = Before = new Point(x, y); } public void setNow(int x, int y){ if(!enabled){ enabled = true; Now = Before = new Point(x, y); }else{ Before = Now; Now = new Point(x, y); } } }
æ€èšŒ
ç°¡åãªæäœã§ãã¹ãŠã®ã¿ããã衚瀺ã§ããŸãã ãããè¡ãã«ã¯ãonDrawã¡ãœããã§æ¬¡ã®ããã«å
¥åããŸãã
canvas.restore(); // for(int i = 0; i < fingers.size(); i++){ // canvas.drawCircle(fingers.get(i).Now.x, fingers.get(i).Now.y, 40 * density, paint); }
移åãã£ã³ãã¹
ãã£ã³ãã¹ã®ç§»åãå®è£ ããã«ã¯ããªããžã§ã¯ãã®ç§»åãããã¯ã§onTouchEventã¡ãœããã®checkGesturesã¡ãœãããåŒã³åºãå¿ èŠããããŸããããã¯ã¿ããã§æ©èœããŸãã ãã ãããã®ã¡ãœããã®åŒã³åºãã¯æ¢ã«ã³ã¡ã³ãã®äžã«ãããŸãã ã³ã¡ã³ããå€ããã¡ãœããèªäœãèšè¿°ããŸãã
public void checkGestures(){ Finger point = fingers.get(0); // position.x += point.Now.x - point.Before.x; // position.y += point.Now.y - point.Before.y; }
æãéå§ããŠç§»åã§ããŸãããã¹ãŠãæ£ããå®äºãããããã£ã³ãã¹ããã®åŸãã«ãã©ãã°ããå¿ èŠããããŸãã
ãã£ã³ãã¹ãŸã§ã®è·é¢ãå€æŽãã
ãã®ãžã§ã¹ãã£ãŒãå®è£ ããã«ã¯ãã¡ãœããã®ã³ã³ãã³ãå šäœããã«ãã¿ããïŒè€æ°ã®æãããå ŽåïŒãšéåžžã®ã¿ããã«åé¢ããå¿ èŠããããŸãã ããããã«ãã¿ããã®å Žåã2æ¬ã®æãšéå»ã®çŸåšã®è·é¢ãåžžã«ãã§ãã¯ããŸãã checkGesturesã¡ãœããã®å 容ãå€æŽããŸãã
Finger point = fingers.get(0); if(fingers.size() > 1){ // Multitouch // (now) (before) float now = checkDistance(point.Now, fingers.get(1).Now); float before = checkDistance(point.Before, fingers.get(1).Before); float oldSize = zoom; // zoom = Math.max(now - before + zoom, density * 25); // position.x -= (zoom - oldSize) / 2; // position.y -= (zoom - oldSize) / 2; }else{ // position.x += point.Now.x - point.Before.x; position.y += point.Now.y - point.Before.y; }
ãã®ã³ãŒãã»ã¯ã·ã§ã³ã§ã¯ãcheckDistanceã¡ãœããã䜿çšãããŸãããããã¯ApplicationViewã«è¿œå ããå¿ èŠããããŸãã 圌ã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
static float checkDistance(Point p1, Point p2){ // return FloatMath.sqrt((p1.x - p2.x)*(p1.x - p2.x)+(p1.y - p2.y)*(p1.y - p2.y)); }
ããã§ã2æ¬ã®æã«è§ŠããŠæ··å/ç¹æ®ããããšããã£ã³ãã¹ãŸã§ã®è·é¢ãå€ãããŸãã ãšãã¥ã¬ãŒã¿ã䜿çšããŠããå Žåãäœãæ©èœããŸããã
ã¢ãŒãå€æŽ
ã¢ãŒããæ åœããå€æ°ãäœæããå¿ èŠããããŸãã booleanåã®drawingModeãšåŒã³ãŸãã ãã³ã°ã¿ãããå®è£ ããã«ã¯ããã°ããããŠããåŒã³åºãããã¡ãœããã䜿çšããå¿ èŠããããŸãã ããã€ãã®ã·ããªãªããããŸãã
- onDrawã¡ãœããã§ã³ãŒããèšè¿°ããŸãã
- onTouchEventã«ã³ãŒããèšè¿°ããŸãã
- ã¿ã€ããŒãäœæãããã®äžã«ã³ãŒããèšè¿°ããŸãã
- ãã³ãã©ãŒãäœæããpostDelayedã¡ãœããã䜿çšããŠRunnableãåŒã³åºããŸãã
ç§ã®æèŠã§ã¯ãonDrawã¡ãœããã§ã¯ãã°ã©ãã£ãã¯ã¹ã®ã¿ã衚瀺ããå¿ èŠããããŸãã onTouchEventã«æžã蟌ãããšãã§ããã®ã¯ãæã移åãããšããäºå®ã®ã¿ãèæ ®ããŠãåžžã«ãã®ã¡ãœãããåŒã³åºãããšã§ãã ã¿ã€ããŒã¯åžžã«æ©èœããããã¯å°ãé¢åãªã®ã§ã4çªç®ã®ãªãã·ã§ã³ã䜿çšããŸãã ApplicationViewã¯ã©ã¹ã§ãHandlerã¿ã€ãã®ãã³ãã©ãŒå€æ°ãäœæããifã«è¡ãè¿œå ããŸãïŒaction == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWNãããã¯ïŒ
handler.postDelayed(longPress, 1000);
ããã§ãlongPressãšããååã®Runnableãäœæããå¿ èŠããããŸãã
Runnable longPress = new Runnable() { public void run() { } };
ããã§ãFingerã¯ã©ã¹ã§ã¯ãæŒãæéãå«ãlongåã®wasDownå€æ°ãäœæããå¿ èŠããããŸãïŒããã«ã¿ããã«äŸ¿å©ã§ãïŒ ã ãã®å€æ°ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ãSystem.currentTimeMillisïŒïŒã®å€ãèšå®ããå¿ èŠããããŸãã ãŸããPointåã®startPointå€æ°ãè¿œå ããå¿ èŠããããŸããããã«ã¯ãæã®éå§äœçœ®ãå«ãŸããŸãã ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããå€ããŸãã¯setNowãæåã«åŒã³åºããããšãã®å€ãå«ããå¿ èŠããããŸãã ãŸããå®è£ ããã€ãã³ãã«å¯Ÿãããã®ã¿ããã®é©åæ§ã衚瀺ããããŒã«åã®enabledLongTouchå€æ°ãäœæããå¿ èŠããããŸãã æãæåããåããããŠãããã©ãããåžžã«ç¢ºèªããå¿ èŠããããŸãã ãã®æ©èœã¯setNowã§å®è£ ã§ããŸãã çµæã¯æ¬¡ã®ããã«ãªããŸãã
import android.graphics.Point; public class Finger { public int ID; public Point Now; public Point Before; public long wasDown; boolean enabled = false; public boolean enabledLongTouch = true; Point startPoint; public Finger(int id, int x, int y){ wasDown = System.currentTimeMillis(); ID = id; Now = Before = startPoint = new Point(x, y); } public void setNow(int x, int y){ if(!enabled){ enabled = true; Now = Before = startPoint = new Point(x, y); }else{ Before = Now; Now = new Point(x, y); if(ApplicationView.checkDistance(Now, startPoint) > ApplicationView.density * 25) enabledLongTouch = false; } } }
Runnableã®runã¡ãœããã§ããã®ã¿ãããé·æéç¶ããã©ããã確èªã§ããŸãã
if(fingers.size() > 0 && fingers.get(0).enabledLongTouch){ fingers.get(0).enabledLongTouch = false; drawingMode = !drawingMode; vibrator.vibrate(80); }
è¯ããã
é·ãã¿ãããããè¯ãããããã«ã¯ãã¢ã¯ãã£ãã«ãªã£ããšãã«ããããªæ¯åããªã³ã«ããå¿
èŠããããŸãã ãããè¡ãã«ã¯ãåã«ãã€ãã¬ãŒã¿ã¿ã€ãã®ãã€ãã¬ãŒã¿å€æ°ãäœæãã次ã®ããã«ã³ã³ã¹ãã©ã¯ã¿ã§ãã®å€ãèšå®ããŸãã
éèŠïŒãããã§ã¹ãã§æ¯åãåŠçããã«ã¯ã次ã®è¡ãå¿ èŠã§ãã
次ã«ãã¿ã€ããŒã®runã¡ãœããã§ããã³ã°ã¿ãããã¹ãã®æåŸã«ã次ã®ããã«å ¥åã§ããŸãã
vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
éèŠïŒãããã§ã¹ãã§æ¯åãåŠçããã«ã¯ã次ã®è¡ãå¿ èŠã§ãã
<uses-permission android:name="android.permission.VIBRATE"/>
次ã«ãã¿ã€ããŒã®runã¡ãœããã§ããã³ã°ã¿ãããã¹ãã®æåŸã«ã次ã®ããã«å ¥åã§ããŸãã
vibrator.vibrate(80);
æç»
çŸåšããã£ã³ãã¹ã«ãã€ã³ããå®è£ ãããã©ã·ã®ãµã€ãºãå€æŽããŠããŸãã ãããè¡ãã«ã¯ãcheckGesturesã¡ãœããã®åéšåããæç»ã¢ãŒããšéåžžã¢ãŒãã®2ã€ã®éšåã«åå²ããŸãã ã¿ãããããšãã®æç»ã¢ãŒãã§ã¯ãç·ãæãã ãã§ããã«ãã¿ããã®æç»ã¢ãŒãã§ã¯ããã©ã·ã®ãµã€ãºãå€æŽããŸãã ããã¯ãcheckGesturesã¡ãœãããã©ã®ããã«ãªããã瀺ããŠããŸãã
Finger finger = fingers.get(0); if(fingers.size() > 1){ float now = checkDistance(finger.Now, fingers.get(1).Now); float before = checkDistance(finger.Before, fingers.get(1).Before); if(!drawingMode){ float oldSize = zoom; zoom = Math.max(now - before + zoom, density * 25); position.x -= (zoom - oldSize) / 2; position.y -= (zoom - oldSize) / 2; }else paint.setStrokeWidth(paint.getStrokeWidth() + (now - before) / 8); }else{ if(!drawingMode){ position.x += finger.Now.x - finger.Before.x; position.y += finger.Now.y - finger.Before.y; }else{ float x1 = (finger.Before.x-position.x)*500/zoom; // float x2 = (finger.Now.x-position.x)*500/zoom; // float y1 = (finger.Before.y-position.y)*500/zoom; // float y2 = (finger.Now.y-position.y)*500/zoom; canvas.drawLine(x1, y1, x2, y2, paint); // canvas.drawCircle(x1, y1, paint.getStrokeWidth() / 2, paint); // canvas.drawCircle(x2, y2, paint.getStrokeWidth() / 2, paint); cursor = finger.Now; } }
æåŸã®è¡ã§ã¯ãå€ã1ã€ã®ã«ãŒãœã«ã«èšå®ããŸããã ããã¯ãã«ãŒãœã«ã®åº§æšãå«ãPointåã®å€æ°ã§ãã ã«ãŒãœã«ã¯ããã©ã·ã®ãµã€ãºã§ããã²ãŒãããããã«ã®ã¿å¿ èŠã§ãã onDrawã¡ãœããã§ã«ãŒãœã«ã衚瀺ããã«ã¯ã次ãè¿œå ããŸãã
if(drawingMode){ int old = paint.getColor(); // paint.setColor(Color.GRAY); // canvas.drawCircle((cursor.x-position.x)*500/zoom, (cursor.y-position.y)*500/zoom, paint.getStrokeWidth() / 2, paint); // paint.setColor(old); // }
ããã§ããã£ã³ãã¹ã®ç§»åããºãŒã ã€ã³ããºãŒã ã¢ãŠããæç»ã¢ãŒããžã®åãæ¿ããæç»ããã©ã·ã®ãµã€ãºå€æŽãã§ããŸãã è²ã®éžæãå®çŸããããã ãã«æ®ã£ãŠããŸãã
ã«ã©ãŒããã«ãŒ
è²ãéžæããã«ã¯ãç»é¢ãããã«ã¿ããããŸãã ãããè¡ãã«ã¯ãç»é¢äžã®æåŸã®ã¿ãããä¿æããApplicationViewã®å€æ°ãšããã®ã¿ããã®åº§æšãä¿æããå€æ°ãäœæããå¿ èŠããããŸãã æåã®ãã®ã¯longåã®lastTapTimeãšåŒã°ãã2çªç®ã¯Pointåã®lastTapPositionãšåŒã°ããŸãã 次ã«ãonTouchEventã¡ãœãããå€æŽããŸãã
int id = event.getPointerId(event.getActionIndex()); int action = event.getActionMasked(); if(action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) fingers.add(event.getActionIndex(), new Finger(id, (int)event.getX(), (int)event.getY())); else if(action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_POINTER_UP){ Finger finger = fingers.get(event.getActionIndex()); // // 100, 200, // 25dp if(System.currentTimeMillis() - finger.wasDown < 100 && finger.wasDown - lastTapTime < 200 && finger.wasDown - lastTapTime > 0 && checkDistance(finger.Now, lastTapPosition) < density * 25){ // } lastTapTime = System.currentTimeMillis(); // lastTapPosition = finger.Now; // fingers.remove(fingers.get(event.getActionIndex())); }else if(action == MotionEvent.ACTION_MOVE){ for(int n = 0; n < fingers.size(); n++){ fingers.get(n).setNow((int)event.getX(n), (int)event.getY(n)); } checkGestures(); } return true;
æ®ã£ãŠããã®ã¯ãè²éžæãã€ã¢ãã°ãå®è£ ããããšã ãã§ãã ã¿ããïŒã³ã¡ã³ãã®ããŒã¯ïŒãããå Žåã次ã®ããã«èšè¿°ããŸãã
Builder builder = new AlertDialog.Builder(getContext()); String[] items = {"", "", "", "", "", "", "", ""}; final AlertDialog dialog = builder.setTitle(" ").setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { int[] colors = {Color.RED, Color.GREEN, Color.BLUE, 0xFF99CCFF, Color.BLACK, Color.WHITE, Color.YELLOW, 0xFFFFCC99}; paint.setColor(colors[which]); } }).create(); dialog.show();
ã¢ããªã±ãŒã·ã§ã³ãå®è¡ãããšãè²éžæãŠã£ã³ããŠãããã«ã¯ãªãã¯ããŠè¡šç€ºãããããšãããããŸãã
ãããã«
ã«ã¹ã¿ã ãžã§ã¹ãã£ãèªèããããšã¯ããã»ã©é£ãããããŸããã§ããã ã°ã©ãã£ã«ã«ãšãã£ã¿ãŒã®äŸã䜿çšããŠãããåæããŸããã ãã¡ãããã¢ããªã±ãŒã·ã§ã³ã ãã§ãªããã²ãŒã ãåæ§ã®å®è£ ãææã§ããŸãã
ãããžã§ã¯ãã®ãœãŒã¹ã³ãŒãã¯ãã¡ãã§ãã
developer.android.comããã®æ å ±ã䜿çšããŸãã ã æåã«ãã®èšäºã䜿çšããŸãã ã
AndreyMI ã LeoCcoder ã silentnuke ã vovkabã®ãŠãŒã¶ãŒã«ãæè¬ããŸãã