1

I'm new to Android app development and I would like to ask something.

I have a bitmap inside my SurfaceView that I want to animate and move programmatically. I also want to put a button in the screen to control the moving of the bitmap. But since I cannot put a button in a SurfaceView, I declared it inside a RelativeLayout in my XML layout called main.xml.

Here's what's inside my main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/main_layout" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Test Button" />

</RelativeLayout>

So what I'm trying to do is to "combine" (can't find a better word) the SurfaceView with the Layout that is in my main.xml.

Here is my Main.java where I try to combine the Layout w/ the SurfaceView

package com.src.test.view;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.RelativeLayout;

public class Main extends Activity {

    private RelativeLayout _myXmlLayout;
    private MyView _myView;
    private Button _myButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        _myXmlLayout = (RelativeLayout) findViewById(R.id.main_layout);
        _myView = new MyView(this);
        _myButton = (Button) findViewById(R.id.button1);

        _myXmlLayout.addView(_myButton);
        _myXmlLayout.addView(_myView);

        setContentView(_myXmlLayout);
    }
}

but it gives me an "application has stopped unexpectedly" error. Am I doing it wrong? If so, can you suggest a better way of implementing this?

Your response is highly appreciated. Thanks!

p.s. no bitmap animation codes and button controls yet. It's just the views that I'm currently solving. :)

EDIT:

I edited my codes and here it is:

so here's my edited Main.java

package com.src.test.view;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class Main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);

    }
}

and here's my main.xml

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

    <com.src.test.view.MyView
        android:id="@+id/myView" 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <Button
        android:text="Test Button"
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left" />
    <Button
        android:text="Test Button2"
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right" />

</FrameLayout>

I tried to run it but it gives me an error.

Here's the logcat

(ZygoteInit.java:626)
10-29 01:18:51.046: E/AndroidRuntime(318):  at dalvik.system.NativeStart.main(Native Method)
10-29 01:18:51.046: E/AndroidRuntime(318): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class com.src.test.view.MyView
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.createView(LayoutInflater.java:503)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:565)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
10-29 01:18:51.046: E/AndroidRuntime(318):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.app.Activity.setContentView(Activity.java:1647)
10-29 01:18:51.046: E/AndroidRuntime(318):  at com.src.test.view.Main.onCreate(Main.java:12)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
10-29 01:18:51.046: E/AndroidRuntime(318):  ... 11 more
10-29 01:18:51.046: E/AndroidRuntime(318): Caused by: java.lang.NoSuchMethodException: MyView(Context,AttributeSet)
10-29 01:18:51.046: E/AndroidRuntime(318):  at java.lang.Class.getMatchingConstructor(Class.java:660)
10-29 01:18:51.046: E/AndroidRuntime(318):  at java.lang.Class.getConstructor(Class.java:477)
10-29 01:18:51.046: E/AndroidRuntime(318):  at android.view.LayoutInflater.createView(LayoutInflater.java:475)
10-29 01:18:51.046: E/AndroidRuntime(318):  ... 21 more

Thank you for your response

skynet
  • 9,898
  • 5
  • 43
  • 52
src
  • 469
  • 1
  • 6
  • 12

1 Answers1

4

I think you are overcomplicating this for yourself. At least, to simply put a button over a SurfaceView, visually, you can do something like what is shown here, by putting the button in the same FrameLayout as the surface view.

You can declare your custom view in xml as well, so it could look like:

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

    <com.src.test.view.MyView android:id="@+id/myView" android:layout_width="fill_parent" android:layout_height="fill_parent" />
    <Button android:text="Button" android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</FrameLayout>

then in onCreate you only have to say

setContentView(R.layout.main_layout);

You can position the button wherever you wish, for example if you want it to be in the bottom center, use android:layout_gravity="bottom|center_horizontal".

EDIT:

To make sure that your custom view implements all the necessary constructors (some of which are called when views are created from xml), open your custom view class in the eclipse editor, and go to the menu Source -> Generate Constructors from Superclass...

It will help you create constructors

Community
  • 1
  • 1
skynet
  • 9,898
  • 5
  • 43
  • 52
  • Thanks for the response, I tried your code but I'm still getting the same error. I followed your xml code, with just additional buttons and changed the `setContentView(_myXmlLayout)` to `setContentView(R.layout.main)`. Am I missing something? Thank you – src Oct 28 '11 at 17:04
  • Please post the output of logcat with your exception stacktrace in your question – skynet Oct 28 '11 at 17:09
  • You are getting this error because your view does not implement the constructor `MyView(Context context, AttributeSet attributes)`. I will edit my answer to show how to do this. – skynet Oct 28 '11 at 17:39
  • I followed your suggestion and there's no error anymore. Thanks. But I only see the buttons on the screen, no bitmap. I suppose the SurfaceView isn't visible? Anything that I needed to do after generating constructors? I painted the canvas blue on the surfaceview but I can't see it. Instead, the black background appears with the buttons. – src Oct 28 '11 at 17:59
  • Sounds like a problem with the implementation of the custom surfaceview. You could test if it shows up at all by using `android:background="@android:color/white"` in the xml for the component. Otherwise ask a new question and post the code from your custom view – skynet Oct 28 '11 at 18:05
  • Yes I believe it's on the custom surfaceview. Maybe I should post a new question from this. Based from your suggestion I've come up with a new set of possibilities to try on so, big thanks for your help! :) – src Oct 28 '11 at 18:11
  • Oh the code works now! The problem why I can't see the surfaceview was that I added the new constructor `MyView(Context context, AttributeSet attributes)` without removing the old constructor `MyView(Context context)`. Now I removed it and it worked! Many thanks! :) – src Oct 28 '11 at 18:18