This question already has answers here:
How to set layout_weight attribute dynamically from code?
(12 answers)
Closed 5 years ago.
I am trying to achieve a dynamic layout where there are 2 fragments (1 takes up the top 80% of the screen, and the other takes up the bottom 20% of the screen), and I want to be able to dynamically hide the bottom fragment and stretch the top fragment to fill the screen.
If there's an alternative way of doing it I'd like to know, but for now I only know of 1 way to do it. So I have 2 FrameLayouts and I am trying to set the layout_weight of the top FrameLayout (main_container) to 5.
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.jobby.jobbydriver.activity.main"
android:id="#+id/activity_main"
android:orientation="vertical"
android:background="#color/ColorBG"
android:weightSum="5"
android:layout_height="match_parent"
android:layout_width="match_parent" >
<FrameLayout
android:id="#+id/main_container"
android:layout_weight="4"
android:layout_height="0dp"
android:layout_width="match_parent" />
<FrameLayout
android:id="#+id/second_container"
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="match_parent" />
</LinearLayout>
my code,
FrameLayout frameLayout = findViewById(R.id.main_container);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) frameLayout.getLayoutParams();
params.weight = 5.0f; // "weight" is red, (Cannot resolve symbol 'weight')
frameLayout.setLayoutParams(params);
At the 2nd line from the bottom, params.weight is showing up in red, so weight is not a value of params here. This works for LinearLayout, but not FrameLayout, so I'm not sure what I'm doing wrong.
When you try to get any view/viewgroups layout params it will give its parent's layout param.
By considering this you will get a LenearLayout.LayoutParams not FrameLayout.LayoutParams.
So, try this:
FrameLayout frameLayout = findViewById(R.id.main_container);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) frameLayout.getLayoutParams();
params.weight = 5.0f;
frameLayout.setLayoutParams(params);
NB: you already set weightsum 5. So, also consider to change other view weight.
Related
I'm trying to split my screen into different sizes using four Linear layouts within a linear layout. When I add weights to my project, it shows on the screen that the layout is split into 4 even parts on the layout preview. But when I run the app on a device or emulator, the views are not shown. But when I remove the weight attributes, the views are shown.
I've used code samples which successfully used the weight property but don't work on my program. I've also programmatically got the width and height of all the sub-views on the code. They are not null so they are there but just not visible. I've tried adding properties like visibility = true and focusable = true but to no avail. I've added a drawView to the view using this code
DrawView drawView = new DrawView();
ViewGroup mainLayout = (ViewGroup) findViewById(R.id.main);
mainLayout.addView(drawView);
DrawView is a class that extends View and I call the methods canvas.drawLine() and canvas.drawText() to draw to the screen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:weightSum="4">
<LinearLayout
android:visibility="visible"
android:focusable="true"
android:id="#+id/l1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/colorAccent"
android:orientation="horizontal"></LinearLayout>
<LinearLayout
android:visibility="visible"
android:id="#+id/l2"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorBtnText"></LinearLayout>
<LinearLayout
android:id="#+id/l3"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorBtnBackground"></LinearLayout>
<LinearLayout
android:id="#+id/l4"
android:orientation="horizontal"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorLbl"></LinearLayout>
</LinearLayout>
Nothing I tried above worked. I've spent quite a bit of time on this and would really appreciate some feedback.
I think the DrawView need setLayoutParams(LinearLayout.LayoutParams) before add to LinearLayout, set fixed height or weight by LayoutParams. if you don't, DrawView height is MATCH_PARENT, that will make other view's height is 0.
you can try this:
DrawView drawView = new DrawView();
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.main);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,0, 1); // or new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,100); to set fixed height
mainLayout.addView(drawView, params);
If it work, i think the best way is DrawView override onMeasure method, and calculate height itself.
As you can see, you set the "android:weightSum" to 4 in your xml file. While it still have 4 childs under the main linear layout, the code shows no error. However, when you run your code, you programmatically add another view into your main linear layout which exceed the weight sum of your main layout.
So, what i would suggest is, you may try to remove the android:weightSum="4" attribute from your xml layout that way it will automatically calculate the layout size by its weight.
I have an Activity with linear layout. It has two Views - one Button and one custom View beneath. I want to be able to set the custom one's height programmatically (it will be calculated during the startup from an image drawn onto it). And I want the button above it to fill the remaining space. How to achieve this?
So far I have this XML code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
android:orientation="vertical"
tools:context="eu.example.app.PianoActivity">
<Button
android:id="#+id/dummy_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="#string/dummy_button"/>
<eu.example.app.PianoView
android:id="#+id/pianoView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:keepScreenOn="true"/>
</LinearLayout>
As you can see I added the weight of 1 and height of 0dp to the button, so it fills the remaining space. And since it is required to provide some value, I have given a fixed 50dp to the custom View.
Now I tried to change the height using this code:
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(100, 100);
this.setLayoutParams(layoutParams);
this.requestLayout();
But it didn't do anything no matter where I placed it - whether in the View's constructors or in the onDraw() method.
//EDIT:
Additional info: the custom view inherits directly from View and overrides only onDraw() method to draw some stuff on itself.
You should use
public void onWindowFocusChanged(boolean hasFocus) {}
method to set height and width.
Put an id attribute ot your linear layout in xml as:-
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/liLay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
android:orientation="vertical"
tools:context="eu.example.app.PianoActivity">
<Button ---/>
<eu.example.app.PianoView---/>
</LinearLayout>
Now in your onCreate() method initialse the layout, as:-
LinearLayout liLay = (LinearLayout)findViewById(R.id.liLay);
and now set the layout Parameters progmatically,
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(100, 100);
liLay.setLayoutParams(layoutParams);
This will help you.
Use this:
layoutParams.height = 130;
yourLayout.setLayoutParams(layoutParams);
In my app, I've a layout like:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/belowAcionBar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal">
</LinearLayout>
</FrameLayout>
I need to set the height of LinearLayout belowAcionBar dynamically. This view needs to be shown just below ActionBar.
To set the height I'm using below code:
View panelView = findViewById(R.id.belowAcionBar); // This gives object of LinearLayout
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) panelView.getLayoutParams();
params.height = 48; // In dp
panelView.setLayoutParams(params);
Issue 1:
Since belowAcionBar is a LinearLayout, first I tried of using LayoutParams as LinearLayout.LayoutParams, rather than FrameLayout.LayoutParams.
But it thre a runtime error Can't cast FrameLayout.LayoutParams to LinearLayout.LayoutParams.
Why it is getting panelView.getLayoutParams() as FrameLayout?
Issue 2:
Even after using code above, my view belowAcionBar is appearing to be much less than 48dp. Seems like it is being partially hidden behind ActionBar.
Issue 3:
If I change the layout to:
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout android:orientation="vertical"
android:id="#+id/belowAcionBar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/purple_dark" >
</LinearLayout>
</LinearLayout>
</FrameLayout>
And change the java code to:
View panelView = findViewById(R.id.belowAcionBar);
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) panelView.getLayoutParams();
params.height = 48; // In dp
panelView.setLayoutParams(params);
Then my code works perfectly, but adds extra Layout. Why it is working now?
Thanks in advance.
I have in main.xml TitlePageIndicator and ViewPager, and I want to add admob (right into LinearLayout) at the bottom of RelativeLayout. How can I do this?
When I launch it, the log says nothing about errors (since there is no place to put admob), but admob is invisible, I can`t see it. (looks like admob is outside the screen because I tried to set specific sizes to ViewPager and it works perfect)
I do not want to set specific sizes to ViewPager (becouse of the different screen sizes)
Thanks.
My main.xml is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.viewpagerindicator.TitlePageIndicator
android:id="#+id/indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/indicator"/>
<LinearLayout
android:id="#+id/for_ads"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/viewpager"/>
</RelativeLayout>
UPD.
solved
I used this answer and it works perfect for me
First, your RelativeLayout needs an ID if you want to reference it:
RelativeLayout rLayout = (RelativeLayout)findViewById(R.id.yourRelativeId);
Then create some LayoutParams for the object (in this case, your admob adview) that tell it to align itself to the bottom (and not align to any other views, this way it isn't pushed off-screen or moved by the other views):
RelativeLayout.LayoutParams rLParams =
new RelativeLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
rLParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 1);
Next, add the view to your RelativeLayout with your LayoutParams:
rLayout.addView(yourAdView, rLParams);
I want to add two views one after the other, I used this way but I am getting an error.
This is my XML.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/parent"
>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/rel1"
android:layout_alignParentTop="true"
></RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/rel2"
android:layout_below="#+id/rel1"
></RelativeLayout>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
In the two Relative layouts rel1,and rel2 I will add my custom views which are going to be drawn dynamically.
my code:
setContentView(R.layout.main);
RelativeLayout rlstat1=(RelativeLayout)findViewById(R.id.rel1);
RelativeLayout rlstat2=(RelativeLayout)findViewById(R.id.rel2);
RelativeLayout.LayoutParams para1 = new RelativeLayout.LayoutParams(
viewWidth, viewHeight);
RelativeLayout.LayoutParams para2 = new RelativeLayout.LayoutParams(
viewWidth, viewHeight);
rlstat1.setLayoutParams(para1);
rlstat1.addView(mView);
para2.addRule(RelativeLayout.BELOW, R.id.rel1);
rlstat2.addView(mView2);
Here mView and mView2 are two view type which I want to set in the two relative layouts.
ViewWidth and ViewHeight are the width and height of the screen it is running.
The problem:
If only one view is added i.e. mView or mView2 it's showing but if both the views are added(like in above) then only one relative layout is shown.
I want that both of my views get set one below other.
Hope I am clear in my question.Can you please tell me the appropriate way to do this.
you are setting layout params to views dynamically in activity and these are new layout params objects, so your rule to add rel2 to below of rel1 gets cleared, instead try:
setContentView(R.layout.main);
RelativeLayout rlstat1=(RelativeLayout)findViewById(R.id.rel1);
RelativeLayout rlstat2=(RelativeLayout)findViewById(R.id.rel2);
RelativeLayout.LayoutParams para1 = rlStat1.getLayoutParams();
para1.width=LayoutParams.FILL_PARENT;
para1.height=LayoutParams.FILL_PARENT;
RelativeLayout.LayoutParams para2 = rlStat2.getLayoutParams();
para2.width=LayoutParams.FILL_PARENT;
para2.height=LayoutParams.FILL_PARENT;
rlstat1.setLayoutParams(para1);
rlstat1.addView(mView);
para2.addRule(RelativeLayout.BELOW, R.id.rel1);
rlstat2.addView(mView2);