I am using linear layout with 2 textviews, 4 buttons, 1 seekbar,1 image view. If I am place those textviews,buttons, etc. in a linear layout the alignment is fine in android phone. While I am running the same code in android tablet, alignment is not proper. Why this alignment is not proper in tablet.? I have created the textviews,buttons etc by java code. Even I am specifying the two text views horizontally by settings the left margin of the second text view by devicewidth/2 having the difference in android phone and tablet. I need to align like the below.
TextView1 TextView2
Button1 Button2 Button3 Button4 SeekBar ImageView
Here is my code.
LinearLayout.LayoutParams textViewParams1 = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
textViewLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView TextView1=new TextView(this);
TextView1.setText("Text1");
textViewParams1.gravity=Gravity.CENTER;
textViewParams1.setMargins(60, 20, 40, 10);
textViewLayout.addView(chooseColorTextView, textViewParams1);
LinearLayout.LayoutParams textViewParams2 = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
TextView TextView2=new TextView(this);
TextView2.setText("Text2");
int width=getWindowManager().getDefaultDisplay().getWidth();
textViewParams2.gravity=Gravity.CENTER;
textViewParams2.setMargins((width/2), 20, 40, 10);
textViewLayout.addView(strokeWidthTextView, textViewParams2);
parentlinearLayout.addView(textViewLayout, textViewLayoutParams);
In the next linear layout, I have added the 4 buttons,seekbar and image view. But facing problems in alignment.
I advise to create complex layout that must be rendered on different screen sizes in XML rather than programmatically, so you can have two different main.xml in res/layout and in res/layout-large and the system would pick up the correct one depending on screen size.
Use layout_weight and weightSum in XML:
<LinearLayout android:weightSum="1" android:layout_width="match_parent" android:layout_height="wrap_content">
<!-- First column -->
<LinearLayout android:layout_weight=".5" android:layout_width="0dp" android:layout_height="wrap_content"> ... </LinearLayout>
<!-- Second column -->
<LinearLayout android:layout_weight=".5" android:layout_width="0dp" android:layout_height="wrap_content"> ... </LinearLayout>
</LinearLayout>
This will produce a dynamically resizing 2 column layout. If you want the divide shorter or longer, change .5 to .3 and .7 for a 30/70% split etc.
Please read more about wrap_content and other android controls. Also read about dpi of tablets. Due to resolution appearance changes.
Why don't you use a TableLayout ? its the one you need to manage cells alignement:
All that you need is in the span attribute to make cells use multiple columns.
TableLayout myLayout = new TableLayout(myContext);
TableRow row1 = new TableRow(myContext);
TableRow.LayoutParams layouparams1 = new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT,TableRow.LayoutParams.WRAP_CONTENT);
layouparams1.span = 4;
row1.setLayoutParams = layouparams1 ;
TableRow.LayoutParams layouparams2 = new TableRow.LayoutParams(TableRow.LayoutParams.FILL_PARENT,TableRow.LayoutParams.WRAP_CONTENT);
layouparams2.span = 2;
TableRow row2 = new TableRow(myContext);
row2.setLayoutParams = layouparams2 ;
//then create and add your childs to each row :
...
row1.addView(text1);
row1.addView(text1);
row1.addView(button1);
row1.addView(button2);
row1.addView(button3);
row1.addView(button4);
row1.addView(seekbar);
row1.addView(imageView);
myLayout.addView(row1);
myLayout.addView(row2);
also consider adding layout_weight on children to manage the space they left to each other.
Related
I have the following method which I call a few times to create a list of buttons. It works well and creates the buttons.
public void CreateButton(int i) {
LinearLayout btnLayout = (LinearLayout)findViewById(R.id.btnLayout);
Button btn = new Button(this);
btn.setId(i);
btn.setText(String.valueOf(i+1));
btnLayout.addView(btn);
}
But each created button is fitting the screen in width, and I would want it to stay side by side, two buttons per row. I managed to set the button to half the screen size using this:
int displaywidth= getResources().getDisplayMetrics().widthPixels;
btn.setLayoutParams(new LayoutParams((int)(displaywidth/2), LayoutParams.WRAP_CONTENT));
It makes the button's width to be half the screen's size, but I can't figure out how to place them side by side. Any help is appreciated.
Change your orientation in your LinearLayout to horizontal.
<LinearLayout
...
android:orientation="horizontal"
... >
...
</LinearLayout>
If you only have a single LinearLayout that is to hold multiple side-by-side buttons you can make horizontal LinearLayouts to hold your button pairs and either nest them in the main veritical layout or utilize another layout, for example RelativeLayout, to get the desired results.
Try using weight property of LinearLayout. If in each row you want only two buttons then give
android:weightSum="1"
to LinearLayout and
android:layout_weight="0.5"
to each button or you can set weight dynamically in your code by
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, xf);
where x represents the float value of layout weight of your button.
for more details about layout weight http://developer.android.com/guide/topics/ui/layout/linear.html
One way to solve the problem is by using their weight and width. Make sure the Linear Layout has a horizontal orientation. Then, use Layout_params to set their width to "Wrap_Content" and their weight to "1". Then both will automatically take up the same amount of space.
I am trying to achieve a dynamic list of textviews like in the image below :-
Here is my code :-
LayerDrawable dashboardResShape_community= (LayerDrawable) getResources().getDrawable(R.drawable.upcomingtask_tags_shape);
// The background effect is by the layer list drawable from the above code
LinearLayout tags_view2=(LinearLayout)findViewById(R.id.tags_view);
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 2, 2, 2);
TextView[] tx = new TextView[15];
for(int i=0; i<15; i++) {
tx[i] = new TextView(getActivity());
tx[i].setPadding(8, 4, 8, 4);
tx[i].setBackground(dashboardResShape_community);
tx[i].setLayoutParams(lp);
tx[i].setText("Tag"+i);
tags_view2.addView(tx[i]);
}
and in my xml there is only a linear layout :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tags_view"
android:orientation="horizontal" >
</LinearLayout>
This is what i achieve :-
When i am adding 15 textviews, only 8 are shown like below, the rest should come in the next line but they are not.
If i add more textviews, it goes out of screen but i want to add the textview in the second line when the first line is full. What i am doing wrong here?
Its LinearLayout's limitation.
If you want the explained behavior than
You have to make your own Layout/View refer this link or
Impliment LinearLayout Horizontal orientation with wrapping children like this
you cannot get more text views on next line after linear layout is filled( screen width ), you already the made linear layout orientation as horizontal. Better solution add one more linear layout or use relative (do some child count coding and set parameters). The best solution i prefer for u is table layout. Easier to code code and handle
What you can do is add as many textviews as will fit on the screen to your linearlayout, but then when a textview would go off the screen, you could add another linearlayout below the one that you already had, and then add on to that. You could keep doing that and you would end up with no textviews goind off the screen. You could also try using a gridview.
Here is what this layout looks like:
http://developer.android.com/guide/topics/ui/layout/gridview.html
And here is the documentation:
http://developer.android.com/reference/android/widget/GridView.html
I am adding views dynamically in a linear layout as follows:
xml:
<LinearLayout
android:id="#+id/part1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:gravity="right"
android:orientation="horizontal" >
</LinearLayout>
java:
View linearLayout = findViewById(R.id.part1);
((LinearLayout) linearLayout).removeAllViews();
for (int i = 0; i < 15; i ++){
TextView tv = new TextView(this);
tv.setText(String.valueOf(i));
LinearLayout.LayoutParams lay = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(lay);
tv.setBackgroundResource(R.drawable.msg);
tv.setId(i);
((LinearLayout) linearLayout).addView(tv);
}
Now i have two questions:
1) the text views are added horizontally correctly but if not fitting screensize, some of them won't appear, how to force it to continue adding in a new line once the horizontal space is full ?
2) textviews are added from left to right, how to add them from right to left ?
thanks
You need to understand how ViewGroups work, in this case, LinearLayout will add items horizontally or vertically without making position calculations for you unless you explicitly specify (jumping to next line is not one of them...), think of it as an item holder that will show items only on the space you specify for it (thats why some of the elements disappear...), by default the way LinearLayout arrange items is from left to right or up to down, if this do not fit your needs, you could go for any of the ViewGroup options android has, the most important might be:
RelativeLayout
FrameLayout
TableLayout
AbsoluteLayout(not recommended)
If you need some sort of Free Draw on the screen, you can always go for a View object, override onDraw, and play with the canvas of that object...
Regards!
What I Tried To Do
I tried to set my ImageButton's layout_gravity via Java code, the way I want the ImageButton to be is presented like the way within the Orange frame in the image below:
The Blue frame is a vertical LinearLayout act as a "base" layout and this is the layout I tried to add child layouts to.
The Orange and Red are both horizontal LinearLayout.
The Orange layout is the way I want to put the ImageButton and the TextView, this one is set up via XML
The Red layout is the result I tried to mimic the Orange layout via Java code.
The Related Code
Here's the XML code that set up the Orange layout, this is the effect I want to achieve via Java code:
<!-- Begin the Orange Layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/info_left_padding"
android:layout_marginRight="#dimen/info_right_padding" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:minHeight="#dimen/detail_min_line_item_height"
android:text="TextView" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:adjustViewBounds="true"
android:maxHeight="#dimen/abs__action_bar_default_height"
android:scaleType="fitCenter"
android:src="#drawable/navigation_cancel" />
</FrameLayout>
</LinearLayout>
Here's the Java code that set up the Red layout
int textHeight = (int)getResources().getDimension(R.dimen.detail_min_line_item_height);
int imgHeight = (int)getResources().getDimension(R.dimen.abs__action_bar_default_height);
TextView mTextView = new TextView(this);
ImageButton mDeleteButton = new ImageButton(this);
// Set Delete Button Padding
// mDeleteButton.setPadding(buttonPadding, buttonPadding, buttonPadding, buttonPadding);
// Set Imagebutton Scale type as fitCentre
mDeleteButton.setScaleType(ScaleType.FIT_CENTER);
// Set AdjustViewBounds
mDeleteButton.setAdjustViewBounds(true);
// Set max height of the image
mDeleteButton.setMaxHeight(imgHeight);
// Set the text appearance to be "large"
mTextView.setTextAppearance(this, android.R.style.TextAppearance_Large);
mTextView.setText(text);
// Set the minimum height of this textview
mTextView.setMinHeight(textHeight);
// Set the content of the textview to be centred
mTextView.setGravity(Gravity.CENTER_VERTICAL);
// Set the ImageButton's background image
mDeleteButton.setImageResource(R.drawable.navigation_cancel);
LinearLayout.LayoutParams hParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
LinearLayout hLayout = new LinearLayout(this);
// Set Margins
hParams.leftMargin = (int) getResources().getDimension(R.dimen.info_left_padding);
hParams.rightMargin = (int) getResources().getDimension(R.dimen.info_right_padding);
hParams.bottomMargin = (int) getResources().getDimension(R.dimen.text_layout_margin);
hLayout.setLayoutParams(hParams);
// Set orientation to horizontal
hLayout.setOrientation(LinearLayout.HORIZONTAL);
// The settings below is actually setting up some of the button's parameters
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
buttonParams.gravity = Gravity.RIGHT;
mDeleteButton.setLayoutParams(buttonParams);
hLayout.addView(mTextView);
hLayout.addView(mDeleteButton);
layout_blue.addView(hLayout);
What I've Tried So Far
According to some SO post like this: Java method for android:layout_gravity I initially tried to first put my ImageButton into a FrameLayout then set the params of this FrameLayout, like this:
FrameLayout buttonFrame = new FrameLayout(this);
FrameLayout.LayoutParams buttonParams = new FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.WRAP_CONTENT,
android.widget.FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.RIGHT | Gravity.CENTER_VERTICAL);
buttonFrame.setLayoutParams(buttonParams);
buttonFrame.addView(mDeleteButton);
But I had the same result as the image presented above. Later I also tried to change the LayoutParams width to MATCH_PARENTonly to find theImageButton` was stretched horizontally (Yes it's stretched)
Then I tried the method posted in these two SO posts:
How to set layout_gravity programmatically?
How to set a button's parameters programatically
Their method is to set up a LinearLayout.Params first, then apply this params to the button (The Code I posted in The Related Code section applies this method). In short it is:
// The settings below is actually setting up some of the button's parameters
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
buttonParams.gravity = Gravity.RIGHT;
mDeleteButton.setLayoutParams(buttonParams);
However, the result was still the same as the image presented above.
Question
Since I need to programmatically add more child views to the Blue layout later, I wonder if there's a way to set up each child layout like the Orange one in the image?
At Last
I found a solution which is quite similar to #Permita 's answer.
Here's my solution:
LinearLayout.LayoutParams textParams = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT);
textParams.weight = 1.0f;
mTextView.setLayoutParams(textParams);
Add the below code, it will assign all the available space to the texView, shifting the button to right side of the layout to make it appear like the orangeLayout.
mTextView.setLayoutParams(LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, 1.0f));
Try layout_width = "0dp" layout_weight="1" for the TextView. This tells TextView to occupy the whole available width, so that FrameLayout with ImageView will align to the right border.
<TextView
android:id="#+id/textView1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:minHeight="#dimen/detail_min_line_item_height"
android:text="TextView" />
Instead of using the standard LinearLayout, why not try to use the more complex RelativeLayout? With it, you can adjust the locations of each individual view relative to others. You can set the ImageButton in the orange layout to android:layout_alignParentRight="true", which will set the button attached to the right side of the parent layout, the RelativeLayout in my case, but the LinearLayout in yours. Here is the link to the API Guides for Relative Layouts on the Android developers website.
Context: I have a TableLayout (created using XML), which has one TableRow, which has one TextView. The code:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:fillViewport="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableLayout
android:id="#+id/mytable"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
>
<TableRow>
<TextView
android:id="#+id/add_alarm"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:gravity="center"
android:text="New\nItem"
android:textSize="30sp"
/>
</TableRow>
</TableLayout>
</ScrollView>
In my Activity's onCreate() method, I am trying to add another View to the TableRow dynamically. Here is the code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = LayoutInflater.from(this);
View mainLayout = inflater.inflate(R.layout.main, null);
TableLayout tl = (TableLayout) mainLayout.findViewById(R.id.mytable);
TableRow tr = (TableRow) tl.getChildAt(0);
Log.d(TAG, "tr class = " + tr.getClass().getName() + " | width = " + tr.getWidth() + "\n");
final RelativeLayout rl = (RelativeLayout) inflater.inflate(R.layout.alarm_widget, null);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1);
tr.addView(rl, lp);
tl.invalidate();
setContentView(mainLayout);
}
Question: This code is not having the intended effect of displaying both the Views (the one in the XML layout already & the other added dynamically) in a columns of equal width.
With the code given above, the dynamically added View has a width of '0' and is therefore invisible.
If I change the code to tr.addView(rl) (i.e. without reference to LayoutParams), the dynamically added view is visible, but the columns are not equal in width.
How can I achieve this?
Edit: I changed the code based on the comments to the following. It still doesn't work as expected:
TableLayout.LayoutParams lp = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT, 1f);
tr.addView(rl, lp);
The problem is this behavior defined for TableRow:
The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively MATCH_PARENT and WRAP_CONTENT.
Rather than add your text views directly to the TableRow, have the TableRow hold a horizontal LinearLayout and add the second view to that holder.
(Also, using LinearLayout.LayoutParams for something that's going into a TableRow is wrong. You should have been using TableRow.LayoutParams. But that wouldn't be the way to get equal-width TextViews. Use a LinearLayout holder.)
I think it's not a good idea to dynamically add an item to a TableRow - it defeats the purpose of using a table. Imagine if you add an item to the first row of the table, but not on the second, meaning the first row has more elements. It wouldn't look much like a table.
But if you insist,
From developer guide:
The children of a TableRow do not need to specify the layout_width and layout_height attributes in the XML file. TableRow always enforces those values to be respectively MATCH_PARENT and WRAP_CONTENT.
You may need to start looking on the layout_weight of each element. Try adding layout_weight=1 on the row's static elements, and then setting your dynamic RelativeLayout's weight to 1 before adding it to the row.
rl.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1f));
The last parameter is weight.
Set height like this to the layout containing the ScrollView.
It solved my own problem where tablelayout does not show last lines.
android:layout_height="0dp"