A reference to pojo in Android is lost during onClick event - android

I'm developing a small game where I have images that changes and a control panel (some buttons) which the user suppose to press them according to the shown image. The GameView class extends SurfaceView so when the activity starts it just create the game and set the content view (a layout with SurfaceView and some buttons in relative layout). The game call loadGameObjects during setSurfaceSize callback as follow:
public void setSurfaceSize(int width, int height)
{
synchronized (holder)
{
canvasWidth = width;
canvasHeight = height;
GameView.this.postInvalidate();
loadGameObjects(getResources());
}
}
In loadGameObjects method i keep a reference to a game pojo object which is not a view (but holds references to images) as follow:
public void loadGameObjects(Resources resouces)
{
List<GameObject> gameObjects = new LinkedList<GameObject>();
int middleX = getWidth()/2;
int middleY = getHeight()/2;
//Create the backgroung game object
BitmapDrawable background = (BitmapDrawable)resouces.getDrawable(R.drawable.g_monitor);
Bitmap bitmap = Bitmap.createScaledBitmap(background.getBitmap(), getWidth(),
getHeight(), true);
background = new BitmapDrawable(bitmap);
gameObjects.add(new GameObject(this, getContext(), background, new Point(0,0)));
//Create the game object with all its images.
Map<RunningGoblinResourceEnum, BitmapDrawable> goblinImgs = new HashMap<RunningGoblinResourceEnum, BitmapDrawable>();
goblinImgs.put(RunningGoblinResourceEnum.greenGoblinUp, (BitmapDrawable)resouces.getDrawable(R.drawable.goblin_up_green));
//This map get more entries like this...
//ourGoblin is a member var that later will be null in onClick
ourGoblin = new RunningGoblinObject(this, getContext(), goblinImgs,
new Point(middleX, middleY));
gameObjects.add(ourGoblin);
setGameObjects(gameObjects);
}
During doDraw the game objects "draw" method is called to draw themself on the canvas.
My problem is that when I click the button the reference to ourGoblin game object is null although it was valid during loadGameObjects method.
Can someone please tell me what I'm missing?

I had something simillar.
In loadGameObjects method you create ourGoblin instance using the new operator. However, if this is a view in a layout which was used with setContentView the system does not relate your view to the view in the layout and thus from the system point of view the view in the layout is still null until findViewById will be called with this view id. Try to call findViewById on that id and see if ourGoblin is still null, if not then take in mind that you still have two instances of that object, one created using the new operator and one by the system.

Sure,
You can see that it is a very simple and straight forward onClick implementation:
public void onClick(View v)
{
Log.d(getClass().getName() + "onClick", "ourGoblin = " + ourGoblin);
if(ourGoblin == null)
return;
Log.d(getClass().getName() + "onClick", "ourGoblin = " + ourGoblin.getCurrentImageEnum().toString());
int id = v.getId();
switch(id)
{
case R.id.greenUp:
if(RunningGoblinResourceEnum.greenGoblinUp.equals(ourGoblin.getCurrentImageEnum()))
{
//Do something to statistics
}
break;
}
}
and also my layout xml file is as follow:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gameFrame"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.test.game.GameView android:id="#+id/gameView"
android:layout_width="match_parent" android:layout_height="match_parent" />
<RelativeLayout android:id="#+id/controlPanel"
android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:id="#+id/greenUp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_centerInParent="true"
android:text="up"/>
</RelativeLayout>
</FrameLayout>

Related

how to send the front image view to the end of elements and so on for framelayout elements android

