I am new to Android programming...
I want to programmatically add layouts to a ScrollView, so I use this code below
for(int i = 0; i < 10; i++){
LinearLayout myLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.my_layout, null);
ImageView imgView = (ImageView) getLayoutInflater().inflate(R.layout.img_view, null);
//set ImageView source
TextView txtView = (TextView) getLayoutInflater().inflate(R.layout.txt_view, null);
//set TextView text
myLayout.addView(imgView);
myLayout.addView(txtView);
scrllView.addView(myLayout);
}
The above code works fine. But I want to know if there is a shorter and easier way to do this, because my code will be bulky, and I will have to create a layout XML file for every view I want to add
Maybe I am thinking instead of creating multiple XML file in my layout folder, I can just have one XML file, having LinearLayout as the parent with ImageView and TextView as children, so my_layout.xml will look like this
<?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="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:id="#+id/img"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/txt"/>
</LinearLayout>
Then I can inflate my_layout.xml file in my Java code add target the ImageView and TextView using their IDs
LinearLayout myLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.my_layout, null);
ImageView imgView = //find the child of myLayout (ImageView) with ID of img
//set ImageView source
TextView txtView = //find the child of myLayout (TextView) with ID of txt
//set TextView text
I want to know if it's possible to achieve this.
Okay... I finally got what I am looking for. The code below worked perfectly
LinearLayout myLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.my_layout, null);
ImageView imgView = myLayout.findViewById(R.id.img);
//set ImageView source
TextView txtView = myLayout.findViewById(R.id.txt);
//set TextView text
Related
I have a problem trying to align a view to RIGHT inside a relative layout programmatically:
Here is the xml(i don't ant to change the main layout, i want it linear layout because i'am simulating a problem):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main2"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.upf.ctrl_tp2.Main2Activity"
android:orientation="vertical">
</LinearLayout>
Here is the mainActivity.java code:
public class Main2Activity extends AppCompatActivity {
LinearLayout main;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
main = (LinearLayout) findViewById(R.id.activity_main2);
TextView txt = new TextView(this);
txt.setText("Hello World!");
txt.setTextSize(20);
RelativeLayout r = new RelativeLayout(this);
RelativeLayout.LayoutParams laypar = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
laypar.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);//seems that this doesn't work ?
r.setLayoutParams(laypar);
r.addView(txt);
main.addView(r);
}}
The Result i got:
What i wanted:
The align right will not work inside a linear layout.
The layout_gravity will work.
Replace
laypar.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);//seems that this doesn't work ?
with this
laypar.gravity = Gravity.RIGHT;
Set the LayoutParam to the TextView.
txt.setLayoutParams(laypar);
You can also use android:layout_alignParentRight="truein xml.
Yes MR. #CrazyDeveloper all thing looking good only one thing you have to remark .
RelativeLayout r = new RelativeLayout(this);
// actul issue belove .
RelativeLayout.LayoutParams laypar = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
just change it .
RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
Width is MATCH_PARENT instead of WRAP_CONTENT
try this :
main = (LinearLayout) findViewById(R.id.ll_layout);
TextView txt = new TextView(this);
txt.setText("Hello World!");
txt.setTextSize(20);
RelativeLayout r = new RelativeLayout(this);
RelativeLayout.LayoutParams laypar = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
laypar.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);//seems that this doesn't work ?
r.setGravity(Gravity.RIGHT);
r.setLayoutParams(laypar);
r.addView(txt);
ll_layout.addView(r);
I have an Activity and associated with it layout. Also I have another layout with some Views. I want to initialize a variable (TextView) from my Activity using a View from that standalone layout. I always get null.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button); // This is OK
// because R.id.button is from R.layout.main layout
tvOne = (TextView) findViewById(R.id.first_item); // This is not OK
// because R.id.first_item is from another layout.
}
You can't instantiate a view within another layout, but you can instantiate a layout which can be the view you want.
LayoutInflater inflater = getLayoutInflater();
TextView text = (TextView) inflater.inflate(R.layout.contenttext, yourRootView, false);
Here would be the corresponding layout (contenttext.xml):
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"/>
This is the correct behaviour, because findViewById() will only search for views set in the view hierarchy passed to setContentView()
I have a need to create more than one TableLayout with a varied number of rows in one XML layout.
In my main layout I have an empty LinearLayout, as shown below:
<LinearLayout android:id="#+id/resultsLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
I declare this in my activity as so:
private LinearLayout linearResultsLayout;
linearResultsLayout = (LinearLayout) findViewById(R.id.resultsLayout);
I have added a table_layout.xml and a table_row.xml to my Layouts folder:
Table_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/resultsTable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="99"
android:background="#drawable/curvedbg"
>
</TableLayout>
Table_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<TableRow xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView android:id="#+id/row_header" android:layout_weight="33" />
<TextView android:id="#+id/downstream" android:layout_weight="33"/>
<TextView android:id="#+id/upstream" android:layout_weight="33"/>
</TableRow>
My aim is to inflate the table and then inflate how ever many rows I require in to the newly inflated table whilst also passing data in the form of TextViews. The code below should give you an idea of what I'm trying to do. It doesn't work, however. NullPointerException.
private void createTable() {
String[] downResults = {"Downstream","2000","98"};
String[] upResults = {"Upstream","1000","78"};
String[] rowHeadings = {"","Bandwidth","QoS"};
TextView heading = (TextView) findViewById(R.id.row_header);
TextView downstream = (TextView) findViewById(R.id.downstream);
TextView upstream = (TextView) findViewById(R.id.upstream);
TableLayout newTable = (TableLayout) findViewById(R.id.resultsTable);
View table = inflater.inflate(R.layout.table_layout, null);
View row = inflater.inflate(R.layout.table_row, null);
linearResultsLayout.addView(table);
for(int i = 0; i < rowHeadings.length; i++){
heading.setText(rowHeadings[i].toString());
downstream.setText(downResults[i].toString());
upstream.setText(upResults[i].toString());
newTable.addView(row);
}
}
I assume it will be more complicated than how I'm trying to accomplish it.
You should probably use a ListView:
But, assuming you can't / won't, the problem you have is that you are referencing the wrong layout when you get your TextView objects. Your code should probably look more like this:
String[] downResults = {"Downstream","2000","98"};
String[] upResults = {"Upstream","1000","78"};
String[] rowHeadings = {"","Bandwidth","QoS"};
View table = inflater.inflate(R.layout.table_layout, linearResultsLayout, false));
View row = inflater.inflate(R.layout.table_row, linearResultsLayout, false));
TextView heading = (TextView) row.findViewById(R.id.row_header);
TextView downstream = (TextView) row.findViewById(R.id.downstream);
TextView upstream = (TextView) row.findViewById(R.id.upstream);
TableLayout newTable = (TableLayout) table.findViewById(R.id.resultsTable);
linearResultsLayout.addView(table);
for(int i = 0; i < rowHeadings.length; i++){
heading.setText(rowHeadings[i].toString());
downstream.setText(downResults[i].toString());
upstream.setText(upResults[i].toString());
table.addView(row);
}
Notice the row.findViewById and also the table.addView
EDIT: note the change in the layout inflater
This is my layout xml file:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/container1"
android:tag="1"
//... >
<TextView
android:id="#+id/txt1"
android:tag="1"
//... />
</LinearLayout>
<LinearLayout
android:id="#+id/container2"
android:tag="2"
//... >
<TextView
android:id="#+id/txt2"
android:tag="2"
//... />
</LinearLayout>
//...
It has 2 containers and one textview inside each one. Now, when I touch one button I need the container to exchange the textviews. To get this, this is my approach:
person1 = (TextView) findViewById(R.id.txt1);
person2 = (TextView) findViewById(R.id.txt2);
place1 = (LinearLayout) findViewById(R.id.place1);
place2 = (LinearLayout) findViewById(R.id.place2);
-
place1.removeView(person1);
place2.removeView(person2);
place1.addView(person2);
place2.addView(person1);
But this is what I'm getting on the LogCat:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Both the layouts contains a single TextView inside them. So instead of removing and adding views why don't you just switch the text between them? It would save your time and your performance would be better.
LinearLayout ll = (LinearLayout) findViewById(R.id.your_ll_id);
TextView tv = (LinearLayout) findViewById(R.id.your_tv_id);
ViewGroup parent = (ViewGroup) tv.getParent();
parent.removeView(tv);
tv.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
//...
ll.addView(tv);
You have to add textview at runtime in linearlayout rather than add textview in xml at compile time.
if you add textview at runtime it will not give you error.
linearLayout.removeAllViews();
final TextView person1 = new TextView(this);
linearLayout1.addView(person1);
final TextView person2 = new TextView(this);
linearLayout2.addView(person2);
I need to put an ImageView under a TextView that was constructed using java. The textview is displaying information from a previous activity. Here is my code:
package com.example.a_simple_ui;
public class MainActivity2 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent recieve = getIntent();
String message = recieve.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
setContentView(textView);
}
}
So now I need a picture under the textview above and to change the background color. Either by java or XML. Thank you.
You can use any approach from bellow two suggestion:
1) If your layout design is fixed than it is better to use xml based layout (static layout) rather than adding layout run-time.
For that first create xml layout main_Activity.xml like:
main_Activity.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:orientation="vertical" >
<TextView
android:id="#+id/tvDesc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<Imageview
android:id="#+id/ivIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/ic_launcher" />
</LinearLayout>
MainActivity2 .java
package com.example.a_simple_ui; public class MainActivity2 extends
Activity {
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(textView); Intent recieve = getIntent();
String message = recieve.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView =(TextView)findViewById(R.id.tvDesc);
textView.setTextSize(40);
textView.setText(message); } }
2) You need to add TextView and Imageview in linearlayout then need to set that linearlayout in setContentView() like:
package com.example.a_simple_ui;
public class MainActivity2 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent recieve = getIntent();
String message = recieve.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
ImageView imageView = new ImageView(this);
imageView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
imageView.setImageResource(R.drawable.ic_launcher);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(textview);
layout.addView(imageView);
setContentView(layout);
}
}
Ok, actually I can't understand, why you use TextView class as you content view. In that case, you can, offcourse, make you own textview extending default one and create particular layout with imageview for it, but, the easiest (and more logical) way is to create lauout file for your activity with TextView and ImageView.
For example, it can be something like that:
<?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" >
<ImageView
android:id="#+id/myImageView"
android:layout_width="wrap_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/myTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
And your activity onCreate method will be looks something like:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(textView);
Intent recieve = getIntent();
String message = recieve.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = (TextView) findViewById(R.id.myTextView);
textView.setTextSize(40);
textView.setText(message);
ImageView imageView = (ImageView) findViewById(R.id.myImageView);
}
You need to call setContentView before finding views by id.
If you have to create texview dynamic, from java (I can't see any reason for it from your code) you can add id property to LinearLayout and than find it by id and add texview to that, and it will be placed after imageview.
p.s. Actually there are a lot of ways to do that, please, define your question more preciselly if my answer doesn't suits you
p.p.s. If you really have to create textView in runtime and you can't use xml layouts, you can create LinearLayout in runtime (LinearLayout layout = new LinearLayout(this) and after that, create textView and ImageView and add that two views to that layout, after that make set this layout as content view for the activity