рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╢рд╛рд░рд╛ рдкрд╣рдЪрд╛рди

рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреЗрдо рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдореИрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛ред рдорд╛рдирдХ Android SDK рдореЗрдВ GestureDetector рд╡рд░реНрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИ ( рдпрд╣рд╛рдВ рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдкреНрд░рджрд░реНрд╢рди рд╣реИ) , рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдЙрди рд╕рднреА рдЗрд╢рд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдирдХреА рдореБрдЭреЗ рдЬрд╝рд░реВрд░рдд рдереА, рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдиреЗ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬреИрд╕рд╛ рдХрд┐ рдореБрдЭреЗ рдЬрд╝рд░реВрд░рдд рдереА (onLongPress, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рди рдХреЗрд╡рд▓ рдХрд╛рдо рдХрд┐рдпрд╛ рдПрдХ рд▓рдВрдмреЗ рд╕реНрдкрд░реНрд╢ рд╕реЗ, рд▓реЗрдХрд┐рди рд╕реНрдХреНрд░реАрди рдкрд░ рдЙрдВрдЧрд▓реА рд╕реЗ рд▓рдВрдмреЗ рд╕реНрдкрд░реНрд╢ рд╕реЗ рднреА) ред рдЧреЗрдо рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬреЗрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд╛рдзрд╛рд░рдг рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╡реЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рдХреБрдЫ рддрддреНрд╡реЛрдВ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдпрд╣ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдЯрдЪ рдЗрдирдкреБрдЯ рд╡рд╛рд▓реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЗрд╕реНрдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рд╣рдореЗрдВ рдпрд╣ рдорд╛рдирдиреЗ рдХрд╛ рдЕрдзрд┐рдХрд╛рд░ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрдирд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИред рдЖрдЬ рд╣рдо рдЕрдкрдиреЗ рдЖрд╡реЗрджрди рдореЗрдВ рд▓реЙрдиреНрдЧ рдкреНрд░реЗрд╕ , рдбрдмрд▓ рдЯрдЪ , рдкрд┐рдВрдЪ рдУрдкрди , рдкрд┐рдВрдЪ рдХреНрд▓реЛрдЬрд╝ рдФрд░ рдЕрдиреНрдп рдХреА рдорд╛рдиреНрдпрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред

рд╣реЗрд▓реЛ, рд╣реЗрдмреНрд░!

рдкреВрд░реНрд╡ рдЙрддреНрдкрд╛рджрди


рдПрдХ рдЯрдЪ рд╕реНрдХреНрд░реАрди, рдорд▓реНрдЯреАрдЯрдЪ рдФрд░ рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЧреНрд░рд╛рдлрд┐рдХ рд╕рдВрдкрд╛рджрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╣рдорд╛рд░рд╛ рдЧреНрд░рд╛рдлрд┐рдХ рдПрдбрд┐рдЯрд░ рдХреНрдпрд╛ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП? рдПрдХ рдЫреЛрдЯрд╛ рд▓реИрдЧрд┐рдВрдЧ рдХреИрдирд╡рд╕, рдЬрд┐рд╕рд╕реЗ рджреВрд░реА рдХреЛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрдВрдЧрд▓рд┐рдпреЛрдВ рдХреЛ рдлреИрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдПрдХ рд╕рд╛рде рд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреИрдирд╡рд╛рд╕ рдХреЛ рдЦреАрдВрдЪрдиреЗ рдФрд░ рдЙрд╕ рдкрд░ рдбреНрд░рд╛рдЗрдВрдЧ рдХреЛ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рд╣рдореЗрдВ рд▓рдВрдмреЗ рд╕реНрдкрд░реНрд╢ рдХреЗ рд▓рд┐рдП рдореЛрдб рдХреЗ рдмрджрд▓рд╛рд╡ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдбрдмрд▓-рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ, рд░рдВрдЧ рдЪрдпрди рд╡рд┐рдВрдбреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред

