Crash when using Handler/addView in Android Studio - java

so basically i have 2 problems.. 1st problem is the handler and runnable..
i have an image and i want to make it move..
so i wrote this
ImageView a = findViewById(R.id.os);
final Handler handler = new Handler();
final Runnable run = new Runnable() {
#Override
public void run() {
float y = a.getY();
if(y > layout.getHeight())
y=0;
else
y+=7;
handler.postDelayed(this,3000);
a.setY(y);
}
};
handler.post(run);
when i run it, the app crashes...my layout is ConstraintLayout.
and i wrote this code in a method "onClick" so after clicking the button the image starts moving.
..
2nd Problem : i want to add alot of objects (enemies etc to make a game) but the problem if I do that using XML it will take a long time. imagine adding 200 objects and what if I wanted to repeat adding them after they get removed or changing their attributes ? i will need to define an id for all them and create objects in reference to their id's all of them ...so I needed to figure out how to add objects programmatically to the ConstraintLayout..so i Wrote this:
ArrayList<ImageView> bosses=new ArrayList<>();
ConstraintLayout d = findViewById(R.id.layout);
for(int i =0;i<200;i++) {
bosses.add(new ImageView(this));
ConstraintLayout.LayoutParams lay =
new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
lay.startToStart= d.getId(); lay.endToStart= d.getId();
lay.topToTop = d.getId(); lay.bottomToTop=d.getId();
bosses.get(i).setLayoutParams(lay);
d.addView(bosses.get(i));
}
and it crashes too....I'm trying to learn how to move objects and how to add them programmatically so I can create games but i keep facing these crashes. if anyone could help I'll be thankful.

Related

Move code into my RecyclerAdapter to prevent NPE

I have this piece of code inside my MainActivity , what I'm trying to do is to tint a background for an element, it works nice, but the handler is not supposed to do the job of waiting when the views are all inflated, so, I want to move this code inside my onBindViewHolder but Im kinda lost, any hint ?
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
for (int i = 0; i < mArrayListSelectedTAGS.size(); i++) {
View view = mRecyclerView.getLayoutManager().findViewByPosition(mArrayListaTAGs.indexOf(mArrayListSelectedTAGS.get(i)));
view.setBackgroundColor(getApplicationContext().getResources().getColor(R.color.colorVincular));
}
}
}, 500);
Te question is, how do I get the exact view on my onBindView holder in order to tint it, and how to call it from MainActivity
thanks
For those having the same issue , I just solved this with a simple Interface, in my onBindViewHolder, after I bind all my views, I call an interface named onBindFinished(boolean isFinished);
after that in my adapter I just set that value to true if the onBind have finished
and in my class the only thing I do is checking if onBindFinished is true I just paint the views.

Creating buttons dynamically on android

i'm trying to create buttons dynamically though code using a linear layout to set one button after the other, my code runs doesn't give any errors, nor throwing any exceptions or anything, but all i get is an empty screen. Thanks in advance.
private void runThreadCreateButton(final List<Stop> stops) {
new Thread() {
public void run() {
int i=0;
while (i++ < 1) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
for(int j=0;j<stops.size();j++)
{
Button myButton = new Button(getApplicationContext());
myButton.setText(stops.get(j).getName());
LinearLayout ll = new LinearLayout(getApplicationContext());
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
}
}
});
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}.start();
}
you create a new Layout, but you Activity is not set to show your layout. Call setContentView() on your Main Activity with your new layout.
LinearLayout ll = new LinearLayout(getApplicationContext());
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
//add something like this
yourMainActivity.setContentView(ll);
Well, if you didn't add your layout to your activity this was your main problem.
However you should learn about composing your layouts in xml. This makes your code a lot more readable and maintainable. Also you don't need to worry about switching Threads all the time.
If you need to populate your views with runtime data, you should use list views and list adapters. ListViews and ListAdapters are essentials to almost every android app, so you you should really learn about them. If you want your list items to hold more complex layout you can do so by implementing your own custom list adapters.
There are also lots of performance tweaks you can do, when using list views.
For most use cases generating and managing your layout from code is not a good approach.

Getting series from doughnut chart - achartengine

I am using a doughnut chart through achartengine and it is working fine except I can't figure out how to get the values associated with the region a user clicks on. It is my understanding through reading other questions that this is possible but the posted fixes aren't working for me. I have tried an onClick/Touch listener using getCurrentSeriesAndPoint but this always returns null. Here is my code:
final GraphicalView gV = new DoughnutChart().getView(getBaseContext(),
regionNames, regionSizes);
gV.setClickable(true);
gV.setFocusable(true);
gV.setOnClickListener( new OnClickListener() {
#Override
public void onClick(View arg0) {
SeriesSelection selection = gV.getCurrentSeriesAndPoint();
double[] xy = gV.toRealPoint(0);
if (selection == null) {
//update
} else {
//update
}
}
});
Let me know if there is any more information I can add.
My end goal will be to extract the name of the region clicked and then call another activity with that name to display more information about it.
The click and get selection is currently implemented for XYChart(line, bar,...) and for the PieChart, so there is no such support for the DoughnutChart yet.

