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);
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.
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.
I would start with my goal. What I want to achieve is to have layout which is 3 times bigger then real screen of phone.
Right now I try to test my solution, but I have problem with scrolling.
This is how look my layout:
<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="400dp"
tools:context=".Zo"
android:id="#+id/zo_root"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="9">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Red"
></FrameLayout >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Yellow"
></FrameLayout >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
android:background="#color/Blue"
></FrameLayout >
</LinearLayout>
</ScrollView>
My code behind:
#Override
protected void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zo);
setParameterForScroolView();
}
private void setParameterForScroolView()
{
ParameterKeeper parameterKeeper = new ParameterKeeper(this);
LinearLayout linearLayout = (LinearLayout)findViewById(R.id.zo_root);
linearLayout.getLayoutParams().height = parameterKeeper.getHeightOfScreen() *3;
}
The code behind works well, cause my whole screen is red, but I can't scroll it at all.
There was answer which said, that I need to remove from scrollView android:fillViewport="true". After that my LinearLayout diseapers like in this question.
I added LinearLayout as root (source) but it not helped me at all.
Have you got any idea to solve it?
I try also set height 1600dp instead 400dp for Root LinearLayout in xml to be sure, that it's not problem with recalculating view. It's not working too.
You are changing the size of the wrong layout. you suppose to modify the height of the first layout inside the scroll view.
Some way scroll doesn't work if the child elements have layout_weight and I change programmatically value of height in parent's view.
In my case the only way to make it works was to set height equal to size of screen in every of frame layout in code of activity. This way I could reach my goal which was to have layout height == 3 x real screen size
I have this layout in my Android application (I'm using this as a splash screen along with the main menu screen.
Here's the XML
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.izzivizzi.avant2go.ACMainActivity"
android:background="#mipmap/wallpaper"
android:orientation="vertical"
android:animateLayoutChanges="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
...................
</RelativeLayout>
<LinearLayout
android:id="#+id/mainMenuButtons"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:layout_marginTop="#dimen/margin_middle"
android:orientation="vertical"
android:visibility="gone">
...................
</LinearLayout>
</LinearLayout>
What it's supposed to do
At first when the Activity is launched, only the RelativeLayout is displayed with weight 1, which means the children are displayed in the middle of the screen (it's a textview along with some images, but I think that's redundant information here).
After a couple of seconds, the LinearLayout's visibility is set to VISIBLE and it has a weight of 2, which means it pushes the top RelativeLayout up.
Now since the main LinearLayout's animateLayoutChanges is set to true, I was expecting that the RelativeLayout's children will animate to their new position (towards the top of the screen) and the new LinearLayout element will slowly appear.
Well, the LinearLayout does slowly appear but the RelativeLayout's children just blink up because the RelativeLayout position doesn't actually change, it just changes it's height.
The problem
Now since the RelativeLayout's children are simply blinked up instead of animated, I need to find a way to animate it towards the top while the LinearLayout slowly appears.
I will greatly appreciate a solution to this problem. Thank you!
Instead of toggling the visibility, why not add the linear layout in code?
You can leave it in the layout file, just get a reference to it: then remove it, after your few seconds runs, and add it back (make sure to use appropriate layout params with weight set).
I have a LinearLayout which contains two other RelativeLayouts (orientation horizontal). I don't know the width of the left RelativeLayout at runtime. Is it possible to sync both layouts? If the left RelativeLayout has the width of 100dp, the right RelativeLayoutshould also be 100dp. Or both should be 50dp.
Can I handle this in the XML file or have I to do it via code and setting the LayoutParams to the same values?
set width of 0dp and weight of 1 in each RelativeLayout
<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="100dp"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
</RelativeLayout>
</LinearLayout>
If it's a dynamic width - there is no xml way of doing that.
In xml you can only:
set a fixed width for both relative layouts
set a fixed width of linear layout (or match parent) and for relative layouts use width="0dp" and weight=1
If the width of the first layout is unknown, you need to use some tricks like that:
firstRelativeLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
secondRelativeLayout.getLayoutParams().width=firstRelativeLayout.width;
secondRelativeLayout.requestLayout();
}
});