рдЖрд╡реЗрджрди рдЖрдзрд╛рд░


рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЧреНрд░рд╣рдг рдореЗрдВ рдПрдХ Android рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВред рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдирдП рдПрд╕рдбреАрдХреЗ рд╕реЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдЧреА, рдЗрд╕рд▓рд┐рдП рдПрдкреАрдЖрдИ 8 (рдПрдВрдбреНрд░реЙрдЗрдб 2.2) рдХреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдЖрд╡рд╢реНрдпрдХ рдПрд╕рдбреАрдХреЗ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред 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)); } } 


рддрджрдиреБрд╕рд╛рд░, рд╣рдореЗрдВ рдПрдХ ViewView рд╡рд░реНрдЧ рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рджреГрд╢реНрдп рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реЗрдЧрд╛:

 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); //     


рдСрдирдбреНрд░рд╛рдЗрд╡ рд╡рд┐рдзрд┐ рдореЗрдВ, рдЗрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ:

 canvas.translate(position.x, position.y); //   canvas.scale(zoom / 500, zoom / 500); //     canvas.drawBitmap(image, 0, 0, paint); //   


рдпрджрд┐ рд╣рдо рдЕрдкрдирд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрднреА рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдПрдХ рдЧреНрд░реЗ рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдкрд░ рдПрдХ рд╕рдлреЗрдж рд╡рд░реНрдЧ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред

рдмреЗрд╣рддрд░ рдмрдирд╛рдУ
рдЖрдк рдЗрд╕реЗ рдкреВрд░реНрдг-рд╕реНрдХреНрд░реАрди рдмрдирд╛рдХрд░ рдФрд░ рд▓реИрдВрдбрд╕реНрдХреЗрдк рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рдЬреЛрдбрд╝рдХрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛:

 <activity android:name=".MainActivity" android:label="@string/title_activity_main" android:screenOrientation="landscape"> 


рдФрд░ рдпрд╣ рднреА, рдкреВрд░реНрдг рд╕реНрдХреНрд░реАрди рдХреЗ рд▓рд┐рдП, рд╢реИрд▓реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрджрд▓реЗрдВред рдПрдкреАрдЖрдИ 10 рдФрд░ рдЙрд╕рд╕реЗ рдиреАрдЪреЗ рдХреЗ рд▓рд┐рдП (рдорд╛рди / styles.xml) :

 <resources> <style name="AppTheme" parent="android:Theme.Light.NoTitleBar.Fullscreen" /> </resources> 


рдПрдкреАрдЖрдИ 11 рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рдж рдХреЗ рд╕рдВрд╕реНрдХрд░рдг (рдорд╛рдиреЛрдВ- v11 / styles.xml) :

 <resources> <style name="AppTheme" parent="android:Theme.Holo.Light.NoActionBar.Fullscreen" /> </resources> 


рдПрдкреАрдЖрдИ 14 рдХреЗ рд▓рд┐рдП (рдорд╛рди / рд╢реИрд▓рд┐рдпрд╛рдБ- v14.xml) :

 <resources> <style name="AppTheme" parent="android:Theme.DeviceDefault.Light.NoActionBar.Fullscreen" /> </resources> 


рдЯрдЪ рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд╛ рдЕрд╣рд╕рд╛рд╕


рд╣рдореЗрдВ рдСрдирд╕реНрдХреНрд░реАрди рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдХреЗ рдЯрдЪ рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ (рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдЯрдЪ рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ ) :

 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; } 


рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЬрдм рд╣рдо рдПрдХ рдЙрдВрдЧрд▓реА рдХреЛ рдЫреВрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЙрдВрдЧрд▓реА рдХреА рд╕реВрдЪреА рдореЗрдВ рдЯрд╛рдЗрдк рдлрд┐рдВрдЧрд░ рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЬрдм рд╣рдо рдЙрдВрдЧрд▓реА рдЙрдард╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рдЙрдВрдЧрд▓рд┐рдпреЛрдВ рдХреЛ рдШреБрдорд╛рддреЗ рд╕рдордп рд╣рдо рд╕рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдирддреАрдЬрддрди, рдЙрдВрдЧрд▓рд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдФрд░ рдкрд┐рдЫрд▓реЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рд╕рд╛рде рд╕рднреА рд╕реНрдкрд░реНрд╢ рд╣реЛрддреЗ рд╣реИрдВред рдЙрдВрдЧрд▓реА рд╡рд░реНрдЧ:

 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); } } } 


