I have a class Drawview:
public class DrawView extends View {
private ColorBall[] colorballs = new ColorBall[3]; // array that holds the balls
private int balID = 0; // variable to know what ball is being dragged
public DrawView(Context context) {
super(context);
setFocusable(true); //necessary for getting the touch events
// setting the start point for the balls
Point point1 = new Point();
point1.x = 50;
point1.y = 20;
Point point2 = new Point();
point2.x = 100;
point2.y = 20;
Point point3 = new Point();
point3.x = 150;
point3.y = 20;
// declare each ball with the ColorBall class
colorballs[0] = new ColorBall(context,R.drawable.bol_groen, point1);
colorballs[1] = new ColorBall(context,R.drawable.bol_rood, point2);
colorballs[2] = new ColorBall(context,R.drawable.bol_blauw, point3);
}
}
And my current class is:
public class Quiz1 extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.e);
AbsoluteLayout l= (AbsoluteLayout)findViewById(R.id.ll);
DrawView d=new DrawView(this);
l.addView(d);
}
}
I am trying to add that DrawView class but its not getting added as a child view of Absolutelayout of my current class view.its executing without any error but i am not able to see Drawview class objects.
And when i am doing this:
public class Quiz1 extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.e);
AbsoluteLayout l= (AbsoluteLayout)findViewById(R.id.ll);
DrawView d=new DrawView(this);
l.addView(d);
}
}
I am getting NullPointerException it means its not renderring the Drawview View.So bottom line is how to add a class extending a View to current view.
Please help me..thanx
The view probably is getting added, but from the code that you've posted it wouldn't lay out in a way where anything would be visible. By default, when you add a view to a layout in Java code like you have done, without explicitly setting any LayoutParams, it will set your view to be laid out using wrap_content for both height and width. Since (as far as we can see) you are not overriding any of View's measurement methods to tell the layout system how big the "content" inside your custom view is, the view will be added to the hierarchy with a height and width of zero.
Before adding your custom view to the layout, you should add a line to set the layout parameters to fill it's container (the parent layout), like so:
AbsoluteLayout l= (AbsoluteLayout)findViewById(R.id.ll);
DrawView d = new DrawView(this);
LayoutParams lp = new AbsoluteLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 0, 0);
d.setLayoutParams(lp);
l.addView(d);
Another option is to add your custom view directly to the XML layout R.layout.e, where you can set all these parameters directly in the XML and not worry about doing it in Java code.
Final side note: AbsoluteLayout has been deprecated for a long time now, and should not be used in new applications. You should use a FrameLayout or RelativeLayout for your application, which provide just as much flexibility.
HTH
Related
I am trying to implement admob in my app, but I can't get it working.
I have a Class A, which is the main class, it extends activity.
I have a Class B, which is the class that is called when the application start. I have the following piece of code in class A to archive this:
B b = new B(this);
setContentView(B);
In class B I have a canvas with test and bitmaps. I want to put an ad on the canvas with admob, but I can't archive this. Class B:
private AdView adView;
int[] degree = { 90, 180, 270, 360 };// random graden eindposities pijl
// int width, height;
Random rand = new Random();
Typeface font;
Matrix matrix = new Matrix();// degree,x,yaxis
Region region;// region die klikbaar is om het pijl te bewegen
AlertDialog alertDialog;
LinearLayout layout;
public YesNo(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
public boolean onTouchEvent(MotionEvent event) {
//do something
}
#Override
protected void onDraw(Canvas canvas) {
//Do something
invalidate();
}
i have tried to implement admob with this code(among other):
public void ads() {
adView = new AdView((Activity) getContext(), AdSize.BANNER,
"xxxxxxxxxxx");
LinearLayout.LayoutParams params;
params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
// Create a linear layout
LinearLayout layout = new LinearLayout((Activity) getContext());
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(6, 6, 6, 6);
layout.addView(adView, params);
}
I searched hours for a solution but I can't find any.
Can somebody help me in the right direction?
First of all, your AdView need to be a part of your content view. The LinearLayout you created in your ads() function. Second, you need to create an AdRequest and load the ad with that request:
AdRequest request = new AdRequest();
request.addTestDevice(AdRequest.TEST_EMULATOR); // get test ads on emulator.
adView.loadAd(request);
Check out the documentation for more information on how to set up your AdView.
In your ads function, you do not actually use the LinearLayout you create - you need to put that into another layout or directly into your activity, using setContentView
I'm wondering how to measure the dimensions of a view. In my case it is aan Absolute Layout. I've read the answers concerning those questions but I still don't get it.
This is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AbsoluteLayout layoutbase = (AbsoluteLayout) findViewById(R.id.layoutbase);
drawOval();
}
public void drawOval(){ //, int screenWidth, int screenHeight){
AbsoluteLayout layoutbase = (AbsoluteLayout) findViewById(R.id.layoutbase);
int screenWidth = layoutbase.getWidth();
int screenHeight = layoutbase.getHeight();
Log.i("MyActivity", "screenWidth: " + screenWidth + ", screenHeight: " +screenHeight);
Coordinates c = new Coordinates(BUTTONSIZE,screenWidth,screenHeight);
...some code ...
((ViewGroup) layoutbase ).addView(mybutton, new AbsoluteLayout.LayoutParams(BUTTONSIZE, BUTTONSIZE, c.mX, c.mY));
mybutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
showText(mybutton);
}
});
}
public void showText(View button){
int x = findViewById(LAYOUT).getWidth();
int y = findViewById(LAYOUT).getHeight();
Toast message = Toast.makeText(this, "x: " + x , Toast.LENGTH_SHORT);
message.show();
}
The getWidth() command works great in showText() but it does not in drawOval(). I know it looks a bit different there but I also used the int x = findViewById(LAYOUT).getWidth(); version in drawOval(), and x/y are always 0. I don't really understand why there seems to be no width/height at that earlier point. Even if I actually draw a Button on the Absolute Layout, getWidth() returns 0. Oviously I want to measure the sizes in drawOval().
I think will help you.
LinearLayout headerLayout = (LinearLayout)findviewbyid(R.id.headerLayout);
ViewTreeObserver observer = headerLayout .getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
int headerLayoutHeight= headerLayout.getHeight();
int headerLayoutWidth = headerLayout.getWidth();
headerLayout .getViewTreeObserver().removeGlobalOnLayoutListener(
this);
}
});
}
getWidth() is giving you 0 because onCreate is called before layout actually happens. Due to views being able to have dynamic positions and sizes based on attributes or other elements (fill_parent for example) there's not a fixed size for any given view or layout. At runtime there is a point in time (actually it can happen repeatedly depending on many factors) where everything is actually measured and laid out. If you really need the height and width, you'll have to get them later as you've discovered.
This specially deal with Dimensions so
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
This may help you in managing dimensions.
Note: This returns the display dimensions in pixels - as expected. But the getWidth() and getHeight() methods are deprecated. Instead you can use:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
as also Martin Koubek suggested.
If your goal is to simply draw an oval on the screen, then consider creating your own custom View rather than messing around with AbsoluteLayout. Your custom View must override onDraw(android.graphics.Canvas), which will be called when the view should render its content.
Here is some extremely simple sample code that might help get you started:
public class MainActivity extends Activity {
private final Paint mPaint = new Paint();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
// create a nested custom view class that can draw an oval. if the
// "SampleView" is not specific to the Activity, put the class in
// a new file called "SampleView.java" and make the class public
// and non-static so that other Activities can use it.
private static class SampleView extends View {
public SampleView(Context context) {
super(context);
setFocusable(true);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.CYAN);
// smoothen edges
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(4.5f);
// set alpha value (opacity)
mPaint.setAlpha(0x80);
// draw oval on canvas
canvas.drawOval(new RectF(50, 50, 20, 40), mPaint);
}
}
}
This give you screen resolution:
WindowManager wm = (WindowManager)context.getSystemService(context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point outSize = new Point();
display.getSize(outSize);
kabuko's answer is correct, but could be a little more clear, so let me clarify.
getWidth() and getHeight() are (correctly) giving you 0 because they have not been drawn in the layout when you call them. try calling the two methods on the button after addView() (after the view has been drawn and is present in the layout) and see if that gives you the expected result.
See this post for more information.
I want to keep the same size of the bitmap for the canvas, because when I add the custom view to the LinearLayout shows the canvas with different size and I want to set the size of the canvas like bitmap object.
Part of the code:
public class TESTActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout l = new LinearLayout(this);
l.setOrientation(1);
Button b1 = new Button(this);
Button b2 = new Button(this);
View mV = new MyView(this);
l.addView(b1);
l.addView(b2);
l.addView(mV);
setContentView(l);
}
public class MyView extends View {
public MyView(Context c) {
super(c);
mBitmap = Bitmap.createBitmap(480, 300, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
...
}
...
}
}
The Canvas class holds the "draw" calls. Canvas(Bitmap bitmap) Construct a canvas with the specified bitmap to draw into. canvas will take the size of the the draw object. so by setting size of bitmap you can set size of canvas.
If you want to draw on canvas with your custom height and width you have to call setContentView(android.view.View yourView , android.view.Viewgroup.LayoutParam yourLayout) in your activity class.Because by default setContentView(View view) method use full width and height.So you have to use its overloaded method with two parameter along with your desired. See documentation for more info.And don`t use only LayoutParams() constructor to create its object. Use it by writing its full path like android.view.ViewGroup.LayoutParams. Because there are some other classes with same name in Android SDK.If you only use LayoutParams Eclipse may not find correct class so use full path.
MyView customView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
customView = new MyView(getApplicationContext());
android.view.ViewGroup.LayoutParams lp = new android.view.ViewGroup.LayoutParams(100,200);//100 is width and 200 is height
setContentView(customView, lp);
customView.setOnClickListener(this);
}`
I am attempting to create a user interface dynamically. I have successfully create a view and loaded my background image. I have created two additional small view items to display on the background. My problem is that I have not been able to find any advice/instruction that tells me how to draw the small views. It seems that it should be a trivial exercise and I am guessing it is just finding the correct referencing. Hope someone out there can point me in the right direction.
Here is my Activity:
public class GhostActivity extends Activity implements OnTouchListener
{
private DrawView ghostView;
public Card mCard1, mCard2;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
// ToDo add your GUI initialization code here
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
ghostView = new DrawView(this);
setContentView(ghostView);
//get the window size
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Context context = getApplicationContext();
//create view items with initial positions
Point startPoint;
startPoint = new Point();
startPoint.x = 5;
startPoint.y = 3;
mCard1 = new Card(context, 1, R.drawable.bol_geel, startPoint);
startPoint.x = 5;
startPoint.y = 43;
mCard2 = new Card(context, 2, R.drawable.bol_rood, startPoint);
//now display them on the ghostView *****************HOW?
// set the callbacks
ghostView.setOnTouchListener(this);
mCard1.setOnTouchListener(this);
mCard2.setOnTouchListener(this);
}
and here is the View;
public class DrawView extends View
{
Drawable bg ;
public DrawView(Context context) {
super(context);
//setFocusable(true);
Drawable bg = this.getResources().getDrawable(R.drawable.bubbleblue480x800);
setBackgroundDrawable(bg);
}
#Override protected void onDraw(Canvas canvas) {
// canvas.drawColor(0x0000000); //if you want another background color
//draw on the canvas
}
}
edit: I believe my problem is needing to pass a pointer to the ghostView canvas. what makes me think that is if I create the children within ghostView then call their .draw method they appear exactly as I would expect.
#Override protected void onDraw(Canvas canvas) {
canvas.drawColor(0x0000000); //if you want another background color
//draw the cards on the canvas
mCard1.draw(canvas);
mCard2.draw(canvas);
}
so at this point I am wondering how to get a reference pointer to the ghostView canvas.
To be honest I am finding the whole Activity - View relationship confusing.
Edit: I have taken a different approach based on detail in this tutorial
http://www.kellbot.com/2009/06/android-hello-circle/
It uses a FrameLayout and it seems I can achieve my objective.
To add view dynamically to view your class must extends from ViewGroup or LinearLayout class then you will able to call method addView.
Inside your ghost view first add a layout e.g Linear or Relative. Then only you could able to add views inside that layout you cant simply add a view to a xml file.
Or you can create a dynamic layout then only u can add view inside that layout.
RelativeLayout relative= new RelativeLayout(findViewById(R.id.your relativeLayoutID));
relative.addView(child);
child could be anything button textview and widget.
I want to make the view move around the screen. Is that possible?
in other words, I want panning to be possible and I think that has something to do with the view.
How do you do Panning a video preview?
If you want to move your view all over the screen, its possible. Presuming this is indeed your requirement, here's what you could do. Make the view a child of Relative Layout. Everytime you want to move the view, get the RelativeLayout.LayoutParams of the child view, change relevent margins and set this as the child view's LayoutParam.
If you are doing this to a SurfaceView (needed to play the video), you get surfaceChanged callback everytime you change the margin.
Here's a sample code of the tweak I did for API Demos' CameraPreview activity which does the same. The SurfaceView is moved from left to right. Hope this helps.
Regards,
Anirudh.
public class CameraPreview extends Activity {
protected static final String TAG = "CameraPreview";
private Preview mPreview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Hide the window title.
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Create our Preview view and set it as the content of our activity.
mPreview = new Preview(this);
mPreview.setId(100);
RelativeLayout mainLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams mainLp = new RelativeLayout.LayoutParams(640, 480);
mainLp.leftMargin = 20;
mainLayout.addView(mPreview, mainLp);
Button btn = new Button(this);
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
RelativeLayout.LayoutParams nLp = (LayoutParams) mPreview.getLayoutParams();
nLp.leftMargin += 10;
Log.v(TAG,"nLp.leftMargin: " + nLp.leftMargin);
mPreview.setLayoutParams(nLp);
}
});
btn.setText("Click me!");
RelativeLayout.LayoutParams btnLp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
btnLp.addRule(RelativeLayout.BELOW, mPreview.getId());
mainLayout.addView(btn ,btnLp);
setContentView(mainLayout);
}
}