Adding a view to a LinearLayout at a specified position - android

I have the following main.xml file with a LinearLayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1" android:id="#+id/llid">
<TextView android:text="Client profile"
android:id="#+id/ProfileName"
android:layout_width="fill_parent"
android:textStyle="bold"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
</TextView>
<TextView android:text="Specs"
android:id="#+id/Specs"
android:layout_width="fill_parent"
android:textStyle="bold"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
</TextView>
</LinearLayout>
I add an image to the LinearLayout via code at runtime like so
ImageView image = new ImageView(this);
image.setImageBitmap(bmp);
LinearLayout ll = (LinearLayout) findViewById(R.id.llid);
ll.addView(image);
However, I want to add the ImageView between the 2 TextViews in my LinearLayout. I can't seem to find a way in the android docs to add a view before another view, or after. How can I do this?
NB I call
setContentView(R.layout.main);
Before I add the ImageView to the LinearLayout.

When adding a View to a ViewGroup, you can specify an index which sets the position of the view in the parent.
You have two views and so (counting from zero) you would want to add at the 1st position; just call ll.addView(image, 1); to have it placed in between the two TextViews.

The docs state you can use the index to insert it where you want. I see you are using the signature of the view only, did you try the signature with the index parameter?
public void addView(View child, int index)

I faced a similar problem. In my case I wanted to add a LinearLayout at last position of another LinearLayout. To accomplish it, I did:
LinearLayout parentLayout = (LinearLayout) findViewById(R.id.parentLayout);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
// add others views to your linear layout
parentLayout.addView(layout, parentLayout.getChildCount());

setContentView(R.layout.main);
ImageView img = (ImageView) findViewById(R.id.imagefield);
img.setImageResource(your_image_here);
and in the xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1"
android:id="#+id/llid">
<TextView android:text="Client profile"
android:id="#+id/ProfileName"
android:layout_width="fill_parent"
android:textStyle="bold"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
</TextView>
<ImageView android:id="#+id/imagefield"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
<TextView android:text="Specs"
android:id="#+id/Specs"
android:layout_width="fill_parent"
android:textStyle="bold"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
</TextView>
</LinearLayout>

Add an ImageView into the xml, and if its not being used, make it invisible (image.setVisibility(View.INVISIBLE)). It may not show anything anyway when no image is set.

To get position of view in a view group
val targetPosition = oldLL.indexOfChild(viewToAdd)
To add a view at a position in a view group
newLL.addView(viewToAdd,targetPosition)

Related

(android) an scrollview that gets programmatically filled loses title