I have create a new layout which is type of FrameLayout and I have added four elements of image view I want to take the first image view to the end programmatically
in short reorder the elements of framelayout programmatically. suppose we do that listen to button clickListener
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/framelayout">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#mipmap/a20141008_091817"
android:id="#+id/i1"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#mipmap/a20141008_091819"
android:id="#+id/i2"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#mipmap/a20141008_091821"
android:id="#+id/i3"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#mipmap/a20141008_091823"
android:id="#+id/i4"/>
</FrameLayout>
I appreciated any help.
In this case, it seems you want to re-order the child-views of the FrameLayout. I'd suggest you simply use the ViewGroup, and use getChildAt(some-index), addView(viewToAdd, index-to-place-it) as well as removeViewAt(some-index) to achieve the re-ordering; In my suggested solution - I assume the layout won't change (this can be improved):
ViewGroup viewGroup = (ViewGroup)this.findViewById(android.R.id.content).getRootView();
int first = 0;
int second = 1;
int third = 2;
int fourth = 3;
View view1 = viewGroup.getChildAt(first);
View view4 = viewGroup.getChildAt(fourth);
viewGroup.removeViewAt(first);
//move fourth to first
viewGroup.addView(view4, first);
viewGroup.removeViewAt(fourth);
//move first to fourth
viewGroup.addView(view1, fourth);
View view2 = viewGroup.getChildAt(second);
View view3 = viewGroup.getChildAt(third);
viewGroup.removeViewAt(second);
//move third to second
viewGroup.addView(view3, second);
//move second to third
viewGroup.removeViewAt(third);
viewGroup.addView(view2, third);
I hope this helps you and others. You can also checkout the selected answer in this closely related question and this one, and the selected answer here shows how to re-order views.
first of all. Thanks so much for every one try to help me.
then i figure out my problem in good practice way and I wish to share it with you may any one will need it in future.
the steps
create a frameLayout as in the xml in my question
add your image into frameLayout
create a java file and connect it to the xml
we must to know the ids of all the images into the framlayout
create a timer which will change the order of image in X seconds
get the count of all the images into the framLayout
create Intager var which will determine which is next of image to bring to front
still calling the timer to work in x times as i mentioned
create method to stop the timer if we want in my case I stop the timer in the onPause() method
this is the java file which will do all the above steps. wish it help any one
public class FrameLayout5 extends AppCompatActivity {
FrameLayout frameLayout;
Handler handler; // this class will work as timer for change the order of images in delay
List<Integer> views; // this Array list will store all the ids of all the ImageViews into framelayout
int counter; // this counter will help us to find the next element to bring it to front
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame_layout5);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
frameLayout = (FrameLayout) findViewById(R.id.framelayout);
handler = new Handler();
views = new ArrayList<Integer>();
counter=0;
// get all the children of framelayout
for (int i = 0; i < frameLayout.getChildCount() ; i++) {
views.add(frameLayout.getChildAt(i).getId());
}
handler.postDelayed(runnable, 1000); // 1000 mean that this method will excute every 1 second
}
Runnable runnable = new Runnable() {
#Override
public void run() {
int i=counter%(frameLayout.getChildCount());
counter++;
ImageView a = (ImageView) findViewById(views.get(i));
frameLayout.bringChildToFront(a);
handler.postDelayed(runnable, 1000);
Log.d("run", "called "+i);
}
};
#Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(runnable);
}
}
#ExpensiveBelly
#ishmaelMakitla
What about changing the visibility of the ImageViews to invisible/gone so you just display the one you want to show?

Colors "flowing" in Android background