рдорд╛рдиреНрдпрддрд╛
рд╣рдо рд╕рднреА рд╕реНрдкрд░реНрд╢реЛрдВ рдХреЛ рд╕рд░рд▓ рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдСрдирдбреНрд░рд╛рдЗрд╡ рд╡рд┐рдзрд┐ рдореЗрдВ, рдЗрд╕реЗ рджрд░реНрдЬ рдХрд░реЗрдВ:

 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); } 


рдЪрд▓ рд░рд╣рд╛ рдХреИрдирд╡рд╛рд╕


рдЪрд▓рддреА рд╣реБрдИ рдХреИрдирд╡рд╛рд╕ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдореВрд╡рд┐рдВрдЧ рдмреНрд▓реЙрдХ рдореЗрдВ, рдСрдирд╕реНрдХреНрд░реАрди рдореЛрдб рдореЗрдВ рдЪреЗрдХрдЧреИрд╕реНрдЯрд░реНрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЯрдЪ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдЧреАред рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреЙрд▓ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЯрд┐рдкреНрдкрдгреА рдХреЗ рддрд╣рддред рдЗрд╕реЗ рд░рджреНрдж рдХрд░реЗрдВ рдФрд░ рд╕реНрд╡рдпрдВ рд╡рд┐рдзрд┐ рд▓рд┐рдЦреЗрдВ:

 public void checkGestures(){ Finger point = fingers.get(0); //    position.x += point.Now.x - point.Before.x; //   position.y += point.Now.y - point.Before.y; } 


рдЖрдк рдЕрдкрдиреА рдЙрдВрдЧрд▓реА рдХреЛ рд╢реБрд░реВ рдФрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдЧрд░ рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреИрдирд╡рд╛рд╕ рдХреЛ рдЗрд╕рдХреЗ рдкреАрдЫреЗ рдЦреАрдВрдЪ рд▓рд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рджреВрд░реА рдХреЛ рдХреИрдирд╡рд╛рд╕ рдореЗрдВ рдмрджрд▓реЗрдВ



рдЗрд╕ рдЗрд╢рд╛рд░реЗ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╡рд┐рдзрд┐ рдХреА рд╕рдВрдкреВрд░реНрдг рд╕рд╛рдордЧреНрд░реА рдХреЛ рдорд▓реНрдЯреАрдЯрдЪ (рдЬрдм рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдЙрдВрдЧрд▓реА рд╣реЛ) рдФрд░ рд╕рд╛рдзрд╛рд░рдг рд╕реНрдкрд░реНрд╢ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдпрд╣ рдПрдХ рдорд▓реНрдЯреАрдЯрдЪ рд╣реИ, рддреЛ рд╣рдо рд▓рдЧрд╛рддрд╛рд░ рджреЛ рдЙрдВрдЧрд▓рд┐рдпреЛрдВ рдФрд░ рдЕрддреАрдд рдХреЗ рдмреАрдЪ рдХреА рд╡рд░реНрддрдорд╛рди рджреВрд░реА рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗред 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; } 


рдХреЛрдб рдХреЗ рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рдЪреЗрдХрдбрд┐рд╕реНрдЯреЗрдВрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕реЗ 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)); } 