I have this layout:
<?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:layout_centerInParent="true"
android:layout_centerVertical="true"
android:background="#000"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal|center_vertical">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/play"
android:gravity="center_horizontal"
android:scaleType="centerInside"
android:text="#string/highScores"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff" />
<View
android:layout_width="1dp"
android:layout_height="20dp"></View>
<TableLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal">
</TableLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
I fill the 'container' TableLayout with elements like this:
layout.addView(buildTitleRow());
for (int i = 0; i < users.length(); i++) {
JSONObject parent = (JSONObject) users.get(i);
layout.addView(buildRowFrom(parent, i + 1));
}
buildTitleRow:
private TableRow buildTitleRow(){
TableRow result = new TableRow(this);
int color = Color.parseColor("#ffff00");
View view = new View(this);
view.setMinimumWidth(10);
result.addView(view);
view = new View(this);
view.setMinimumWidth(10);
result.addView(view);
//the same for other views
return result;
}
buildRowFrom:
private TableRow buildRowFrom(final JSONObject element, int counter) throws JSONException {
TableRow result = new TableRow(this);
String rowName = element.getString("name");
int color = Color.parseColor("#00ff00");
if(rowName.equals(userName)){
color = Color.parseColor("#ffffff");
}
TextView textView = new TextView(this);
textView.setText(counter + ".");
textView.setTextColor(color);
result.addView(textView);
//some other views
return result;
}
this really works well just until the scrolling needs to take place...
Once there are more elements than the height of the screen the table remains scrollable (luckily) but the original 'title' Textview doesn't show up anymore (you can't scroll up towards it anymore)
Does anyone know how to tweak the layout to keep it visible once more elements are added than the size of the screen?
Thanks a lot,
S.
I've tried your code and found find something wrong in your xml layout.
The attribute android:layout_gravity will change the layout's own gravity. So if set this attribute to a LinearLayout with center and its android:layout_height is wrap_content(means that the real height of the 'LinearLayout' will exceed the screen's height) and fill ScrollView(its height is the screen's height) with it, the LinearLayout will align to center of its parent ScrollView.
If you want to keep the content of 'LinearLayout' centered, you can set android:fillViewport="true" to ScrollView and then the LinearLayout will fill the parent and you can use android:gravity="center" on the LinearLayout. Reference
But there is still some thing need to be changed. In your java code, View view = new View(this) this line will new a View and then you add it into TableLayout. But this TableLayout will be full of View because of the description of View below.
* The base class implementation of measure defaults to the background size,
* unless a larger size is allowed by the MeasureSpec. Subclasses should
* override {#link #onMeasure(int, int)} to provide better measurements of
* their content.
You can use a concrete view like TextView instead of it.
I don't know if I have clarified it. I think if you remove the attribute android:layout_gravity of LinearLayout, it will work.
I'm glad if it would help.
I did the adaptations Paul suggested + change android:layout_height of the ScrollView to "wrap_content" to keep the inner LinearLayout centered when the android:layout_gravity="center" was removed from it (see complete layout below).
I wouldn't have found it without Paul's suggestion and explanation so I'll accept his answer as answer, this answer is just for the sake of completeness...
I'm not expecting this question to get that much of attention anyways ;-)
Thanks Paul :-D
<?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:layout_centerInParent="true"
android:layout_centerVertical="true"
android:background="#000"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|center_vertical">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/play"
android:gravity="center_horizontal"
android:scaleType="centerInside"
android:text="#string/highScores"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#fff" />
<View
android:layout_width="1dp"
android:layout_height="20dp"></View>
<TableLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal">
</TableLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>

How can i create multiple RelativeLayouts(with existing xml layout) in an LinearLayout programmatically?

I want to put multiple RelativeLayouts in one LinearLayout programmatically. Instead of using a ListView. My layout XML looks like following:
<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:background="#drawable/background_select_app" >
<ScrollView
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#80000000" >
<LinearLayout
android:id="#+id/parent_linear_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#FFFFFF" >
</LinearLayout>
</ScrollView>
</RelativeLayout>
and following is the RelativeLayout which I want to add as child in LinearLayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="280dp"
android:layout_height="40dp"
android:background="#drawable/row"
android:gravity="center" >
<TextView
android:id="#+id/name_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#333333" />
</RelativeLayout>
Can i do it programmatically? Thanks in advance.
try like this:
public void testgenerate() {
LinearLayout rootLaout=findViewById(R.id.idofliner);
LayoutInflater layoutInflater = getLayoutInflater();
for(int i=0;i<10;i++){
RelativeLayout inflate = (RelativeLayout) layoutInflater.inflate(R.layout.relativelayutid, null);
rootLaout.addView(inflate);
}
}
Usually there is no need to nest a RelativeLayout in your LinearLayout, you can achieve the same as Linearlayout with just a single RelativeLayout (so your view hierarchy has one Layout less to traverse --> improves performance ) or if you simply want to align your elements verticaly / horizontally than use only one LinearLayout instead of an extra RelativeLayout
Im not sure what you want to do, but to me it sounds like that RecyclerView or ListView is what you are looking for?

Adding Button To LinearLayout

I'm trying to add a button to a LinearLayout dynamically. Here is my code:
JAVA
LayoutInflater inflater = mMainActivity.getLayoutInflater();
View layout = inflater.inflate(R.layout.browse_list_fragment, (ViewGroup) getView(), false);
LinearLayout breadcrumb = (LinearLayout) layout.findViewById(R.id.browse_list_fragment_previous);
Button button = new Button(mMainActivity);
button.setText(name);
button.setTextColor(mMainActivity.getResources().getColor(R.color.action_bar_breadcrumb));
button.setTextSize(22);
button.setTypeface(Typeface.createFromAsset(mMainActivity.getAssets(), "HelveticaNeueBold.ttf"));
button.setTag(mHashMap);
breadcrumb.addView(button, new LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
XML
<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/browse_list_fragment_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#android:color/white">
<Button android:id="#+id/browse_list_fragment_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="#string/button_menu"
android:textColor="#color/grey"
android:background="#android:color/transparent"
android:drawableLeft="#drawable/carrot_grey"
android:onClick="buttonClick"/>
</LinearLayout>
<LinearLayout android:id="#+id/browse_list_fragment_previous"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical">
</LinearLayout>
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingLeft="5dp"/>
</LinearLayout>
The Problem
I don't have any exceptions thrown and when I connect the debugger and step through the code I can see that the button is in fact added to the layout. I have tried inflating a button and adding it, different combinations of Java and XML code, stubbing out lines of code, using RelativeLayout as the root layout, removing different parts of the layout and using different widths and heights but I can't ge this button to show up on the screen. Can someone can see what I'm doing wrong or at least point me in the right direction? I'd greatly appreciate it.
You called inflater.inflate() with false as the last argument:
View layout = inflater.inflate(R.layout.browse_list_fragment,
(ViewGroup) getView(), false);
So you are not adding the layout to any view and thus can't see the button you added to this layout. Try to call inflate() with true or add the layout later to the view.

Dynamically adding views to RelativeLayout inside ScrollView

I am trying to add dynamically created several RelativeLayouts into a LinearLayout which is inside a RelativeLayout, which is inside a ScrollView. When the total height of the all views exceed the size of the phone screen, all views are displayed correctly. But when the total size of dynamically added views is not enough for filling the screen, only the first RelativeLayout element is shown and the others are not displayed in the screen. I am really hopeless and do not understand why.
Here is the code to dynamically populate views inside linear layout:
LinearLayout commentsLayout = (LinearLayout) findViewById(R.id.comments_layout);
LayoutInflater inflater = (LayoutInflater)
this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for(Comment c: commentsList) {
RelativeLayout layoutItem = (RelativeLayout) inflater.inflate(
R.layout.list_item_comment, null, false);
TextView tv = (TextView) layoutItem.findViewById(R.id.textView);
ImageView iv = (ImageView) layoutItem.findViewById(R.id.imageView);
// set tv's text
// set iv's image and onclicklistener, nothing fancy here, everything goes well
commentsLayout.addView(layoutItem);
}
Here is list_item_comment.xml:
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white"
>
<ImageView
android:id="#+id/imageView"
android:layout_width="50dip"
android:layout_height="50dip"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="#+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_margin="10dp"
android:textSize="16sp"
android:layout_toRightOf="#id/imageView"
/>
</RelativeLayout>
And here is the xml file for this activity:
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/main_layout"
>
...
<ScrollView
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
android:id="#+id/scrollView"
>
<RelativeLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/relativeContainer"
>
...
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/comments_layout"
/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
And the screenshots:
Without sufficient layouts: (INCORRECT, needs to show 3 comments)
With enough layouts: (CORRECT ONE, screen is filled)
I just need to show all three comments in the first case :/ Thanks in advance.
instead of fill_parent, try changing the layout_height of the <RelativeLayout> of your list_item_comment.xml to wrap_content.
Also, why do you need another <RelativeLayout> inside your <ScrollView> of the xml of your activity. The LinearLayout is sufficient to do what you want your activity to look like. Maybe you can just remove it.

How can dynamically add a View to a ViewGroup and vertically align with one of its child

I have a ViewGroup and it has a few children. And one of them is a TextView ("+id/text").
In my code, I would like to know how can I add a new View or ViewGroup which will be positioned vertically aligned and below the TextView (+"id/text")?
Thank you.
I have followed the advice below and try to use TableLayout.
As a test, I try to layout statically to make sure things are aligned correctly.
Here is my layout xml:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout android:id="#+id/panel" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight">
<TableRow
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageButton
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:src="#drawable/icon"
android:layout_column="0" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="fill_parent"
android:layout_column="1">
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left" />
</LinearLayout>
</TableRow>
<TableRow>
<ImageButton
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:src="#drawable/icon"
android:layout_column="1"/>
</TableRow>
</TableLayout>
But when i run in on emulator. The ImageButton on the 2nd row, does not align vertically with the textView in 1st row. Any idea why?
Consider using a TableLayout as your ViewGroup. With a TableLayout you can programmatically add a child at a specific location.
View view = new ViewIWantToAdd();
TableLayout layout = (TableLayout)findViewById(R.id.table_layout);
layout.addView(view);
Would add a view at the bottom of the TableLayout. Typically you would use a TableRow as the contents of the TableView, but you can add any view.
If your layout is not so complex, use RelativeLayout
A Layout where the positions of the children can be described in
relation to each other or to the parent...
When you insert a new child view, create a new LayoutParams then setRule
You can put the child view below the textView with this
:)

Categories

Resources