I have an application and I want to set it's background just like the Instagram's login page, the one with that "gradient colors". The colors are "moving" and it creats a cool effect. This is what I've tried so far:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_take_one);
colorFul = (RelativeLayout) findViewById(R.id.background);
GradientDrawable gd = new GradientDrawable(GradientDrawable.Orientation.TL_BR, new int[] {a,b});
gd.setCornerRadius(0f);
colorFul.setBackgroundDrawable(gd);
for(int i = 0; i<6; i++){
if(a == 0xff000000){
a = 0xff00ffff;
b = 0xff444444;
}else if(a == 0xff00ffff){
a = 0xff888888;
b = 0xff00ff00;
}else if(a == 0xff888888){
a = 0xffcccccc;
b = 0xffff00ff;
}else if(a==0xffcccccc){
a = 0xffff0000;
b = 0xffffffff;
}else if(a==0xffff0000){
a = 0xffffffff;
b = 0xffffff00;
}
System.out.println("||");
SystemClock.sleep(1000);
System.out.println(">");
}
}
But this doesn't work. What happens is that the collors don't change, it remains black until it gets to the last if and then the background become white and yellow(that are, respectively, the collors 0xffffffff and 0xffffff00), in gradient shape.
So, how can I do it? I don't care how it's done. Whether it is with GradientDrawable or using an animated gif as background(which didn't work, the gif remained still) or any other way. Thanks.
(This is what I want, the gif isn't that good but you can see how the background is changing it's color)
You could programmatically create something that changes the level of gradient over time, but that would require some effort. Alternatively, you could use a TransitionDrawable to fade between different gradients, which should produce a similar effect.
This can be implemented as follows:
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- use two gradients, extending from opposite sides of the page-->
<item android:drawable="#drawable/gradientLeft" />
<item android:drawable="#drawable/gradientRight" />
</transition>
Then, you can activate the transition in code as follows:
TransitionDrawable transition = (TransitionDrawable) myLayout.getBackground();
transition.startTransition(1500);
Obviously you'll probably need to spend some time to get it looking the way you want, but this would be far easier than hard-coding a transitional algorithm!
COMPLETE AND WORKING CODE BELOW
So, I got my idea implemented, and it looks awesome! I didn't expect it would look this nice, but it's really cool. I was bored so decided I would shove the whole thing into a function so it's easier for you (and others) to utilize.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView image = (ImageView) findViewById(R.id.background);
Drawable backgrounds[] = new Drawable[3];
backgrounds[0] = ContextCompat.getDrawable(this, R.drawable.gradient1);
backgrounds[1] = ContextCompat.getDrawable(this, R.drawable.gradient2);
backgrounds[2] = ContextCompat.getDrawable(this, R.drawable.gradient3);
Crossfade(image, backgrounds, 10000);
}
public void Crossfade(final ImageView image, final Drawable layers[], final int speedInMs) {
class BackgroundGradientThread implements Runnable {
Context mainContext;
TransitionDrawable crossFader;
boolean first = true;
BackgroundGradientThread(Context c) {
mainContext = c;
}
public void run() {
Handler mHandler = new Handler(mainContext.getMainLooper());
boolean reverse = false;
while (true) {
if (!reverse) {
for (int i = 0; i < layers.length - 1; i++) {
Drawable tLayers[] = new Drawable[2];
tLayers[0] = layers[i];
tLayers[1] = layers[i + 1];
final TransitionDrawable tCrossFader = new TransitionDrawable(tLayers);
tCrossFader.setCrossFadeEnabled(true);
Runnable transitionRunnable = new Runnable() {
#Override
public void run() {
image.setImageDrawable(tCrossFader);
tCrossFader.startTransition(speedInMs);
}
};
mHandler.post(transitionRunnable);
try {
Thread.sleep(speedInMs);
} catch (Exception e) {
}
}
reverse = true;
}
else if (reverse) {
for (int i = layers.length - 1; i > 0; i--) {
Drawable tLayers[] = new Drawable[2];
tLayers[0] = layers[i];
tLayers[1] = layers[i - 1];
final TransitionDrawable tCrossFader = new TransitionDrawable(tLayers);
tCrossFader.setCrossFadeEnabled(true);
Runnable transitionRunnable = new Runnable() {
#Override
public void run() {
image.setImageDrawable(tCrossFader);
tCrossFader.startTransition(speedInMs);
}
};
mHandler.post(transitionRunnable);
try {
Thread.sleep(speedInMs);
} catch (Exception e) {
}
}
reverse = false;
}
}
}
}
Thread backgroundThread = new Thread(new BackgroundGradientThread(this));
backgroundThread.start();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<ImageView android:id="#+id/background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/gradient2"
android:scaleType="fitXY"/>
<TextView android:text="Hello World!" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
gradient1/2.jpg
The primary function here creates a new thread that will automatically begin shifting the two images back and forth. Once one full transition has completed, it will then begin to fade back into the original image. It creates a really smooth and flowy effect most of the time, but may look weird when combining some gradient drawables. The function looks like this:
public void Crossfade(final ImageView image, final Drawable layers[], final int speedInMs)
1) final ImageView image
The first parameter should be the image object that is going to represent your background.
2) final Drawable layers[]
The second parameter takes an array of drawables, which should be two images like the ones I showed above. Playing around with different gradient images is fun, and quite interesting to watch how colors "flow". Be careful with your image sizes, though, as I had initially used massive images that had crashed the app or stuttered terribly in the animation process.
3) final int speedInMs
The last parameter simply represents the time (in milliseconds) it will take to completely transition from the first drawable to the second.
Here's a GIF of the result of these two images crossfading with a speed of 5000ms (note: I couldn't put a 10 second GIF on here showing the whole transition, but it's quite smooth!):
Github Link To Repository
EDIT 2: I updated the Github and the function on here, but I just added in multi-drawable support so an array of any number of images can be added in and it will cycle through them chronologically, until reaching the end at which point it will reverse through and repeat. Sexy.

