[solved] Control a graphic with android buttons

General topics about the Android-Platform itself.
Coding issues please to the subforum right below.

[solved] Control a graphic with android buttons

Postby Bevor » Wed Mar 31, 2010 7:11 pm

Hello,

at the moment I'm not that much familiar with Android and I try to
teach it myself. My target is it to control a graphic with android
buttons, so at first I designed the layout:

Code: Select all
<?xml version="1.0" encoding="utf-8"?>

<FrameLayout android:id="@+id/FrameLayout01"
                     android:layout_width="fill_parent"
                     android:layout_height="fill_parent"
                     xmlns:android="http://schemas.android.com/apk/res/android">

                <TableLayout
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"
                        android:gravity="bottom"
                        android:stretchColumns="*"
                        android:layout_alignParentBottom="true">
                        <TableRow>
                    <Button
                        android:id="@+id/btnUp"
                        android:layout_width="80px"
                        android:layout_height="wrap_content"
                        android:text="Up"

                        />
                    <Button
                        android:id="@+id/btnEnter"
                        android:layout_width="70px"
                        android:layout_height="wrap_content"
                        android:text="Enter"
                        />
                    <Button
                        android:id="@+id/btnDown"
                        android:layout_width="80px"
                        android:layout_height="wrap_content"
                        android:text="Down"
                        />
                    </TableRow>
        </TableLayout>
</FrameLayout>


This seems to be what I want. Then I created a view and a thread:
--------------------------------------------
Code: Select all
package my.domain.test;

public class GameThread extends Thread {
    private SurfaceHolder surfaceHolder;
    private GamePanelView gamePanel;
    private boolean run = false;

    public GameThread(SurfaceHolder surfaceHolder, GamePanelView
panel) {
        this.surfaceHolder = surfaceHolder;
        this.gamePanel = panel;
    }

    public void setRunning(boolean run) {
        this.run = run;
    }

    @Override
    public void run() {
        Canvas c;
        while (run) {
            c = null;
            try {
                c = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                        gamePanel.updatePosition();
                    gamePanel.onDraw(c);
                }
            } finally {
                if (c != null) {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
}

-----------------------------
package my.domain.test;

public class GamePanelView extends SurfaceView implements Callback {

        private GameThread thread;
        private Bitmap ball;
        private int posX = 10, posY = 10;

        public GamePanelView(Context context, AttributeSet attrs)  {
                super(context, attrs);
                getHolder().addCallback(this);
                thread = new GameThread(getHolder(), this);
                createImages();
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int
width, int height) {
                // TODO Auto-generated method stub

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
                thread.setRunning(true);
                thread.start();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
                //
            }
        }
        }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(ball, posX, posY, null);
    }

    public GameThread getThread()  {
        return thread;
    }

    private void createImages()   {
        ball = BitmapFactory.decodeResource(getResources(),
R.drawable.ball);
    }

    public void updatePosition()  {
        //update Position
    }

}

---------------------------

Drawing the ball itself works and drawing the buttons itself works,
but I neighter know how to combine that nor I know how to listen to
these buttons (it's probably not onKeyDown, because I used this for
the d-pad). In earlier examples, I just used this xml as my main.xml:

Code: Select all
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/
android"
        android:background="#000000"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <my.domain.test
      android:id="@+id/game"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"/>

</FrameLayout>


I can additionally define this in my previous xml file. This seems to
work too, no exceptions. But what do I have to do when I want to draw
graphics and those android buttons I defined in the xml file at the
same time? And what is the best approach to control the graphic with
those buttons? I hope that anybody can give my some useful hints.

Best Regards.
Last edited by Bevor on Thu Apr 01, 2010 10:29 pm, edited 1 time in total.
Bevor
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Jan 23, 2010 6:28 pm

Top

Postby Bevor » Wed Mar 31, 2010 9:26 pm

The drawing problem is solved (spelling mistake in package name) but I still don't know how to listen to such a button and moving the ball with it.
Attachments
android_button_and_ball.jpg
android_button_and_ball.jpg (17.71 KiB) Viewed 590 times
Bevor
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Jan 23, 2010 6:28 pm

