i have a linearLayout inside a RelativeLayout. I need to be able to set the height of the linearlayout dynamically depending on the screen dimensions. Im having some difficulties.
how can i achieve this?
MAIN :
public class MainActivity extends Activity {
LinearLayout L;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
L=(LinearLayout)findViewById(R.id.top);
L.setLayoutParams(new LinearLayout.LayoutParams(1080, 400));
}
}
XML:
<RelativeLayout 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"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fff"
android:id="#+id/top"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</LinearLayout>
When you set layout params, it needs to be that of the parent.
Switch:
L.setLayoutParams(new LinearLayout.LayoutParams(1080, 400));
To:
L.setLayoutParams(new RelativeLayout.LayoutParams(1080, 400));
in your LinearLayout, just set
android:layout_height="0dp"
android:layout_weight="1"
As Justin answered
L.setLayoutParams(new RelativeLayout.LayoutParams(1080, 400));
You might also need, if you have already set the layout
L.requestLayout();
In Kotlin you can do the following:
L.layoutParams = RelativeLayout.LayoutParams(1080, 400)
And then call L.requestLayout() to apply changes
Related
I have a LinearLayout inside which I am including a different layout. Something like this
<LinearLayout
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="20dp"
android:visibility="gone"
tools:visibility="visible">
<include
layout="#layout/new_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginBottom="4dp"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
android:layout_weight="1"/>
</LinearLayout>
Now what I would like to do is, to programmatically change the "marginBottom" of the included layout (new_layout). How can I do that?
I tried calling various LayoutParams and tried changing the margin, but not sure if it is the right approach. Any help greatly appreciated.
Thanks
Try this.. Make the Linear layout using your id
LinearLayout ll =(LinearLayout) findViewById(R.id.linear_layout);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 20);
layoutParams.setMargins(left,top,right,bottom);
where you can pass the value in setMargins
and if you want to input value in dp.. Try this
public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {
final float scale = con.getResources().getDisplayMetrics().density;
// convert the DP into pixel
int pixel = (int)(dp * scale + 0.5f);
ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
s.setMargins(pixel,pixel,pixel,pixel);
yourView.setLayoutParams(params);
}
where you can pass your layout params
include.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:id="#+id/include_layout">
<ImageView android:layout_width="90dp"
android:layout_height="90dp"
android:src="#drawable/cross" />
</LinearLayout>
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<include layout="#layout/include"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello"
android:padding="10dp" />
</LinearLayout>
MainActivity.class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
LinearLayout included=(LinearLayout)findViewById(R.id.include_layout);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(10), Math.round(10), Math.round(10), Math.round(10));
//set margin...
included.setLayoutParams(params);
}
}
You should not directly change or modify margins in the <include> tag. This tag is just adding the layout resource in the current view hierarchy without adding an extra parent view container.
So essentially what you want to do is set margins on the root view container of the "included layout". That is you should directly call findViewById() for the root view and set all of your margins on it pro grammatically and as the included view's parent is a Linear-layout you should use
LinerLayout.LayoutParams params = (LinerLayout.LayoutParams) includedRootView.getLayoutParams();
params.setMargins();
includedViewRoot.setLayoutParams(params);`
You can change it by dimensions also
res/values/dimens.xml
res/values-small/dimens.xml
res/values-normal/dimens.xml
res/values-xlarge/dimens.xml
I think this code helpful...
include.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" >
</ImageView>
</LinearLayout>
activity_main.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" >
<include
android:id="#+id/include_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="4dp"
android:layout_marginStart="4dp"
layout="#layout/include" />
</LinearLayout>
MainActivity
package com.example.stackdemo;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
LinearLayout include_layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
include_layout = (LinearLayout) findViewById(R.id.include_layout);
#SuppressWarnings("deprecation")
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
layoutParams.setMargins(0, 0, 0, 100);
include_layout.setLayoutParams(layoutParams);
}
}
private void showText(){
textView.setText(Html.fromHtml(text));
Log.d("MyLog","tags.size="+tags.size());
for (int i=0;i<tags.size();i++){
Button button = new Button(context);
button.setText(tags.get(i));
ll.addView(button, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT));
tagButtons.add(button);
}
}
This should be simple but this buttons doesn't show. I checked with logs- tags.size=5 so the problem is not in this. ll is a LinearLayout
Here's layout file :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView
android:layout_margin="5dp"
android:id="#+id/scrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
<LinearLayout
android:orientation="horizontal"
android:id="#+id/ll2"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="TextView" />
<LinearLayout
android:id="#+id/ll"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
So, it's a very simple code and I don't understand why are theese views are not being added to a layout with id "ll"
You should call invalidate() on the parent layout which forces children to be drawn on the screen
Remove the linearlayout reference which you have not posted in the question and use like as i have done, Try this
Call showText() in OnCreate- method If you are using Activities
private void showText(){
textView.setText(Html.fromHtml(text));
for (int i=0;i<tags.size();i++){
Button button = new Button(context);
button.setText(tags.get(i));
LinearLayout ll=(LinearLayout) findViewById(R.id.ll);
ll.addView(button);
}
}
I created an app where clicking a button I create a TextView inside a LinearLayout(hosted inside a ScrollView).
When I click the button the TextViews are displayed starting from the top like this example:
First Image
http://imgur.com/8fhtYZs (Sorry I don't have reputation to display it in the post so I inserted the link)
But my task is to create the textviews at the bottom of my LinearLayout and make the TextViews already created scroll up the new one. (Sorry for my bad english) I show an example to be more comprehensible.
Second Image
http://imgur.com/RLHooaH
This is my code:
public class Messaggi2 extends ActionBarActivity implements OnClickListener {
LinearLayout mLayout;
ScrollView scroll;
Button invia;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messaggi2);
mLayout = (LinearLayout) findViewById(R.id.LinearScrollLayout);
scroll = (ScrollView) findViewById(R.id.scrollView2);
invia = (Button) findViewById(R.id.Invia);
invia.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
mLayout.addView(createNewTextView("Message"));
}
private TextView createNewTextView(String text) {
final LayoutParams lparams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
final TextView textView = new TextView(this);
textView.setLayoutParams(lparams);
textView.setText(text);
textView.setBackgroundResource(R.drawable.balloon_broadcast_incoming_pressed);
return textView;
}
}
And this is my Layout.XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ScrollView
android:id="#+id/scrollView2"
android:layout_width="fill_parent"
android:layout_height="640dp"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<LinearLayout
android:id="#+id/LinearScrollLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/Messaggio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/balloon_broadcast_incoming_pressed"
android:text="#string/messaggi" />
</LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_marginTop="70dp"
android:background="#drawable/linear_layout_bg" >
<EditText
android:id="#+id/Scrivi"
android:layout_width="440dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="#string/scriviMessaggio" />
<Button
android:id="#+id/Invia"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/send_btn" />
</LinearLayout>
</LinearLayout>
There is no such thing as LinearLayout.BOTTOM, nor can we add rule for LinearLayout.
But the good news is to insert into LinearLayout, one could decide the sequence.. Just use the addView function with 3 arguments as below
mLayout.addView(view, index, param);
The index determined the order.
You need to set your linear layout's height to the height of your ScrollView so instead of using wrap_content cause that is wrapping your linearlayout change it to match_parent
example:
<LinearLayout
android:id="#+id/LinearScrollLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
When you want to add the button at the bottom of the linearlayout just add a rule to your layout params.
example:
private TextView createNewTextView(String text) {
LinearLayout.LayoutParams layoutParams =
(RelativeLayout.LayoutParams) txt1.getLayoutParams();
layoutParams.addRule(LinearLayout.BOTTOM, 1);
final TextView textView = new TextView(this);
textView.setLayoutParams(lparams);
textView.setText(text);
textView.setBackgroundResource(R.drawable.balloon_broadcast_incoming_pressed);
return textView;
}
I've programmed one of my layouts programatically. And when I tried to implement it in XML I couldn't make it work. It crashes with NullPointerException and I really do not know why.
This is my XML layout
<RelativeLayout 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:orientation="vertical"
tools:context=".DisplayMessageActivity" >
<ImageView
android:id="#+id/canal_1"
android:contentDescription="#string/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="canal1_Click"
android:src="#drawable/pestanya_seleccionada" />
</RelativeLayout>
And what I'm trying is:
ImageView canal1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* layout prinicpal */
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
canal1 = (ImageView) findViewById(R.id.canal_1);
relativeLayout.addView(canal1);
setContentView(relativeLayout, rlp);
}
It crashes at relativeLayout.addView(canal1);
I don't why this fails. In my head everything should run fine.
Thanks for reading and hope you can help me ;)
Kind regards,
Raúl
You have not set content of the xml layout to the screen and you are finding the id of the ImageView. This is causing NPE.
canal1 = (ImageView) findViewById(R.id.canal_1);
The above statement will cause nullpointerexception since you have not set the layout and your are trying to find the id form the defined in the xml file.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activty_main);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayout);
//add other ui elements to the root layout ie RelativeLayout
}
<RelativeLayout 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:id="#+id/relativeLayout"// relative layout id
android:orientation="vertical"
tools:context=".DisplayMessageActivity" >
<ImageView
android:id="#+id/canal_1"
android:contentDescription="#string/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="canal1_Click"
android:src="#drawable/pestanya_seleccionada" />
</RelativeLayout>
The following works, but I want to eliminate the xml so that I can change the image programmatically:
Java:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.p6_touch);
ImageView floatImage = (ImageView) findViewById(R.id.p6_imageView);
floatImage.setOnTouchListener(this);
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/background_black" >
<ImageView
android:id="#+id/p6_imageView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="matrix"
android:src="#drawable/p6_trail_map" >
</ImageView>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:onClick="showFlashlight"
android:src="#drawable/legend_block24" />
</FrameLayout>
In the documentation there is a table that maps XML to Java.
For instance: android:src is equivalent to setImageResource().
You will need to check the inherited table for attributes from any super class.
For instance: android:id is equivalent to setId().
width, height, and gravity are all set in a LayoutParams object and passed to setLayoutParams().
Understand that not every XML attribute has a matching Java method (and vica versa), but all of the attributes you are using do.
An Example, let's call this file activity_main.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/background_black" >
<!-- We'll add this missing ImageView back in with Java -->
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:onClick="showFlashlight"
android:src="#drawable/legend_block24" />
</FrameLayout>
Now in our Activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Let's create the missing ImageView
ImageView image = new ImageView(this);
// Now the layout parameters, these are a little tricky at first
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT);
image.setScaleType(ImageView.ScaleType.MATRIX);
image.setImageResource(R.drawable.p6_trail_map);
image.setOnTouchListener(this);
// Let's get the root layout and add our ImageView
FrameLayout layout = (FrameLayout) findViewById(R.id.root);
layout.addView(image, 0, params);
}