Creating a layout programatically using XML elements - android

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>

Related

Android place view dynamically relative view

Similar to a to do app. I have a top bar that is set by the xml file and at run time I would like to create some textviews which go directly under it. Also there will be a button that adds new text views when clicked.
When I create a new textview from the button how do I make sure that the new Textview stays under the static textviews and/or layouts that I have created. Right now it's not and it's just overlapping.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
Button btn = (Button) findViewById(R.id.Add_new);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AddNewTask(v);
}
});
}
I tried both options to add a new textview and both of them just overalpp and I can't find any documentation on a method such as under/below, most I can find are just alight top and align bottom which wouldn't be useful in this case
public void AddNewTask(View v) {
RelativeLayout rl = (RelativeLayout) findViewById(R.id.overallview);
TextView tv= new TextView(this);
tv.setText("TEST");
rl.addView(tv);
}
My XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:id="#+id/overallview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.robertli.hustle.MainActivity"
tools:showIn="#layout/activity_main"
android:background="#00095e">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:id="#+id/topbar"
>
<TextView
android:id="#+id/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:text="Hustle"
android:textSize="25dp" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:layout_below="#id/topbar"
android:id="#+id/Add_new"
android:background="#00095e"
android:textColor="#ffffff"
android:clickable="true"
android:textSize="50dp" />
Suggestion : You should take a look at ListView to do this !!! ListView help you dynamically add the textview as well.
if you still want to adding directly to Relativelayout
refer this example:
RelativeLayout relativeLayout = new RelativeLayout(context);
View view = new View(context);
relativeLayout.addView(view);
code to dynamically add alignment in RelativeLayout
RelativeLayout.LayoutParams viewLayoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
viewLayoutParams.addRule(RelativeLayout.BELOW, R.id.your_view);
take a look at documentation for more
https://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams.html

dynamically set LinearLayout height/width in relativelayout

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

how to programmatically create an imageView with id and src parameters?

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);
}

Getting Java illegal state Exception when trying to add View by inflating xml

Em getting java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Not able to find out which view has to be removed, any help would be really helpful.
Here is the Code snippet
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:id="#+id/mainLayout"
android:layout_height="fill_parent"
android:orientation="vertical" >
</RelativeLayout>
data.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"
android:orientation="vertical" >
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</RelativeLayout>
Activity Code
public class ToDo extends Activity {
/** Called when the activity is first created. */
Button addNew;
RelativeLayout mainLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mainLayout=(RelativeLayout)findViewById(R.id.mainLayout);
RelativeLayout rel;
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(int idx=0;idx<2;idx++){
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rel = (RelativeLayout) inflater.inflate(R.layout.data,null);
params.setMargins(0, 50, 0, 0);
TextView fromWeb= (TextView) rel.findViewById(R.id.txt);
fromWeb.setText("AA");
mainLayout.addView(rel,params);
}
}
}
The code below is incorrect:
TextView fromWeb= (TextView) rel.findViewById(R.id.txt);
fromWeb.setText("AA");
rel.addView(fromWeb,params); // the TextView is alredy in the rel RelativeLayout!
mainLayout.addView(rel);
because you are adding again(with the addView method) the TextView which is already in the layout file(as you previously searched for it with findViewById). Instead it should be like this:
TextView fromWeb= (TextView) rel.findViewById(R.id.txt);
fromWeb.setText("AA");
mainLayout.addView(rel);
If you want margins for your TextView then set them in the layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/txt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="TextView" />
</RelativeLayout>

Inflating TextView and LinearLayout programmatically

The problem here I don't get the same output view result in these two cases, I want to fix case 1 to get same output result as case 2:
Inflate textview and linearlayout, and then add textview to linearlayout programmatically.
Add textview to linearlayout in xml.
Code and Output For Case 1:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
text_view.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:textColor="#000000"
android:text="1"
android:textSize="20sp"
android:background="#AAAAAA"
android:gravity="center"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="2dp"
android:layout_marginRight="2dp"
/>
onCreate method in LayoutTestActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout lt = (LinearLayout) getLayoutInflater().inflate(R.layout.main, null);
TextView tv = (TextView) getLayoutInflater().inflate(R.layout.text_view, null);
lt.addView(tv);
setContentView(lt);
}
output view (Not Correct)
Code and Output For Case 2:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:textColor="#000000"
android:text="1"
android:textSize="20sp"
android:background="#AAAAAA"
android:gravity="center"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="2dp"
android:layout_marginRight="2dp"
/>
</LinearLayout>
onCreate method in LayoutTestActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
output view (Correct)
I'm not sure if it makes any difference - but my suggestion is this:
Provide the android:id="#+id/linearLayout"-tag for the LinearLayout in your main.xml.
Then do this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout lt = (LinearLayout) findViewById( R.id.linearLayout );
TextView tv = (TextView) getLayoutInflater().inflate(R.layout.text_view, null);
lt.addView(tv);
}
You might also want to test if there is a difference between supplying null or your LinearLayout lt as the second parameter when inflating the TextView e.g.:
TextView tv = (TextView) getLayoutInflater().inflate(R.layout.text_view, lt);
You have to set the LayoutParams in the first case. In the second this is done automatically since TextView is in the xml. Hope this helps!
I think in the first place that you have to set the main layout in the setContentView() method directly and afterwards make the inflate.
setContentView(R.layout.main);
LinearLayout mainLayout = (Linearlayout) findViewbyId(R.id.mainLayoutId);
TextView tv = (TextView) getLayoutInflater().inflate(R.layout.text_view, mainLayout, false);
mainLayout.addView(tv);
I think this way it should work.
To keep the xml layout params you have to pass the last two parameters to the inflate() method.

Categories

Resources