рдЕрдм, рджреЛ рдЙрдВрдЧрд▓рд┐рдпреЛрдВ рдХреЛ рдЫреВрдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдорд┐рд▓рд╛рдиреЗ / рдкреНрд░рдЬрдирди рдХрд░рдиреЗ рд╕реЗ, рдХреИрдирд╡рд╛рд╕ рдХреА рджреВрд░реА рдмрджрд▓ рдЬрд╛рдПрдЧреАред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдПрдореБрд▓реЗрдЯрд░ рд╣реИ, рддреЛ рдХреБрдЫ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред

рдореЛрдб рдореЗрдВ рдмрджрд▓рд╛рд╡



рд╣рдореЗрдВ рдПрдХ рд╡реИрд░рд┐рдПрдмрд▓ рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдЬреЛ рдореЛрдб рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛ред рдореИрдВрдиреЗ рдЗрд╕реЗ рдЯрд╛рдЗрдк рдмреВрд▓рд┐рдпрди рдХреА рдбреНрд░рд╛рдЗрдВрдЧ рдХрд╣рд╛ред рдПрдХ рд▓рдВрдмреЗ рд╕реНрдкрд░реНрд╢ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдХрдИ рдкрд░рд┐рджреГрд╢реНрдп рд╣реИрдВ:
  1. рд╣рдо onDraw рдореЗрдердб рдореЗрдВ рдЕрдкрдирд╛ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ;
  2. рд╣рдо рдЕрдкрдирд╛ рдХреЛрдб onTouchEvent рдореЗрдВ рд▓рд┐рдЦрддреЗ рд╣реИрдВ;
  3. рд╣рдо рдПрдХ рдЯрд╛рдЗрдорд░ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕рдореЗрдВ рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╣реИрдВ;
  4. рд╣рдо рдПрдХ рд╣реИрдВрдбрд▓рд░ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдкреЛрд╕реНрдЯрдбреЗрд▓рд┐рдб рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рд░рдирдиреЗрдмрд▓ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ;

OnDraw рдореЗрдердб рдореЗрдВ, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдХреЗрд╡рд▓ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдк onTouchEvent рдореЗрдВ рдХреЗрд╡рд▓ рдЗрд╕ рддрдереНрдп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдВрдЧрд▓реА рдЖрдЧреЗ рдмрдврд╝ рдЬрд╛рдПрдЧреА, рдЬрд┐рд╕рд╕реЗ рд▓рдЧрд╛рддрд╛рд░ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдЯрд╛рдЗрдорд░ рд▓рдЧрд╛рддрд╛рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдереЛрдбрд╝рд╛ рдХрд╖реНрдЯрдкреНрд░рдж рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЪреМрдереЗ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред ApplicationView рд╡рд░реНрдЧ рдореЗрдВ, рд╣рдо рдЯрд╛рдЗрдк рд╣реИрдВрдбрд▓рд░ рдХрд╛ рдПрдХ рд╣реИрдВрдбрд▓рд░ рд╡реИрд░рд┐рдПрдмрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЕрдЧрд░: рдХрд╛рд░реНрд░рд╡рд╛рдИ == MotionEvent.ACTION_DOWN || рдХреНрд░рд┐рдпрд╛ == MotionEvent.ACTION_POINTER_DOWN рдмреНрд▓реЙрдХ рдореЗрдВ рднреА рд▓рд╛рдЗрди рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:

 handler.postDelayed(longPress, 1000); 


рдЕрдм рд╣рдореЗрдВ рд▓реЙрдиреНрдЧрдкреНрд░реЗрд╕ рдирд╛рдо рдХрд╛ рдПрдХ рд░рдирд╡реЗрдмрд▓ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

 Runnable longPress = new Runnable() { public void run() { } }; 