Postby Bevor » Thu Apr 01, 2010 10:28 pm

I found a working solution but I don't know if there is anything I should pay attention on with this solution (e.g. maybe a "synchronized" in setMotion or anything like that?)
Code: Select all
public enum Motion {
     DOWN, UP;
}

---------------------

public class BallTest extends Activity {
   
   private GamePanelView gameView = null;
   private GameThread thread = null;
   private Button btnEnter;
   private Button btnUp;
   private Button btnDown;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //Set the activity content from a layout resource.
        //The resource will be inflated, adding all top-level views to the activity.
        setContentView(R.layout.main);  //Shows the buttons
//        setContentView(new GamePanelView(getApplicationContext(), null));
        gameView = (GamePanelView)findViewById(R.id.game);
        btnEnter = (Button)findViewById(R.id.btnEnter);
        btnUp = (Button)findViewById(R.id.btnUp);
        btnDown = (Button)findViewById(R.id.btnDown);
        btnEnter.setOnClickListener(new OnClickListener() {      
         @Override
         public void onClick(View v) {
            //Quit the application for now
            finish();         
         }
      });
        btnUp.setOnClickListener(new OnClickListener() {   
         @Override
         public void onClick(View v) {
            gameView.setMotion(Motion.UP);
         }
      });
        btnDown.setOnClickListener(new OnClickListener() {
         @Override
         public void onClick(View v) {
            gameView.setMotion(Motion.DOWN);
         }
      });
        thread = gameView.getThread();
    }
}

-----------------------------------

public class GamePanelView extends SurfaceView implements Callback {
   
   private GameThread thread;
   private Bitmap ball;
   private int posX = 10, posY = 10;
   private SurfaceHolder surfaceHolder;
   
   public GamePanelView(Context context, AttributeSet attrs)  {
      super(context, attrs);
      this.surfaceHolder = getHolder();      //?
      surfaceHolder.addCallback(this);        //?
      thread = new GameThread(getHolder(), this);
      createImages();
   }

   @Override
   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
      // TODO Auto-generated method stub
      
   }

   @Override
   public void surfaceCreated(SurfaceHolder holder) {
      thread.setRunning(true);
      thread.start();
   }

   @Override
   public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        thread.setRunning(false);
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {
               //
            }
        }
   }
   
    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawColor(Color.BLACK);
        canvas.drawBitmap(ball, posX, posY, null);
    }
   
    public void setMotion(Motion motion)  {
       if (motion == Motion.UP)  {
          posY -= 10;
       }
       if (motion == Motion.DOWN)  {
          posY += 10;
       }
    }
   
    public GameThread getThread()  {
       return thread;
    }
   
    private void createImages()   {
       ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
    }
}

---------------------------

public class GameThread extends Thread {
    private SurfaceHolder surfaceHolder;
    private GamePanelView gamePanel;
    private boolean run = false;

    public GameThread(SurfaceHolder surfaceHolder, GamePanelView panel) {
        this.surfaceHolder = surfaceHolder;
        this.gamePanel = panel;
    }

    public void setRunning(boolean run) {
        this.run = run;
    }

    @Override
    public void run() {
        Canvas c;
        while (run) {
            c = null;
            try {
               //In order to draw to the Surface Canvas from within your second thread,
               //you must pass the thread your SurfaceHandler and retrieve the Canvas with lockCanvas().
               //You can now take the Canvas given to you by the SurfaceHolder and do your necessary drawing upon it.
                c = surfaceHolder.lockCanvas(null);
                synchronized (surfaceHolder) {
                    gamePanel.onDraw(c);
                }
            } finally {
                // do this in a finally so that if an exception is thrown
                // during the above, we don't leave the Surface in an
                // inconsistent state
                if (c != null) {
                    surfaceHolder.unlockCanvasAndPost(c);
                }
            }
        }
    }
}
Bevor
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Jan 23, 2010 6:28 pm

Top

Return to General

Who is online

Users browsing this forum: No registered users and 2 guests