Using personal SurfaceView on LinearLayout

I'm currently developing an Android App, using a personal SurfaceView and double buffering. However I'm facing a little problem with my code.
In one hand I have an xml view, based on LinearLayout hierarchy. When I instantiate my activity, I set my contentView on this xml. The problem is then that my double buffering don't works anymore. Thread is running but nothing is displayed.
In the other hand, I set my contentView with a new personal SurfaveView element and display works fine. But of course, I cannot access anymore to the other elements of my LinearLayout.
Actually, I would like to set my contentView on my xml view AND keep my display working.
I hope I was clear enough, thank you for your answers!
Here is my activity:
public class MainController extends Activity {
#Override
protected void onCreate(final Bundle p_savedInstanceState) {
super.onCreate(p_savedInstanceState);
setContentView(R.layout.main_controller_activity);
this.drawableView = (MCustomDrawableView) findViewById(R.id.drawingBox);
...
}
...
}
My surface view:
public class MCustomDrawableView extends SurfaceView {
public MCustomDrawableView(Context p_context, AttributeSet p_attributes) {
super(p_context, p_attributes);
this.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(final SurfaceHolder p_holder) {
try {
// Instantiating a new thread
thread = new MBufferingThread(getInstance());
thread.start();
} catch (Exception exception) {
exception.printStackTrace();
}
}
#Override
public void surfaceChanged(final SurfaceHolder p_holder, int p_format, int p_width, int p_height) {...}
#Override
public void surfaceDestroyed(final SurfaceHolder p_holder) {...}
});
// Setup drawing options
setupDrawing();
}
...
}
And my xml view:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:background="#color/app_background"
tools:context=".MainController">
<com.iskn.calligraphy.models.draw.MCustomDrawableView
android:id="#+id/drawingBox"
style="#style/DrawingBox" />
<SeekBar
android:id="#+id/brushSize"
style="#style/SizeSeekBar" />
<SeekBar
android:id="#+id/brushOpacity"
style="#style/OpacitySeekBar" />
</LinearLayout>
EDIT:
After further researches and analyses, it appears clearly that:
setContentView(R.layout.main_controller_activity): in this case I get all the elements from my activity, but the MCustomDrawableView display nothing.
setContentView(new MCustomDrawableView(getApplicationContext())): on that case, MCustomDrawableView is working well (it displays what I want), but I don't have the others View from my main_controller_activity
In both cases:
my thread is running and works well.
my drawing function is called as well, with the holder.lockCanvas() and holder.unlockCanvasAndPost(bufferCanvas) methods.
Well, I found a functionnal solution :
I think the problem was coming from the MCustomDrawableView initialization . I created a new instance of that class from the onCreate method , and not from the xml file . Then, I set it to the contentView:
protected void onCreate(Bundle p_savedInstanceState) {
super.onCreate(p_savedInstanceState);
setContentView(R.layout.main_controller_activity);
// Instantiate drawable object & set style properties
this.drawableView = new MCustomDrawableView(getApplicationContext());
FrameLayout.LayoutParams style = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
// Add the drawable view to the main_activity
addContentView(this.drawableView, style);
}
But this way raises a new problem. The added view is on the top, which means that all the others View are hided. I solved this with bringToBack(this.drawableView) below method:
private void bringToBack(View p_view) {
// Get parent from the current view
ViewGroup viewGroup = ((ViewGroup) p_view.getParent());
int childrenCount = viewGroup.indexOfChild(p_view);
for(int cpt = 0; cpt < childrenCount; cpt++) {
// Move the child to the top
viewGroup.bringChildToFront(viewGroup.getChildAt(cpt));
}
}
It brings back the provided view to the background position. I also had to set the LinearLayout's alpha to 0.
I'm still open to other solutions!

