Statically Typed

because Hindley-Milner rocks

Touch and Drag in Android


It’s my pet project to learn the Android platform and begin writing apps in Scala on it.  Once I get the legalities of my employment with respect to code I produce outside of work I might even be able to start releasing code/Android apps/create a website/etc.  For now, I’m not ready yet to make useful apps.  Hell, I’m still working out the kinks with touch events.  To that end I’ve been playing around with making a much limited clone of the Alchemy game.

If you’ve never played it or seen it, the link should provide enough detail to get an idea.  From a developer’s point of view there’s very little going on.  Essentially you have several icons which are drawn to the screen.  By dragging one icon atop another you might create a new element, i.e. both the original icons disappear and are replaced by a new icon.  Yes, this is a very mechanical viewpoint and utterly simplified to what is happening under the hood but it serves as a good starting point and goal.

Here is some sample code that puts a button on the screen (that really doesn’t need to be there,) draws an icon in the center of the view and allows the user to drag the icon around.  It contains a bug and really isn’t blog worthy but I’ve seen a bazillion SO questions about TouchEvents.  Hope this helps someone, somewhere…

public class Dragable extends Activity {
    private Drawable mTiles = null;
    private int mDrawHeight = -1;
    private int mDrawWidth = -1;
    private DrawTiles mDrawTiles;
    /** Called when the activity is first created. */    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                final Resources res = getResources();
                mTiles = res.getDrawable(R.drawable.tiles);
                mDrawHeight = mTiles.getIntrinsicHeight();
                mDrawWidth = mTiles.getIntrinsicWidth();
                final SurfaceView surf = (SurfaceView)findViewById(R.id.surface_home);
                surf.setOnTouchListener( new SurfaceView.OnTouchListener(){
                    private boolean moving = false;//stupid state
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        switch( event.getAction() ){
                        case MotionEvent.ACTION_DOWN:
                            final int x = (int)event.getX();
                            final int y = (int)event.getY();
                            final Rect bounds = mTiles.getBounds();
                            moving = bounds.intersects(x, y, x+1, y+1);
                            return true;
                        case MotionEvent.ACTION_MOVE:
                            if( moving ){
                                final int x_new = (int)event.getX();
                                final int y_new = (int)event.getY();
                                mDrawTiles.draw( new DrawLogic(){
                                    @Override
                                    public void draw(Rect _surface) {
                                        mTiles.setBounds(
                                            x_new - mDrawWidth/2,
                                            y_new - mDrawHeight/2,
                                            x_new + mDrawWidth/2,
                                            y_new + mDrawHeight/2);
                                        }
                                    });
                                }
                            return true;
                        case MotionEvent.ACTION_UP:
                            moving = false;
                            return true;
                    }
                    return false;
                }        	        
            });
            final Button addButton = (Button)findViewById(R.id.add_new);
            addButton.setOnClickListener( new OnClickListener(){
                @Override
                public void onClick(View v) {
                    DrawTiles draw = new DrawTiles( surf );
                    draw.draw( new DrawLogic(){
                        @Override
                        public void draw(Rect _surface) {
                        mTiles.setBounds(
                            _surface.centerX() - mDrawWidth/2,
                            _surface.centerY() - mDrawHeight/2,
                            _surface.centerX() + mDrawHeight/2,
                            _surface.centerY() + mDrawHeight/2);
                        }
                    });
                }
            });
            mDrawTiles = new DrawTiles( surf );
        }
        private interface DrawLogic{
            void draw(Rect _surface);
        }
        private class DrawTiles{
            protected final SurfaceHolder mHolder;
            public DrawTiles(SurfaceView _view){
                mHolder = _view.getHolder();
            }
            public void draw(DrawLogic _logic){
                Canvas canvas = null;
                try{
                    canvas = mHolder.lockCanvas();
                    _logic.draw( mHolder.getSurfaceFrame() );
                    if( canvas != null){
                        mTiles.draw(canvas);
                     }
                 }
                 finally{
                     if( canvas != null ){
                         mHolder.unlockCanvasAndPost(canvas);
                     }
                 }
             }
        }
    }

The main.xml file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <SurfaceView 
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/surface_home"/>
    <Button
        android:id="@+id/add_new"
        android:text="@string/add_new"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"/>
</RelativeLayout>

Can’t way I didn’t warn you.  I really need to get rid of that button.  It bugs me.

Advertisements

6 comments on “Touch and Drag in Android

  1. nevin
    January 21, 2011

    Hey why do I keep getting an error on setOnClick Listener?

    The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (new DialogInterface.OnClickListener(){})

    • owreese
      January 21, 2011

      In this case, since you’re using a dialog and not a ButtonView or similar object, a Dialog itself lacks a setOnClickListener() method. Just because there is a nested class within the DialogInterface for an DialogInterface.OnClickListener doesn’t mean it’s compatible with the underlying object. I know, screwy. I have no idea why they did this.

  2. Rodrigo
    June 14, 2011

    where R.drawable.tiles ??

    • owreese
      June 14, 2011

      It would be found within the resource folder of my source code directory. There’s a bunch of free things you can find by Google (“free android icons.”) I used some of those I found there. Since they are not mine to give away, I’m not including them on the post.

  3. Ali
    September 2, 2011

    Hi Guys…
    I want to drag the image and drop it in a chess board like structure(Grid View)..
    do any one know how to do it….plz any one help me out>>>>>>

  4. rajesh
    March 6, 2013

    add this
    import android.view.View.OnClickListener;

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Information

This entry was posted on December 2, 2010 by in Android, Java, Pet Project.
%d bloggers like this: