I'm currently making a simple game with the surfaceview but I find it hard to position the buttons or texts within the Relative layout programmatically in android. For example, in the sample below Im setting the relativelayouts with texts in a relative layout, and I want to set it to the right side of the screen with few margins to the right. How should I understand where I'm positioning the contents ? And are there some tips on positioning contents programmatically?
RelativeLayout Rs = new RelativeLayout(this);
Rs.setBackgroundResource(R.drawable.btn);
Rs.setGravity(Gravity.CENTER);
Regame.addView(RR,400,150);
Rs.setX(0);
txt= new TextView(this);
I guess it would be sufficient if you accessed the canvas from within the surfaceView.Probably would be more efficient if you used onSizeChange
for the width and height but i guess the canvas getWidth and getHeight would suffice.Also my example is just drawing once the surface is created, you'll have to make your own update logic.Also i am ditching the relative layout but i think this could suffice your needs:
public class GameView extends SurfaceView {
protected SurfaceHolder holder;
public GameView(Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
Canvas c = holder.lockCanvas(null);
onDraw(c);
holder.unlockCanvasAndPost(c);
}
});
}
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(20);
int width=canvas.getWidth();
int height=canvas.getHeight();
//Just for example
int desiredHeight=height/2;
int desiredMargin=10;
String desiredText="Some text";
int textWidth=Math.round(paint.measureText(desiredText));
int desiredWidth=width-textWidth-desiredMargin;
canvas.drawText(desiredText, desiredWidth,desiredHeight, paint);
}
}
Related
I wrote the following code and it works well. But I have other purpose. I want to click only on a view to doing the operations.First, Please see the following image:
MY CODE IS AS FOLLOWS:
public class MainActivity extends Activity {
RelativeLayout relativeLayout;
#Override
protected void onCreate(Bundle bundle)
{ super.onCreate(bundle);
relativeLayout = new RelativeLayout(getApplicationContext());
setContentView(relativeLayout);
A a = new A(this);
relativeLayout.addView(a);
a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
B b = new B(getApplicationContext());
relativeLayout.addView(b);
}
});
}
}
class A extends View {
Paint paint;
A(Context context) {
super(context);
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawRect(20,60,100,150,paint);
}
}
class B extends View {
Paint paint;
B(Context context){
super(context);
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas){
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
canvas.drawRect(100,150,200,250,paint);
}
}
when I run the above code I can see the green rectangle after press on the red rectangle. But the problem is that when I press another places on the screen I can do this operations also. I want that only I can see the green rectangle to press on the red rectangle and not in the another places on the screen to doing this operations.
Use onTouch event
a.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getX(0)>=20 && event.getY(0)>=60 && event.getX(0)<=160 && event.getY(0)<=150) {
B b = new B(getApplicationContext());
relativeLayout.addView(b);
}
return true;
}
});
You are defining the red square's parameters but not the parameters of the canvas in which you are drawing. You are creating the view (A) without defining the width and height of it, so it is set to match_parent by default, which means it will take the whole size of your RelativeLayout (the whole screen). So, when you click "outside" the red square you are actually clicking the view (A).
Try to define an specific height and width for the view in which you are drawing, like this.
A a = new A(this);
a.setLayoutParams(new RelativeLayout.LayoutParams(300,300));
Remember that LayoutParams takes pixels as parameters, so you should really convert the dps to px as specified here
Also, setting some background colors to your views (relativeLayout, A) will help you visualize what you are doing.
# nukeforum, your guess helped me very much. I thank all of you. My problem was exactly from the canvas and its size. I added the following operation in my code and solved my problem.
relativeLayout.addView(a,70,70);
For A class, I changed as follows:
canvas.drawRect(10,20,30,40,paint);
I would like to add TextView and EditView into my custom LinearLayout programmatically.
But I don't know how.
Something like this (that doesn't work):
<com.custom.FavoritesViewer
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"
android:id="#+id/favoritesViewer">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello"/>
</com.custom.FavoritesViewer>
and my custom layout
public class FavoritesViewer extends LinearLayout {
private Bitmap fullImage;
private int canvasWidth;
private int canvasHeight;
private final Paint paint = new Paint();
public FavoritesViewer(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
initializeCanvasSize(context);
}
private void initializeCanvasSize(Context context) {
final Pair<Integer, Integer> screenSize = Utils.getScreenSize(context);
canvasWidth = screenSize.first;
canvasHeight = screenSize.second;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(canvasWidth, canvasHeight / 3);
}
#Override
protected void onDraw(Canvas cvs) {
if (fullImage == null) {
fullImage = Bitmap.createBitmap(canvasWidth, canvasHeight / 3, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(fullImage);
paint.reset();
paint.setColor(Color.parseColor("#AA000000"));
canvas.drawRect(0, 0, canvasWidth, canvasHeight / 3, paint);
}
cvs.drawBitmap(fullImage, 0, 0, null);
}
}
So I have a canvas (like background) and I would like to add some standart Views on top. I cannot add it on onDraw.
Is it any way to add View into custom Layout?
EDITTED
I need to implement some special UI with buttons. I want to wrap this in one component. I draw that UI on canvas and somehow should add buttons (It's enough for me to add simple ImageButton, not to draw an image and emulate button's behaviour). That's why I selected Layout as container and need to add Views programmatically.
As long as you call through to super (probably super.onDraw()), I imagine the parent class will draw the views you add as expected. It looks like you're just overriding onDraw, which would prevent the parent LinearLayout class from rendering it's content (like the TextView).
Try commenting out your onDraw method first, and see if the LinearLayout behaves as expected.
Also, what's the goal of the Custom Layout? There may be a better way to achieve your goal.
I'm trying to make a simple game which uses Canvas and I want to put there something like a button into the right upper corner which allows you to pause the game.
What would be the best way to do that?
I was thinking about drawing those two lines that symbolize pausing on the canvas and pausing the game after the player clicks its locations but isn't there a better way?
I put here also a picture to show you how I want it to look like:
I use relative layout to manage all of the things.
1) find the relative layout
2) add something in your RelativeLayout
3) add the canvas to your RelativeLayout
My example below draws four buttons by simple for loop and add the canvas.
Example:
RelativeLayout layout = (RelativeLayout)findViewById(R.id.bb);
for (int i=0; i<4; i++) {
Button btn = new Button(this);
btn.setId(i);
btn.setText("some_text");
btn.setHeight(i*100);
btn.setX(100*i);
btn.setY(100*i);
layout.addView(btn);
}
YourDesign abc=new YourDesign(this);
layout.addView(abc);
You could consider "YourDesign" is the class of your canvas.
Canvas example:
public class YourDesign extends View{
Bitmap picture;
int x=0;
public YourDesign(Context context) {
super(context);
picture=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
canvas.drawBitmap(picture, x, 100, new Paint());
x++;
if(x>canvas.getWidth())
x=0;
invalidate();
}
I'm quite new to Android programming and I'm stuck on how to get this right.
My situation is I want to draw a rectangle inside a RelatativeLayout and be able to change the shape of the rectangle dynamically relative to the size of the RelativeLayout which does not encompass the whole screen.
My problem is when I try to implement this, the size of the rectangle is still relative to the screen size
Is there a way where I can restrict the canvas size to the RelativeLayout size or is there a better way?
Here is part of my code from the maim activity
RelativeLayout.LayoutParams rl = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
blueView = new Bar(this);
blueView.setLayoutParams(rl);
blueLayout.addView(blueView);
And I also have a Bar class that extends View
public class Bar extends View{
Rect theBar;
public Bar(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
theBar = new Rect();
theBar.set(0, 0, canvas.getWidth(), canvas.getHeight()/2);
Paint blue = new Paint();
blue.setColor(Color.BLACK);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(theBar, blue);
}
}
I can add this logo to the canavas if I do this:
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(200,200);
ImageView boo = new ImageView(ExampletouchActivity.this);
boo.setImageResource(R.drawable.ic_launcher);
boo.setLayoutParams(lp);
fr.addView(boo); //this works fine
But if I try to add the same logo to the canvas like this it does not show anything up:
fr.addView(new Toucher(ExampletouchActivity.this));
My Toucher class is like so...
public class Toucher extends View{
ImageView boo;
public Toucher(Context context)
{
super(context);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(200,200);
boo = new ImageView(context);
boo.setImageResource(R.drawable.ic_launcher);
boo.setLayoutParams(lp);
}
#Override
public void onDraw(Canvas c)
{
boo.draw(c);
}
I have been trying for ages and cannot work out why this imageview will not draw itself to the canvas?
Many Thanks
Layout and Canvas aren't the same thing. Layout is "draw this for me", and Canvas is "I'm drawing this". In your working example, you're taking a static image and putting it into a Layout.
When you are using the canvas, in a view things are different, so try using:
canvas.drawBitmap(bg, src, dst, paint);