рдЕрдм, рдлрд┐рдВрдЧрд░ рдХреНрд▓рд╛рд╕ рдореЗрдВ, рд╣рдореЗрдВ рдЯрд╛рдЗрдк рдХрд╛ рд▓реЙрдиреНрдЧ рд╡реЙрд╢ рд╡реЗрд░рд┐рдПрдмрд▓ рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдкреНрд░реЗрд╕рд┐рдВрдЧ рдХрд╛ рд╕рдордп (рдбрдмрд▓-рдЯреИрдкрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА) рд╣реЛрдЧрд╛ ред рдЗрд╕ рдЪрд░ рдХреЗ рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ, рдЖрдкрдХреЛ System.currentTimeMillis () рдХрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд╣рдореЗрдВ рдЯрд╛рдЗрдк рдкреНрд╡рд╛рдЗрдВрдЯ рдХрд╛ рдПрдХ рд╕реНрдЯрд╛рд░реНрдЯрдкреЙрдЗрдВрдЯ рд╡реИрд░рд┐рдПрдмрд▓ рднреА рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдЙрдВрдЧрд▓реА рдХреА рд╢реБрд░реБрдЖрддреА рд╕реНрдерд┐рддрд┐ рд╣реЛрдЧреАред рдЗрд╕рдореЗрдВ рд╡рд╣ рдорд╛рди рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдкрд╛рд╕ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдпрд╛ рдкрд╣рд▓реА рдмрд╛рд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рдореЗрдВ рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмреВрд▓рд┐рдпрди рдХрд╛ рдПрдХ рд╕рдХреНрд╖рдорд▓реЙрдиреНрдЧ рдЪрд░ рднреА рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рд╕реНрдкрд░реНрд╢ рдХреА рдЙрдкрдпреБрдХреНрддрддрд╛ рдХреЛ рдЙрд╕ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рдпрд╣ рдЬрд╛рдВрдЪрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЙрдВрдЧрд▓реА рд╢реБрд░реВ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рдЪрд▓реА рдЧрдИ рд╣реИред рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╕реЗрдЯрдСрди рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рдкрд░рд┐рдгрд╛рдо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

 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 рдХреА рд░рди рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо рдЬрд╛рдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд╕реНрдкрд░реНрд╢ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд░рд╣рддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВ:

 if(fingers.size() > 0 && fingers.get(0).enabledLongTouch){ fingers.get(0).enabledLongTouch = false; drawingMode = !drawingMode; vibrator.vibrate(80); } 


рдмреЗрд╣рддрд░ рдмрдирд╛рдУ
рд▓рдВрдмреЗ рд╕реНрдкрд░реНрд╢ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП - рд╕рдХреНрд░рд┐рдп рд╣реЛрдиреЗ рдкрд░ рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдХрдВрдкрди рдЪрд╛рд▓реВ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рд╡рд╛рдЗрдмреНрд░реЗрдЯрд░ рдХрд╛ рдПрдХ рд╡рд╛рдЗрдмреНрд░реЗрдЯрд░ рд╡реИрд░рд┐рдПрдмрд▓ рдмрдирд╛рдПрдВ рдФрд░ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдореЗрдВ рдЗрд╕рдХреЗ рдорд╛рди рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╕реЗрдЯ рдХрд░реЗрдВ:
 vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE); 

рдорд╣рддреНрд╡рдкреВрд░реНрдг: рдкреНрд░рдХрдЯ рдореЗрдВ рдХрдВрдкрди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рдкрдВрдХреНрддрд┐ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП:
 <uses-permission android:name="android.permission.VIBRATE"/> 

рдлрд┐рд░, рд▓реЙрдиреНрдЧ-рдЯрдЪ рдЯреЗрд╕реНрдЯ рдХреЗ рдЕрдВрдд рдореЗрдВ, рд╣рдорд╛рд░реЗ рдЯрд╛рдЗрдорд░ рдХреА рд░рди рд╡рд┐рдзрд┐ рдореЗрдВ, рдЖрдк рджрд░реНрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
 vibrator.vibrate(80); 


рдбреНрд░рд╛рдЗрдВрдЧ



