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?
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
Related
I have a custom view as you can see in activity_main.xml. Right now it is hidden under the camera fragment. I want it to show up on top of it.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.snappiesticker.cwac4.StickerView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
This is the class itself:
public class StickerView extends View {
Bitmap bitmap;
float x = 2;
float y = 2;
public StickerView(Context context, AttributeSet attrs) {
super(context,attrs);
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.paunch);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(bitmap, x, y, null);
// I wanted to put it here but that would cause the loop described below.
}
}
by loop, I mean: onDraw is called, which calls bringToFront, which asks the layout to be re-rendered. which calls onDraw, which calls bringToFront, etc. etc.
This is what I want to avoid.
This is instantiated in the mainActivity.
public class MainActivity extends Activity implements CameraHostProvider {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DemoCameraFragment current = new DemoCameraFragment();
getFragmentManager().beginTransaction()
.add(R.id.fragment_container, current)
.commit();
// can I somehow tell it to render the custom sticker view at the front here?
}
}
Did I understand correctly, you want to have your custom StickerView to remain on top of camera fragment? If that is the case you could simply refine your layout to something like this too ;
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.snappiesticker.cwac4.StickerView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Using this layout your camera fragment is added below StickerView and there's no need to call bringToFront() at all. If you use your root layout as fragment container the fragment is added after your custom view i.e above it.
I try to use setContentView (R.layout.main) to display both an imageview and a Custom View. Somehow only the imageview can be shown but the Custom view is not visible (i.e. Bitmap ButtonStart not visible). I tested my code for onDraw and Texture class (responsible to load a bitmap object) somewhere else and it works fine. So I dunno what goes wrong...
Code for Custom view
public class TitleView extends View {
private Bitmap ButtonStart;
public TitleView (Context context, AttributeSet attrs) {
super (context, attrs);
Texture t2 = new Texture(context);
t2.loadFromAsset("button_Start.png");
ButtonStart = t2.getBitmap();
}
#Override
protected void onDraw (Canvas canvas) {
canvas.drawBitmap (ButtonStart, 0, 0, null);
}
}
MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature (Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main_screen_image);
}
}
main_screen_image.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainScreenLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ImageView
android:id="#+id/mainScreenImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="centerCrop"
android:src="#drawable/screenimage"
>
</ImageView>
<com.lowbband.chimera.TitleView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/titleview"/>
</LinearLayout>
With the code above, only screenimage was shown...
<ImageView
android:id="#+id/mainScreenImage"
android:layout_width="fill_parent"
android:layout_height="fill_parent" //it should be wrap_content otherwise it will take whole space
android:scaleType="centerCrop"
android:src="#drawable/screenimage"
>
</ImageView>
<com.lowbband.chimera.TitleView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/titleview"/>
And if the image is large and still fills the screen then put ScrollView outside LinearLayout
I'm struggling with a problem for a few days already and couldn't find solution to my problem so far.
I have two classes:
- StartActivity extends Activity
- TimeGraphView extends SurfaceView
What I want to achieve is to add dynamically buttons from within TimeGraphView to another view (LinearLayout).
To do so wanted to get that LinearLayout inside TimeGraphView with findViewById() but it returns null, and it should because I call it in TimeGraphView not in root element where I used setContentView();
So my question is how can I add button dynamically from custom view level to another view.
And my code:
public class StartActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.time_graph);
LinearLayout layout = (LinearLayout) this.findViewById(R.id.TimeGraphLayout);
//here I can add button but it's not what I want
}
}
and ...
public class TimeGraphView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
public TimeGraphView(Context context) {
super(context);
}
public TimeGraphView(Context context, AttributeSet set) {
super(context, set);
}
public TimeGraphView(Context context, AttributeSet set, int arg) {
super(context, set, arg);
}
public void run() {
while (run) {
if (something) {
LinearLayout layout = (LinearLayout) findViewById(R.id.TimeGraphLayout);
if (layout != null) {
Button button = new Button(context);
button.setText(text);
layout.addView(button);
} else {
Log.e("TimeGraphView", "TimeGraphLayout is null");
//and "layout" is always null and that's the problem ;(
}
}
}
}
}
... and my XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/TimeGraphRootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<HorizontalScrollViewa
android:id="#+id/TimeGraphPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/TimeGraphLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" />
</HorizontalScrollView>
<my.package.TimeGraphView
android:id="#+id/TimeGraphChart"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
You cannot use it in that way. If you add a root element Linearlayout and reference that in addition it might work. If you want to get the TimeGraphLayout class though:
TimeGraphView layout = (TimeGraphView) findViewById(R.id.TimeGraphLayout);
setContentView(layout);
The original way you did it will not work because TimeGraphView is not a LinearLayout
I have a class called Panel like this:
public class Test extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Panel(this));
...
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private LinearLayout layout;
public Panel(Context context) {
super(context);
layout = //get layout resource in layouts folder
}
public void onDraw(Canvas canvas) {
//I want to draw my xml layout
layout.draw(canvas);
}
}
I have tried to use LayoutInflater in order to get my layout:
LayoutInflater inflater = LayoutInflater.from(context);
layout = new LinearLayout(getApplicationContext());
inflater.inflate(R.layout.mylayout, layout);
... but I cant see anything on the screen, only a black background :S
as far as I know you can't draw a linear layout inside the SurfaceView you can draw anything you want in your SurfaceView if you want to add elements to your view like buttons or something like that I recommend using the XML and putting all your elements there. Something like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<SurfaceView android:id="#+id/mySurfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</SurfaceView>
<Button android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:text="myButton"/>
</LinearLayout>
and then you may set your content of your view with setContentView(R.layout.my_xml);
How do I set some UI elements over (on top of) canvas?
I have a simple touch game that has its graphics placed on custom view with canvas. However as my full screen Panel is in the setContentView() I can't add any UI items like progressBar or logo. I would like to have whole canvas layer visible with some objects (progressBar, logo) "floating" over it.
Main class:
public class GameClass extends Activity implements OnGestureListener {
Panel panel;
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
panel = new Panel(this, 1, 2);
setContentView(Panel);
...
}
Panel class:
public class Panel extends View {
public Panel(Context context, int Var1, int Var2) {
super(context);
...
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
}
}
As code shows, touches are handled inside GameClass and the changes in animation are handled inside Panel.
Or maybe.. Would it be possible to start new transparent activity with progress bar and button so that both the button on overlay activity AND objects on underlying activity? And I could need a way to close all the layers (transparent activity, Panel, GameClass) with the button on transparent activity. Complicated? :D
I do have the same problem and here is how I solved it
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.game);
drawView = new DrawView(this);
drawView.requestFocus();
LinearLayout upper = (LinearLayout) findViewById(R.id.LinearLayout01);
upper.addView(drawView);
ImageButton menu = (ImageButton) findViewById(R.id.ImageButton01);
menu.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
finish();
}
});
ImageButton reset = (ImageButton) findViewById(R.id.ImageButton02);
reset.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
drawView.resetGame();
}
});
}
instead of setting contentview to panel adding it Linearlayout that is added in my game.xml and here goes my
game.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:background="#drawable/game_background">
<LinearLayout
android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="350dip" />
<LinearLayout
android:id="#+id/LinearLayout02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/LinearLayout01">
<ImageButton
android:id="#+id/ImageButton01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/menu"></ImageButton>
<ImageButton
android:id="#+id/ImageButton02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/reset"></ImageButton>
</LinearLayout>
<LinearLayout
android:layout_below="#+id/LinearLayout01"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="#+id/layout_ad"
android:layout_height="wrap_content" />