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.
Related
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.
I am using FirestoreRecyclerAdapter to make a chat app in java. When adding a message it works fine but I want messages to show at bottom not on top. I tried
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
Now it reverse it's position which is good but it's not automatically scrolling to bottom position. And when I add a new message I need to scroll manually to see it.
Recyclerview automatically scroll to bottom after adding below lines
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
recyclerView.smoothScrollToPosition(0);
}
});
}
}, 1000);
above solution will not work if parent layout is horizontal scroll.
Other solution is
recyclerView.scrollToPosition(0);
Both line of code work for me. you can use any of the solution
The best way to do it is use the following piece snippet whenever there is a new message. You can use a snapshot listener for that
y = (Here you need to try 2 things. My coding laptop is not with me so I cannot test and tell but either 0 should work or the chatlist.size()-1);
layoutManager.scrollToPosition(y);
OR
layoutManager.smoothScrollToPosition(y);// I do not recommend this for chat apps since it will take time to go down if there are a lot of texts below the user
This is what I used:
#Override
public void onStart() {
super.onStart ();
adapter.startListening();
recyclerView.scrollToPosition (0);
}
Also use
#Override
public void onDataChanged() {
super.onDataChanged ();
recyclerView1.smoothScrollToPosition (0);
}
in adapter
I was using
recyclerView.scrollToPosition (0);
in onCreate and adapter was starting in onStart. Now it's working
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.
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.
I use an BaseAdapter to display a list of objects. This objects are fetched from a server. The getView() method of the BaseAdapter is the following:
/* (non-Javadoc)
* #see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout content = (LinearLayout) View.inflate(lexs, R.layout.favorite_item, null);
LinearLayout paragraphView = new LinearLayout(lexs);
paragraphView.setBackgroundColor(Color.RED);
paragraphView.setGravity(Gravity.CENTER_VERTICAL);
paragraphView.setOrientation(LinearLayout.HORIZONTAL);
ImageView img = new ImageView(lexs);
img.setImageResource(R.drawable.down);
paragraphView.addView(img);
img.setPadding(0, 0, 5, 0);
img.setOnClickListener(new WorkspaceOnClickListener(position));
TextView text = new TextView(lexs);
text.setTextColor(Color.WHITE);
text.setText(favorites.get(position).getParentChapter().getBook().getName() + ": §" + favorites.get(position).getName());
text.setOnClickListener(new ParagraphOnClickListener(position));
DisplayMetrics metrics = new DisplayMetrics();
lexs.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int maxWidth = metrics.widthPixels - 100;
text.setMaxWidth(maxWidth);
text.setMinWidth(maxWidth);
paragraphView.addView(text);
ImageView imgClose = new ImageView(lexs);
imgClose.setMinimumHeight(30);
imgClose.setMinimumWidth(30);
imgClose.setImageResource(R.drawable.close);
imgClose.setPadding(5, 0, 0, 0);
paragraphView.addView(imgClose);
imgClose.setOnClickListener(new CloseListener(position));
content.addView(paragraphView);
content.setPadding(0, 0, 0, 10);
if (favorites.get(position).isExpanded()) {
LinearLayout textLayer = new LinearLayout(lexs);
textLayer.setBackgroundColor(Color.rgb(214, 214, 214));
LinearLayout left = new LinearLayout(lexs);
left.setOrientation(LinearLayout.VERTICAL);
ImageView moveUp = new ImageView(lexs);
moveUp.setImageResource(R.drawable.move_up);
moveUp.setOnClickListener(new MoveListener(UP, position));
moveUp.setPadding(0, 0, 0, 10);
left.addView(moveUp);
ImageView moveDown = new ImageView(lexs);
moveDown.setImageResource(R.drawable.move_down);
moveDown.setOnClickListener(new MoveListener(DOWN, position));
left.addView(moveDown);
TextView paragraphText = new TextView(lexs);
paragraphText.setText(favorites.get(position).getText());
paragraphText.setTextColor(Color.BLACK);
LinearLayout right = new LinearLayout(lexs);
right.setOrientation(LinearLayout.HORIZONTAL);
right.addView(paragraphText);
textLayer.addView(left);
textLayer.addView(right);
content.addView(textLayer);
img.setImageResource(R.drawable.up);
}
return content;
}
}
So I'd like that this whole method is called in background and during the method is executed, a ProgresDialog is shown. I defined the ProgressDialog the following way:
public class LoadingInformation {
private static ProgressDialog progressDialog;
public static void showProgressInformation(Context view) {
progressDialog = ProgressDialog.show(view, "Please wait...", "Doing Extreme Calculations...", true);
System.out.println("Start Loading Screen");
}
public static void stopShowingProgressInformation() {
Handler handler=new Handler();
handler.post(new Runnable(){public void run(){progressDialog.dismiss();}});
System.out.println("Stop Loading Screen");
}
}
But the problem is, i don't know how to implement the calls correctly. I tried to replace all lines:
adapter.notifyDataSetChanged();
With the following code:
public void updateFavoriteList() {
LoadingInformation.showProgressInformation(lexs);
new Thread() {
public void run() {
lexs.runOnUiThread(new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
LoadingInformation.stopShowingProgressInformation();
}
});
}
}.start();
}
But unfortunately this doesn't work as expected. Has anybody a hint how to do it betteR?
The getView() method of the adapter isn’t responsible for downloading the content in the list, all it does is build the current row being displayed in the ListView. getView() doesn’t have anything to do with actually downloading the data from a network resource, which is where you wan’t the ProgressDialog.
When you instantiate the adapter (not shown in your code) you pass the data you want your BaseAdapter to populate the ListView with. Either the data has already been downloaded and simply handed off to the adapter, or the adapter itself does in the constructor.
If you wan’t the dataset for your ListView to change, you’re going to have to create some setter method or have a method in the adapter that refreshes the dataset from the network automatically. In any case though, this is where you want the ProgressDialog to show, not while the getView() method is setting up the ListView row.
P.S. One other suggestion I'd give is to make use of the convertView param passed to getView(). It'll improve the performance of your list by a lot if you have a large list. Check out Romain Guy's presentation about ListView in either the Google I/O 2009 or 2010 talks.
EDIT:
So “favorties” is an array (or List, etc.) of data for your ListView. You most likely pass the “favorites” data to the adapter via a constructor argument. At that point the data already exists in the adapter, or you’re passing a network location so the adapter can fetch the data and display it in the ListView.
For simplicity sake, lets say you download some string data into a String array, before passing it to the adapter. Each element contains a string to be displayed in your ListView via a TextView. You pass that array to the adapter and it handles formatting the ListView for you with the logic in the getView() method.
Now while you are downloading the data to populate the ListView with, you want to show the ProgressDialog to let the user know something is happening. Like some people have already said, you would use an AsyncTask to accomplish this. AsyncTask will allow you to display a ProgressDialog via onPreExecute() while you actually download the data in doInBackground() and get rid of the dialog in onPostExecute().
I hope that makes sense.
The time consuming tasks should be handled with an AsyncTask.
Read https://developer.android.com/resources/articles/painless-threading.html
It has been added to the Android framework to help you do these time consuming things and update progress dialogs without having to code the boilerplate of Tasks and Handlers yourself.