рдЕрдм рд╣рдо рдХреИрдирд╡рд╛рд╕ рдкрд░ рдкреЗрдВрдЯрд┐рдВрдЧ рд▓рд╛рдЧреВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдмреНрд░рд╢ рдХрд╛ рдЖрдХрд╛рд░ рдмрджрд▓ рд░рд╣реЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЪреЗрдХрдЧреИрд╕реНрдЯрд░реНрд╕ рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рднрд╛рдЧ рдХреЛ рджреЛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВрдЧреЗ: рдбреНрд░рд╛рдЗрдВрдЧ рдореЛрдб рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдореЛрдбред рдбреНрд░рд╛рдЗрдВрдЧ рдореЛрдб рдореЗрдВ рдЬрдм рд╣рдо рд╕реНрдкрд░реНрд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдмрд╕ рдПрдХ рд░реЗрдЦрд╛ рдЦреАрдВрдЪреЗрдВрдЧреЗ, рдФрд░ рдорд▓реНрдЯреАрдЯрдЪ рдХреЗ рд╕рд╛рде рдбреНрд░рд╛рдЗрдВрдЧ рдореЛрдб рдореЗрдВ рд╣рдо рдмреНрд░рд╢ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдмрджрд▓ рджреЗрдВрдЧреЗред рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ 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; } } 


рдЕрдВрддрд┐рдо рдкрдВрдХреНрддрд┐ рдореЗрдВ рдореИрдВрдиреЗ рдорд╛рди рдХреЛ рдХрд┐рд╕реА рдПрдХ рдХрд░реНрд╕рд░ рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рд╣реИред рдпрд╣ рдХрд░реНрд╕рд░ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╡рд╛рд▓реЗ рдкреНрд░рдХрд╛рд░ рдмрд┐рдВрджреБ рдХрд╛ рдПрдХ рдЪрд░ рд╣реИред рдмреНрд░рд╢ рдХреЗ рдЖрдХрд╛рд░ рдореЗрдВ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реНрд╕рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдСрдирдбреНрд░реЙ рд╡рд┐рдзрд┐ рдореЗрдВ рдХрд░реНрд╕рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреЛрдбрд╝реЗрдВ:

 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); //    } 


рдЕрдм рд╣рдо рдХреИрдирд╡рд╛рд╕ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╝реВрдо рдЗрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд╝реВрдо рдЖрдЙрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдбреНрд░рд╛рдЗрдВрдЧ рдореЛрдб рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдбреНрд░рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмреНрд░рд╢ рдХрд╛ рдЖрдХрд╛рд░ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХреЗрд╡рд▓ рд░рдВрдЧ рдХреА рдкрд╕рдВрдж рдХрд╛ рдПрд╣рд╕рд╛рд╕ рдХрд░рдирд╛ рд╣реИред

рд░рдВрдЧ рдмреАрдирдиреЗ рд╡рд╛рд▓рд╛



рд░рдВрдЧ рдХрд╛ рдЪреБрдирд╛рд╡ рд╕реНрдХреНрд░реАрди рдкрд░ рдПрдХ рдбрдмрд▓ рдЯреИрдк рдХреЗ рдмрд╛рдж рд╣реЛрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡реНрдпреВ рдореЗрдВ рдПрдХ рдЪрд░ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рд╕реНрдХреНрд░реАрди рдкрд░ рдЕрдВрддрд┐рдо рд╕реНрдкрд░реНрд╢ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдХ рдЪрд░ рдЬреЛ рдЗрд╕ рд╕реНрдкрд░реНрд╢ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЛ рд╕рдВрд░рдХреНрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХреЛ рдЯрд╛рдЗрдк рдХрд╛ рд▓рд╛рд╕реНрдЯрдЯрд╛рдЗрдк рдЯрд╛рдЗрдо рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рджреВрд╕рд░рд╛ - рдЯрд╛рдЗрдк рдкреНрд╡рд╛рдЗрдВрдЯ рдХрд╛ рд▓рд╛рд╕реНрдЯ рдЯрд╛рдЗрдкред рдлрд┐рд░ 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 , silnuke рдФрд░ vovkab рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рднреА рдзрдиреНрдпрд╡рд╛рдж рджреЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛

Source: https://habr.com/ru/post/In154193/


All Articles