Simple fade-out animation for a string on canvas, android

I have a custom view extending from View with lots of text drawn at different angles and I want a particular string to decrease its alpha value to a certain level once, after first start. Any suggestion or snippet would be appreciated :)
postInvalidateDelayed(...) doesn't seem to work for this task.
One possibility might be to create two views, inside of a FrameLayout that overlap each other. One view would contain all the static strings, the other the string you want to animate. Then it would be a simple matter of adding an alpha animation to the animated view.
<?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" >
<package.MyNonAnimatedView
android:id="#+id/nonAnimatedView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<package.MyAnimatedView
android:id="#+id/animatedView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
And for an animation you would attach to the animated view:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator"
android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="100" />
From within your activity's onCreate(Bundle) method, you can call AnimationUtils.loadAnimation(Context, int) to load the animation from the xml resource and attach it to the animated view (provided you give it an id).
You can add a Handler to your activity that can send messages at a specified interval. When your activity receives a callback from the handler, it can notify the view to update the parts that you want to change.
An example:
public class myActivity extends Activity implements Handler.Callback {
int mDelay = 100; // Update interval (milliseconds).
Handler mHandler = new Handler(this);
private Runnable mEvent = new Runnable() {
#Override
public void run() {
mHandler.postDelayed(mEvent, mDelay);
Message message = mHandler.obtainMessage();
// Add arguments to message, if required.
mHandler.sendMessage(message);
}
};
#Override
public boolean handleMessage(Message message) {
// Your view update code.
}
private void start() {
mHandler.postDelayed(mEvent, mDelay);
}
private void stop() {
mHandler.removeCallbacks(mEvent);
}
}
Calling start() starts the handler, stop() stops it. Determining when to stop the handler will probably be in the handleMessage(Message) code.
There was a mistake in the correct measurement of vertical text bounds to be faded. Here is my onDraw method
Paint myPaint = new Paint();
myPaint.setColor(Color.parseColor("#" + colorAlpha + "3AA6D0"));// initially colorAlpha is ff
Rect r = new Rect();
char[] a = "Hello World".toCharArray();
datePaint.getTextBounds(a, 0, a.length, r);// get the bound of the text, I was not calculating this correctly
canvas.drawText("Hello World", 0, 0, myPaint);// draw the text
int colorValue = Integer.parseInt(colorAlpha, 16);
colorValue -= 20;// decrease alpha value for next call to onDraw method by postInvalidateDelayed
if (colorValue > 40) {
colorAlpha = Integer.toHexString(colorValue);
// this will create the effect of fade out animation
// because each call to onDraw method is at the difference of 50 millisecond delay
// and in each call we are decreasing alpha value by 20.
postInvalidateDelayed(50, r.left, r.top, r.right, r.bottom);
}

How to add view components dynamically from activity

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.

Categories

Resources