I am developing an app that requires multiple buttons to be created dynamically (onCreate of MainActivity class). Each button has a dimension of 100x100dp.
Here's the code:
for (int i = 0; i < count; i++) {
buttons[i] = new Button(this);
RelativeLayout ll = (RelativeLayout)findViewById(R.id.maincontainer);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
buttons[i].setY(i * 150); // should be random
buttons[i].setX(i * 120); // should be random
String temp = Character.toString(input.charAt(i));
buttons[i].setText(temp);
buttons[i].setOnClickListener(this);
buttons[i].setId(i);
test1.setText(Integer.toString(buttons[i].getId()));
ll.addView(buttons[i],lp);
}
The position of these buttons should be completely random within the layout which can be easily achieved by generating random values for x and y coordinates. But I need the buttons not to overlap other buttons. Also due to 100x100dp dimension, sometimes the previously generated buttons are being partially overlapped by new ones.
You can actually figure this out programatically. Keep the co-ordinates of the views that you generate stored in a list. Then simply compare the co-ordinates to see if the new view intersects. You can use the following for a visualisation:
http://silentmatt.com/rectangle-intersection/
I hope you try writing code than copying it from someplace. :)
A SO link to help you out: Determine if two rectangles overlap each other?
Related
I am trying to make a game with multiple levels. My plan is to print 15 levels on 1 page. I have attached a photo of the simple design I am currently using.
As you can see in the picture the right border of a button is not showing. For the parent I am using this java code:
LinearLayout horl = new LinearLayout(this);
horl.setId(worldVar);
horl.setOrientation(LinearLayout.HORIZONTAL);
horl.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
And to set 3 buttons horizontally in this LinearLayout I use this code for the buttons. This code just has a simple for loop around to put 3 buttons in this LinearLayout:
Button button = new Button(this);
LinearLayout.LayoutParams params = new LinearLayout
.LayoutParams(getMarginInDp(100), getMarginInDp(100));
params.setMargins(getMarginInDp(1), getMarginInDp(25), getMarginInDp(1), 0);
button.setLayoutParams(params);
GradientDrawable gd = new GradientDrawable();
gd.setCornerRadius(5);
gd.setStroke(1, 0xFF000000);horl.addView(button);
The function getMarginInDp looks like this:
public int getMarginInDp(int dp){
return (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
Does anybody have any idea how to make the border appear because I want to keep the buttons approximately this size and I may even slightly increase the margins?
You can set the weight to 0.33f for each button:
Button button = new Button(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getMarginInDp(100), getMarginInDp(100), 0.33f);
so they are distributed equally in the width of the layout.
I want to create a Card Deck app that contains (lets say) from 0 to 10 total cards as it runs.
I have a RelativeLayout created with XML inside a parent layout, this RelativeLayout has width to match parent and height to wrap content.
Now i want to add fixed size buttons (cards) to that layout and when the don't have room they must not deformate but be scaled and placed on top of the other.
When i just add them it happens this:https://postimg.org/image/ic8pmaju7/
But i want to achieve something like this :https://postimg.org/image/567dj49j9/
*For second image i used setmargins(xleft,x,x,x);...xleft++; , but when i have 2 or 5 buttons they keep being on the top of the other button, instead of just use the free space.
So im asking if there is a layout or a method that when there is no room (small screen or too many buttons) puts buttons on top and next of the other button than deforming them.
ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It's similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use with Android Studio's Layout Editor.
Using the ConstraintLayout you can do it, and spending less user processing than if you use nested LinearLayouts.
To put button next to button and adjust them in according to screen size, you can use the Chains, that is a resource of ConstraintLayout.
Chains provide group-like behavior in a single axis (horizontally or vertically). The other axis can be constrained independently.
Click here to read more about ConstraintLayout and Click here to read more about Chains.
Ok, guys i tryied what you suggested but i couldnt't achieve what i wanted, so i spent HOURS working on it and i ended up with some math and some help of fuctions to (at last) find the solution. I will post my code if someone wants to give a try:
public void ChangeView(View view) {
//here we put number of cards that we want to be scaled and displayed (cards=buttons)
int CardMax=13;//13 for example!!!
//getting scale for dpi of phone screen(i think??)
final float scale = getResources().getDisplayMetrics().density;
// getting some values we need to know
// **THESE VALUES DEPEND FROM SCREEN RESOLUTION OR THE SIZE OF BUTTON**
int layWidth = layout.getWidth(); //getting layout width that equals screen width(in pixels)
int btnWidth = (int) (50 * scale); //setting and scaling the width of the button for any screen
int maxLayfit=layWidth/btnWidth; //getting how many buttons can be added to layout without deformation
int layMidWidth = layWidth / 2; //getting layouts half width (that helps to start adding buttons from middle)
int StrMeasur; // this help how to start setting the buttons
if (CardMax <= maxLayfit) { // if cards are less than Layout can hold without deformation
StrMeasur = CardMax; // StrMeasur equals number of cards
} else {
StrMeasur = maxLayfit; // else equals max number of cards without deformation
}
int pointer=0; //pointer that will say where to put the first button
pointer = layMidWidth - ((btnWidth / 2) * StrMeasur);//depends of how many cards we have and button width
int start =layMidWidth-((btnWidth / 2) * StrMeasur);
int nextBtn = 0; //nextBtn says where to put the next button
//here we set the buttons on top and next to the previous button as we need **TRICKY PART**
if (CardMax > maxLayfit-1) { //if number of cards is bigger than the number the layout can hold
//then we calculate first card position (start/pointer) and the last card position(=layout width-button width)
//we find how many equal parts the layout has to be divided with the given cards
//and we get the width of the part to set it as pointer of the next card place
nextBtn =(((layWidth-start)-btnWidth)-start)/CardMax;
}else{
nextBtn=btnWidth; //else the pointer just set buttons next to the other
}
//Here we display all the buttons
for (int i = 0; i < CardMax; i++) {
Button cards = new Button(this);
cards.setWidth(btnWidth);
cards.setHeight((int) (90 * scale));
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params2.setMargins(pointer, 0, 0, 0);
cards.setLayoutParams(params2);
cards.setText("" + (i + 1));
cards.setId(i);
layout.addView(cards);
pointer = pointer + nextBtn;
}
}
I belive it will work on any screen.
I'm making an app exclusively for android tablets and part of it has buttons dynamically created based on various news headlines. I have a single dimens.xml and I use the scaling factor from DisplayMetrics to make the sizes appropriate for different densities. The problem is that when I change the size in my xml it has absolutely no effect on the dimension that the method returns.
RelativeLayout.LayoutParams announcementButtonLayout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
announcementButtonLayout.topMargin = topMargin;
announcementButtonLayout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
announcementButtonLayout.height = this.getResources().getDimensionPixelSize(R.dimen.news_button_height);
announcementButtonLayout.width = getResources().getDimensionPixelSize(R.dimen.dashboard_right_width);
Button button = new Button (this.getActivity());
button.setWidth(getResources().getDimensionPixelSize(R.dimen.dashboard_right_width));
button.setBackgroundResource(R.drawable.photo_edited);
button.setTextColor(getResources().getColor(R.drawable.news_poll_item_text_color));
float f =Utilities.getPixelScaleMultiplier();
f *= getResources().getDimension(R.dimen.news_item_text);
button.setTextSize(f);
button.setText(announcement.getDescription());
button.setMaxLines(1);
button.setTag(announcement);
button.setOnClickListener(this);
button.setLayoutParams(announcementButtonLayout);
button.setId(index);
Based on my button code above, what could be causing this breach of trust?
Thanks,
Adurnari
EDIT: Included my LayoutParams as reference
Found the solution:
"Cleaning" was taking the values that I had changed in my xml and adding them on a later portion of the page where they were located previously. The lower ones were dictating the size.
Try to work with button.setBounds
Use LayoutParams to set view width and height, then add it to viewgroup.
Button button = new Button (this.getActivity());
//button.setWidth(getResources().getDimensionPixelSize(R.dimen.dashboard_right_width));
button.setBackgroundResource(R.drawable.photo_edited);
button.setTextColor(getResources().getColor(R.drawable.news_poll_item_text_color));
float f =Utilities.getPixelScaleMultiplier();
f *= getResources().getDimension(R.dimen.news_item_text);
button.setTextSize(f);
button.setText(announcement.getDescription());
button.setMaxLines(1);
button.setTag(announcement);
button.setOnClickListener(this);
LayoutParams announcementButtonLayout = new LayoutParams(getResources().getDimensionPixelSize(R.dimen.dashboard_right_width), LayoutParams.WRAP_CONTENT);
button.setLayoutParams(announcementButtonLayout);
button.setId(index);
Clean the project after changing dimens.xml value, maybe the R file is not getting updated in your case.
So I'm new to java, and I have the basics of object placement down. I'm trying to design an app in which 5 objects are randomly placed in a certain activity. How would I go about randomly placing these objects?
Thanks!
Create a custom view that overrides the onDraw method.
Use Math.random or some other random number generating scheme to determine the x and y values of the bitmaps you are going to draw.
Then use Canvas.drawBitmap
you can programmatically add your buttons to your activity with random position without using xml layout and here an example set buttons in activity
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
Button okButton=new Button(this);
okButton.setText("some text");
Random r = new Random();
okButton.setPadding(r.nextInt(), r.nextInt(), r.nextInt(), r.nextInt())
ll.addView(okButton, layoutParams);
and here good thread to look at
Set margins in a LinearLayout programmatically
I am trying to make an app that lets the user store and saves contacts. It can save, but it has problems listing.
I have a for loop that runs through the database and prints a set of data for each contact (each row), an image (actually its a string because it passes the path) and a string. It prints them in a scrollview with a linear layout for each contact (each contact has a linear layout of its own, so that i can let one contact occupy a row each). The images come out, however, the textviews are nowhere to be found.
Using log.d(textview.getText()); it confirms that the textviews are created and take up space.
http://chesnutcase.heliohost.org/derpbox/itv1.png
Two "contacts" with names, not printed out. The space inbetween is presumbly by the textview.
http://chesnutcase.heliohost.org/derpbox/itv2.png
Another two "contacts", but without names. The dont have a space between each other. Or at least, a significantly smaller space.
Code:
DatabaseHandler db = new DatabaseHandler(this);
int a = (int) (long) db.countRows();
LinearLayout theLayout = (LinearLayout)findViewById(R.id.contactsList);
for(int i = 0;i<a;i++){
ImageButton image = new ImageButton(this);
int density=getResources().getDisplayMetrics().densityDpi;
LinearLayout.LayoutParams vp = new LinearLayout.LayoutParams(density,density, 0.5f);
image.setLayoutParams(vp);
image.setScaleType(ImageView.ScaleType.FIT_END);
int b = a - i;
try {
image.setImageBitmap(decodeUri(Uri.parse(db.getContactData("photo_path")[i])));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
theLayout.addView(image);
TextView tv = new TextView(this);
tv.setText(db.getContactData("name")[i]);
Log.d("UserLog","name is " + db.getContactData("name")[i]);
Log.d("UserLog","textfield contains " + tv.getText());
LinearLayout.LayoutParams vp2 = new LinearLayout.LayoutParams(0,0,1f);
tv.setLayoutParams(vp2);
tv.setBackgroundColor(Color.RED);
theLayout.addView(tv);
}
Any solutions? Thanks in advance
Double check which orientation you've applied to the LinearLayout of your contacts list.
You are setting bad LayoutParams to your TextView. You're making your TextView 0px by 0px with a weight of 1.
LinearLayout.LayoutParams vp2 = new LinearLayout.LayoutParams(0,0,1f);
tv.setLayoutParams(vp2);
Try using one of the MATCH_PARENT or WRAP_CONTENT constants. They're listed here: http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#MATCH_PARENT
If you want your TextView to take up the remaining width of the screen I would leave the weight as 1, the width as 0, but you need to set the height to a constant like WRAP_CONTENT.
You're also setting the size of your ImageView to the device screen density (which is a constant) instead of setting a scaling size based off your screen density.
You probably need to call requestLayout(); in order to update the current view layout.
theLayout.requestLayout();
Also it seems you are creating a view with 0 width and 0 height with that layout params:
LinearLayout.LayoutParams vp2 = new LinearLayout.LayoutParams(0,0,1f);
It is better to use ListView for such list.
You will need to write only one Adapter, that's represent logic for creating one row on list.
I would recommend using a CursorAdapter and a layout xml file, this way you can design it to look exactly how you want, and preview it. It is a lot easier than setting all those fiddly LayoutParams
If you have to create them dynamically you may find the text colour is the same as the background, try setting it to something visible like bright red for testing. If you still don't see the text it may be that it's visibility isn't set to View.VISIBLE finally the layout may not be the correct size, a handy tip for this is set the background to a suitably eye catching colour, even if there is no text you should see a shaded block.