Admob integration failing thread to work properly on AndEngine based app

I'm building an android game powered by AndEngine game framework.
I'm using the following code to inegrate with Admob:
#Override
protected void onSetContentView() {
mRenderSurfaceView = new RenderSurfaceView(this, mEngine);
mRenderSurfaceView.applyRenderer();
setContentView(R.layout.main);
final FrameLayout frameLayout = new FrameLayout(this);
final FrameLayout.LayoutParams frameLayoutLayoutParams =
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.FILL_PARENT);
AdView adView = new AdView(this, AdSize.BANNER, "XXXXXXX");
adView.refreshDrawableState();
adView.setVisibility(AdView.VISIBLE);
final FrameLayout.LayoutParams adViewLayoutParams =
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);
AdRequest adRequest = new AdRequest();
adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
adRequest.addTestDevice(Secure.ANDROID_ID);
adView.loadAd(adRequest);
final android.widget.FrameLayout.LayoutParams surfaceViewLayoutParams =
new FrameLayout.LayoutParams(super.createSurfaceViewLayoutParams());
frameLayout.addView(this.mRenderSurfaceView, surfaceViewLayoutParams);
frameLayout.addView(adView, adViewLayoutParams);
this.setContentView(frameLayout, frameLayoutLayoutParams);
}
in the game, when a ball is created it makes a fading-in animation
I made with a thread:
new Thread(new Runnable() {
public void run() {
mBody.setType(BodyType.StaticBody);
mSprite.setAlpha(0.0f);
try {
while(mSprite.getAlpha() < 1.0f) {
mSprite.setAlpha(mSprite.getAlpha() + 0.01f);
Thread.sleep(3);
}
mBody.setType(BodyType.DynamicBody);
mBody.setLinearVelocity(new Vector2(0, 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
The problem is:
the animation works perfectly, BUT
when I'm adding the Admob code the Sprite appears for a second
and then, just disappearing.
it seems to me there is a problem between this two "chunks" of code.
but I can't put my finger on the solution or even what causing this problem to occur.
I only know that the animation is not working when the Admob code is combined in my app.
I'd like to know why and how to solve it.
thank you guys
This could be completely unrelated, but I had a problem with randomly disappearing Sprites recently, though not connected with Admob. The problem went away when I added the following line to the place where I set the Engine up:
engineOptions.getRenderOptions().disableExtensionVertexBufferObjects();
I recommend you to use an XML file to put your admin. Its cleaner, easy to use and according to my own tests it is faster than overriding onsetcontentview. In order to achieve that you need to extend LayoutGameActivity (there is also a simple version of that class. SimpleLayoutActivity if I'm not wrong)
I'll improve the answer when I get a computer.

Why does LinearLayout child getWidth method return 0?

I have a LinearLayout, and this LinearLayout will hold dynamically placed views. I need to find out what the width of the children of LinearLayout, however this has to be done in onCreate method. From researching I've found out that you can't use getWidth from this method. So instead I'm using onWindowFocusChanged, which works for the parent LinearLayout (returning me the actual size), but it doesn't work with its children.
Another thing I noticed is that when the screen is fading away and the screen is locked, I can see at the logs the actual width of the children being returned (I think the activity is being paused).
I'm really stuck and this is needed because I need to dynamically place those views depending on the children width.
You might be able to get with the below. But as others pointed out, this probably isn't a great idea.
LinearLayout.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
LinearLayout.getMeasuredWidth();
inside the onCreate , views still can't know the state of the nearby views and the children ,etc... so only after all is prepared and the layout process is done , you can get the size of views .
here's a quick code for getting the size of the view just before it's being drawn:
private static void runJustBeforeBeingDrawn(final View view, final Runnable runnable)
{
final ViewTreeObserver vto = view.getViewTreeObserver();
final OnPreDrawListener preDrawListener = new OnPreDrawListener()
{
#Override
public boolean onPreDraw()
{
Log.d(App.APPLICATION_TAG, CLASS_TAG + "onpredraw");
runnable.run();
final ViewTreeObserver vto = view.getViewTreeObserver();
vto.removeOnPreDrawListener(this);
return true;
}
};
vto.addOnPreDrawListener(preDrawListener);
}
alternatively , you can use addOnGlobalLayoutListener instead of addOnPreDrawListener if you wish.
example of usage :
runJustBeforeBeingDrawn(view,new Runnable()
{
#Override
public void run()
{
int width=view.getWidth();
int height=view.getHeight();
}
});
another approach is to use onWindowFocusChanged (and check that hasFocus==true) , but that's not always the best way ( only use for simple views-creation, not for dynamic creations)
EDIT: Alternative to runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126
https://stackoverflow.com/a/3594216/1397218
So you should somehow change your logic.

Categories