I got a problem with my for loop / with its content.
I want to have this loop in which an image is repeated n times.
In addition these images should have margins at the top so they have some space between each other.
For now these images are laying on top of each other or won't be generated as they should (Result: Drawable "bg_circle" is only displayed once).
The "userinput" will be filled from an EditText in an Alert Dialog.
Here is my code:
int n = Integer.parseInt(userInput.getText().toString());
RelativeLayout layout = findViewById(R.id.TableView);
for(int i = 0; i <= n; i++){
ImageView image = new ImageView(mContext);
image.setImageResource(R.drawable.bg_circle);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(100,100,0,0);
lp.height = 100;
lp.width = 100;
image.setLayoutParams(lp);
layout.addView(image);
}
Where is the mistake?
Use LinearLayout with vertical orientation instead of RelativeLayout. Also, you should use a ScrollView as root element of the layout:
<ScrollView ...>
<LinearLayout android:orientation="vertical" ...>
... programmatically added images...
</LinearLayout>
</ScrollView>
Related
Here's an image of what my issue looks like:
That box at the bottom is the top half of a button. Whenever I've got too many Stock Options in the dialog box, it first forces the button off screen, THEN it scrolls.
I want the button fixed at the bottom of the dialog and then have the scrolling happen.
Here's the code:
public void buyStock(View view){
Context context = getApplicationContext();
//create ScrollView to hold everything
ScrollView scrollView = new ScrollView(context);
//generate content for dialog
LinearLayout dialogContainer = new LinearLayout(context);
dialogContainer.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 400, 1);
dialogContainer.setLayoutParams(params);
dialogContainer.setPadding(15, 15, 0, 15);
dialogContainer.setBackgroundColor(Color.WHITE);
//each hotel stock options
for (int i = 0; i < hotels.size(); i++) {
Hotel testHotel = hotels.get(i);
testHotel.setPrice(200);
View stockPicker = getStockPicker(testHotel);
LinearLayout.LayoutParams pickerParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 100, 1.0f);
pickerParams.gravity = Gravity.LEFT;
stockPicker.setLayoutParams(pickerParams);
dialogContainer.addView(stockPicker);
stockPicker.setBackgroundColor(0xffffff);
}
scrollView.addView(dialogContainer);
LinearLayout dialogLayout = new LinearLayout(context);
dialogLayout.setOrientation(LinearLayout.VERTICAL);
Button buyButton = new Button(context);
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 100);
buyButton.setLayoutParams(buttonParams);
LinearLayout buttonLayout = new LinearLayout(context);
buttonLayout.addView(buyButton);
dialogLayout.addView(scrollView);
dialogLayout.addView(buttonLayout);
ContextThemeWrapper ctw = new ContextThemeWrapper(this, R.style.AppTheme);
AlertDialog.Builder buyStockDialog = new AlertDialog.Builder(ctw);
buyStockDialog.setTitle("Buy Stock: ");
buyStockDialog.setView(dialogLayout);
buyStockDialog.show();
}
Make dialogLayout a RelativeLayout, and then declare buttonParams as a RelativeLayout.LayoutParams (layout params are declared according the parent viewgroup type, which for buyButton is now a RelativeLayout). Your also going to need to declare a RelativeLayout.LayoutParams for scrollView.
note: This code is in c#/monodroid, not raw java/android, so some quick porting of some of the methods and constants may need to be required, but shouldn't be too time consuming.
If this doesn't work out exactly trying experimenting with other combinations of the RelativeLayout position rules and/or gravity. Let me know if it doesn't work out.
RelativeLayout.LayoutParams scrollParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, some_height);
RelativeLayout.LayoutParams buttonParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, 100);
Then, add these statements to control where scrollView and buyButton are positioned
scrollParams.AddRule(LayoutRules.AlignParentLeft);
scrollParams.AddRule(LayoutRules.AlignParentTop);
buttonParams.AddRule(LayoutRules.Below, scrollView.Id);
The for the getting the button on the bottom of the screen, try one of two things
buttonParams.AddRule(LayoutRules.AlignParentBottom);
or
buyButton.Gravity = Gravity.BOTTOM
Try explicitly setting a fixed height to the scrollView
scrollView.LayoutParameters.Height = HEIGHT;
I think it defaults to WRAP_CONTENT if not specified, and is why its scaling.
You may have to set it in a layout file if you cant from code
<ScrollView
android:id="#+id/scroll_view_1
android:layout_width="wrap_content"
android:layout_height="100"/>
and then change
ScrollView scrollView = new ScrollView(context);
to
ScrollView scrollView = findViewById(R.Id.scroll_view_1, this);
Try wrapping the scrollView in another LinearLayout, and set this new layout's height to a fixed width that keeps the button low enough to your liking. You can actually replace the Scrollview with a ListView, but don't do this until after at least trying to get this fix working first. ListViews scroll, but you'd still face this problem without this fix.
To fix the new issue you mentioned below (with some quick and dirty code, you should use trial and error to fix it correctly), try the following
//each hotel stock options
for (int i = 0; i < hotels.size(); i++)
{
// ...
}
if( hotels.size() < numberOfItemsNeededForCorrectView )
{
for( int i=0; i < numberOfItemsNeededForCorrectView - hotels.size(); i++ )
{
View blankView = new View(context);
LinearLayout.LayoutParams viewParams = new LinearLayout.LayoutParams(1, 100);
blankView.setLayoutParams(viewParams);
blankView.setViewState(ViewState.INVISIBLE);
dialogContainer.addView(stockPicker);
}
}
You can try replacing your scrollView with a list view still and see if that fixes things. You can also try tweaking layout and gravity settings until you get it, or trying introducing other layouts or reorganizing your layouts (or using RelativeLayout, its really not that bad).
So, now in 2022 I've also had this problem. I've just set fixed size for ScrollView in fragment layout xml-file. When you have this problem, you can set, for example, 150dp or 200dp and be happy! And for more convenience, you can create special layout for landscape screen orientation and set fixed layout_height size there. I'm really confused that there's no information about this problem besides this page on the Internet.
<ScrollView
android:layout_width="match_parent"
android:layout_height="200dp">
<!--your view into scrollView here-->
</ScrollView>
I have a tabWidget defined as:
<TabWidget
android:layout_alignParentBottom="true"
android:id="#android:id/tabs"
android:paddingBottom="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center|bottom"
android:weightSum="5"
android:background="#drawable/bottom_bar_without_bg"
/>
Now I am adding custom ImageViews in it:
Drawable d = getResources().getDrawable(R.drawable.tabbar_button_home);
ImageView img1 = new ImageView(this);
img1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
img1.setImageDrawable(d);
TabHost.TabSpec tSpecHome = tHost.newTabSpec("timeline");
tSpecHome.setIndicator(img1);
tSpecHome.setContent(new MyTabContent(getBaseContext()));
tHost.addTab(tSpecHome);
The problem with this code is that all the images are spaced with each other in middle.
e.g abcdef
I want them to stretch to full width and have space in between them e.g a b c d e
Update the code as follows:
Drawable d = getResources().getDrawable(R.drawable.tabbar_button_home);
ImageView img1 = new ImageView(this);
img1.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1.0f)); // this line changed
img1.setImageDrawable(d);
Explanation:
The third parameter in the LayoutParams constructor is the weight. Each image view now has a weight of 1.0f. So they will spread across the layout.
You have them with WRAP_CONTENT width.
Instead they should be set to a width of 0dp and each one have a layout gravity of 1.
I have a Table Layout defined within LinearLayout as follows:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#E6E6E6"
android:orientation="vertical" >
<TableLayout
android:id="#+id/fbTableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:background="#android:color/darker_gray"
android:stretchColumns="*" >
</TableLayout>
</LinearLayout>
I am adding dynamic rows to the TableLayout as follows:
fbTableLayout = (TableLayout) findViewById(R.id.fbTableLayout);
for (int i = 0; i < 4; i++) {
fbTableRow = new TableRow(this);
fbTableRow.setBackgroundColor(Color.WHITE);
LayoutParams layoutParams = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
int leftMargin=10;
int topMargin=2;
int rightMargin=10;
int bottomMargin=2;
layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);
fbTableRow.setLayoutParams(layoutParams);
ImageView iv = new ImageView(this);
iv.setBackgroundDrawable(getResources().getDrawable(
R.drawable.ic_launcher));
iv.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT,
0.25f));
TextView tv = new TextView(this);
tv.setText("Album "+ i);
tv.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT,
0.75f));
fbTableRow.addView(iv);
fbTableRow.addView(tv);
fbTableLayout.addView(fbTableRow, new TableLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
}
But I am not able to generate spaces between the rows generated. The layout is as shown in the figure attached.
I have gone through a number of solutions given in stackoverflow to resolve this issue but none of them are working for me. Not sure what I am missing.
Any help would be greatly appreciated.
Thanks in advance.
Add another table row (in the loop) with a blank image. Specify the size of the image to create the size needed for your space.
Have you tried this when you're adding the table row?
fbTableLayout.addView(fbTableRow, layoutParams);
If not, you can try setting the margins on the individual views within the table row, but I'm pretty sure the above should apply the layout params when the row is being added to the table layout.
The docs for the setMargins method include this note:
A call to requestLayout() needs to be done so that the new margins are taken into account. Left and right margins may be overriden by requestLayout() depending on layout direction.
...so one thing to try would be to call fbTableLayout.requestLayout() after you've added all the rows. This probably won't make a difference, since the view should be getting invalidated in the code you've already posted, but it wouldn't hurt to try.
If that doesn't work, you could use another viewgroup (e.g. a FrameLayout) within each table row to contain your ImageView and TextView and set your padding there.
I have a FrameView that's created in my XML layout, and in my code, I'm trying to create a series of new ImageViews and add them as children of this FrameView. The ImageViews are small, only about 15 pixels square, and I want them to show up in various positions around the FrameView (I'm trying to implement what looks like a radar screen). I'm able to create them and add them just fine, and they show up on the screen. However, when I try to set their margins, it doesn't seem to have any effect. No matter what I set, all the ImageViews show up in the top left corner of the FrameView, as opposed to offset by the appropriate margins. My XML layout is listed below, along with the code that generates the child views. Am I doing something wrong? How can I get the margins to show up properly? Or is there a better way to do this than by using margins.
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RadarBackground"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/radar_bg">
<FrameLayout
android:id="#+id/RadarFrame"
android:layout_width="320dip"
android:layout_height="320dip"
android:layout_marginTop="25dip">
</FrameLayout>
</LinearLayout>
Java:
for (int i = 0; i < getData().getTargetCount(); i ++) {
int id = getData().getTargetId(i);
Log.d(T.TAG_A, "Radar: plotting target " + id);
TargetView tv = new TargetView(this, id, getData().getTargetName(id));
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(
radarCenterX + (int) (getData().calcTargetRadarX(id, radarSize) / radarScale) - (targetSizeX / 2),
radarCenterY - (int) (getData().calcTargetRadarY(id, radarSize) / radarScale) - (targetSizeY / 2),
0, 0);
tv.setImageResource(R.drawable.radar_civilian);
tv.setOnClickListener(this);
mTargets.add(tv);
mFrame.addView(tv, lp);
}
FrameLayout does not consider the margin parameters if you don't specify the view Gravity. Try specifying the gravity for all the ImageViews.
HTH !
I want to create an input box with a submit button to the right. Between them they should span the width of the screen. Currently I have:
LinearLayout row= new LinearLayout(context);
row.setOrientation(HORIZONTAL);
row.setGravity(Gravity.RIGHT);
EditText input = new EditText(context);
Button submit = new Button(context);
submit.setText("Submit");
row.addView(submit);
row.addView(input,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
myView.addView(row,LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
This results in the correct distribution of space: The submit button taking up as much space as it needs, the input button taking up the remaining space, however they are the wrong way round (the submit button is on the left, despite setting the gravity). If I take away the gravity, and reverse the order of adding the elements to the row, the input box takes up the whole width of the screen, and the submit button is not visible. What am I doing wrong?
I'd say it is better to use relative layout and place input to left of the button. But if you really need this with Linear layout you can just use weight parameter:
LinearLayout row= new LinearLayout(context);
EditText input = new EditText(context);
Button submit = new Button(context);
submit.setText("Submit");
LayoutParams inputParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
inputParams.weight = 1;
row.addView(input,inputParams);
LayoutParams buttonParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
buttonParams.weight = 0;
row.addView(submit, buttonParams);
Try adding EditText first setting its width to fill parent and its weight to 1, then the button (width = wrap content)
Items stack in a LinearLayout in the order in which you added them. Switch your two addView calls.
Its typically easier to achieve the right layout with the layout xml files. I.e:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
If you also need to line up buttons on the next line, you can also use a TableLayout. Look at the apidemos for code sample.