1

I have an Activity which has a button and by code I draw a Circle, so my Circle class is:

public class Circle extends View {

private float x = 100;

private float y = 100;

private float radius = 50;

public Circle(Context context) {
    super(context);
}

protected void onDraw(Canvas canvas){
    Paint paint = new Paint();
    canvas.drawCircle(x, y, radius, paint);

}

}

And the code of my activity is:

public class AnotherTest extends AppCompatActivity {

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

    Circle c = new Circle(this);
    setContentView(c);
    } 

   }

But when I invoke setContentView, the button seems to be deleted. Any tips to show the circle and preserve the button?

NUN
  • 35
  • 8

1 Answers1

1

The button you mentioned is in your activity's layout XML file? If so, could you provide the code? setContentView() will only show the circle. If you want to add the circle to your existing layout you have to add it to a ViewGroup in your Activity's XML.

You could do something like this:

public class AnotherTest extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.anothertest_activity);
    } 
}

And the (res/layout/)anothertest_activity.xml file could look like this:

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

<Button
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<your.package.Circle
    android:id="@+id/myCircle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

In Android Studio, right below the xml code are two tabs: "Design" and "Text". Switch to "Text" to paste code, switch back to "Design" to position your elements.

If you drag your views, you have an layout XML file. In the Activity you need to set this file as your content view, otherwise you wouldn't see your views. But you can add views dynamically by doing something like this:

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

<Button
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</RelativeLayout>

And in your Activity:

public class AnotherTest extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Still your xml with your button but without circle
        setContentView(R.layout.anothertest_activity);

        // First find your ViewGroup to add Views to
        RelativeLayout viewGroup = (RelativeLayout) findViewById(R.id.my_viewgroup);
        // Add a new circle to existing layout
        viewGroup.addView(new Circle());
    } 
}

You also could add everything dynamically:

public class AnotherTest extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ViewGroup viewGroup = new LinearLayout(this);           
        setContentView(viewGroup);

        viewGroup.addView(new Button());
        viewGroup.addView(new Circle());
    } 
}

But I strongly recommend using xml layouts. Might want to take a look at Android Layouts

G. Kalender
  • 491
  • 4
  • 13
  • No, I dragged from the environment (Android Studio) to the Activity. – NUN May 26 '16 at 20:30
  • Could it be made only by code? Anyways thanks and I am going to try your answer. – NUN May 26 '16 at 20:47
  • What if onDraw would do something like that: ...onDraw(Canvas canvas){ Paint p = new Paint; for(int i=0; i<20;i++) { canvas.drawCircle((int)Math.random()*150, (int)Math.random()*150, 20, paint); } Would it be made by xml layouts? – NUN May 26 '16 at 21:34
  • You would do such thing in onDraw only when you make a game or something like that and then you wouldn't add views, you would just draw shapes and calculate where the "button" (not really a button view object - just a shape). It's highly recommended to make as much as possible in XML and add Views dynamically (if it's really necessary) like mentioned above. EDIT: Sorry, just saw the rest of your comment: drawing things belong to onDraw() - not in xml. But you could declare the View that has the mentioned onDraw method in xml. – G. Kalender May 26 '16 at 21:37
  • If everything you want to show happens in onDraw(), you can just do setContentView(new YouDrawingClass()); But as soon as you drag n drop views in Android Studio, you have an xml layout and have to use the method above. – G. Kalender May 26 '16 at 21:43
  • I tried dynamically the way you said by: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_etest); Button b = (Button)findViewById(R.id.button11); ViewGroup viewGroup = new LinearLayout(this); viewGroup.addView(b); viewGroup.addView(new Circle(this)); } But the circle is not shown on the screen. – NUN May 26 '16 at 22:05
  • You set the content view to be your xml file. You create a new LinearLayout that is never added. And you reference the Button via findViewById and also add it to the ViewGroup. If you create the LinearLayout dynamically, you have to do "setContentView(viewGroup)". Then you can add Button and Circle to viewGroup – G. Kalender May 26 '16 at 22:15
  • To let you have a functioning example, heres the code, but i strongly recommend XML again: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ViewGroup viewGroup = new LinearLayout(this); setContentView(viewGroup); Button b = new Button(this); b.setText("test"); viewGroup.addView(b); viewGroup.addView(new Circle(this)); } – G. Kalender May 26 '16 at 22:16
  • You are right, By mistake, I copypasted the code I didn't pretend to. The circles have to be made dynamically because the structure of the game forces to be done this way. The rest I think I will do with xml. Another question, how to "recover" by code an element which is inside the xml? – NUN May 26 '16 at 22:39
  • Im not sure what you mean by "recover" but maybe just the "findViewById(R.id.your_view_id)"? Or maybe you mean [inflating](http://stackoverflow.com/a/19110502/6386583)? – G. Kalender May 26 '16 at 22:47
  • findViewById, but if you could, I would be interested in inflating too. – NUN May 26 '16 at 22:54
  • Inflating means you take an XML and "convert" it into an in code usable View object. Mostly used for custom views. Good Tutorial about custom views is found [here](https://developer.android.com/training/custom-views/index.html). Happy coding! – G. Kalender May 26 '16 at 23:01
  • And recovering by findViewById how would it be? – NUN May 26 '16 at 23:11
  • This would only work when the view you want to get is already inflated. setContentView(R.layout.yourLayout) does in fact inflate "yourLayout.xml" internally. So when you are sure that your view is already inflated, you just call "findViewById(R.id.yourViewId)". For this to work you also have to make sure that your view in the XML file has the id-parameter set like in the example above: "android:id="@+id/my_viewgroup". In this case you would do "findViewById(R.id.my_viewgroup)". For more information please take a look at [this](https://developer.android.com/guide/index.html) – G. Kalender May 26 '16 at 23:18