LayoutInflater doesnt work - android

Im building like an chat app, so I want to add elements (user picture and message) on the go to my current view. The problem is in the showMessage function, nothings happens but no error too.
Here's my code:
ChatActivity -> showMessage:
RelativeLayout rly = new RelativeLayout(ChatActivity.this);
rly.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
LayoutInflater inflater = getLayoutInflater();
View viewToAppend = inflater.inflate(R.layout.messages,null);
rly.addView(viewToAppend);
messages XML:
<ImageView
android:id="#+id/imageView1"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="#drawable/fede" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#+id/imageView1"
android:text="messagetext" />
</RelativeLayout>
UPDATE
Adding setContentView(rly); works, but replace all the content with the "xml loaded", i want to append it, not replace all.

if you want to add a layout to the inflater you can just use the inflate method with the layout id as the parameter.
View v = ((LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE )).inflate(R.layout.info_window_adapter_layout, null);
Where context the the reference to the activity context

You may be try like codes. such as
LayoutInflater inflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
May be work successfully. Best of luck!

You create a new RelativeLayout and add the messages view to it, but you never attach the RelativeLayout to the content view. Assign your main layout an id (such as 'main_layout') in your layout xml, then add this:
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
mainLayout.addView(rly);

Related

Inflate layout and edit it in code

I have an android XML file with the following content:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relLay"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/ivQuit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/imgquit"
android:background="#null"
android:adjustViewBounds="true"
android:scaleType="fitXY"/>
<ImageButton
android:id="#+id/btnYes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/btnyes"
android:background="#null"
android:adjustViewBounds="true"
android:scaleType="fitXY"/>
<ImageButton
android:id="#+id/btnNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/btnno"
android:background="#null"
android:adjustViewBounds="true"
android:scaleType="fitXY"/>
</RelativeLayout>
Now I want to inflate it and then edit the ImageButtons via code. I do this as followed:
Inflate XML:
LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.quitgame, null);
Try editing an ImageButton:
ImageView imgView = (ImageView)findViewById(R.id.ivQuit);
ImageButton imgBtnYes = (ImageButton)findViewById(R.id.btnYes);
ImageButton imgBtnNo = (ImageButton)findViewById(R.id.btnNo);
RelativeLayout.LayoutParams relParams = (RelativeLayout.LayoutParams)imgBtnYes.getLayoutParams();
relParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
imgBtnYes.setLayoutParams(relParams);
However as long as the three code lines with the LayoutParams are existent the PopupWindow I create with the inflated view does not appear. It seems that the error is hidden in this line
RelativeLayout.LayoutParams relParams = (RelativeLayout.LayoutParams)imgBtnYes.getLayoutParams();
but I don't understand why.
Can anybody tell me why the PopupWindows does not appear because of this code line(s)?
Is it because of the PopupWindow itself or because of the LayoutInflater?
You have this
LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.quitgame, null);
Use the View object to initialize the views.
ImageView imgView = (ImageView)layout.findViewById(R.id.ivQuit);
ImageButton imgBtnYes = (ImageButton)layout.findViewById(R.id.btnYes);
ImageButton imgBtnNo = (ImageButton)layout.findViewById(R.id.btnNo);
You can findViewById of the current view hierachy set to the activity. In your case you are inflating your layout. So use the inlfated view object to initialize your views.
You are inflating the layout with root set to null, so your layout variable (returned by the inflate method) holds the root of the inflated layout (in this case, your RelativeLayout). I didnt see the code where you are attaching the inflated layout to your activity's content (maybe the code you posted is not complete?).
Given this, your findViewById calls should return nulls.
Moreover, as far as I know and understand, unless the view is attached to a view that is already somewhere in the activity, the LayoutParams are not going to be correct as no dimensions are set (even in case they are invoked on a view that isn't null, obviously).

how to add another view using layout inflatter

I created mainLayout with two buttons
add: to add other layout
remove : to remove other layout.
<Button
android:id="#+id/btnAdd"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Add View"
android:onClick="addView" />
<Button
android:id="#+id/btnRemove"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove View"
android:onClick="removeView" />
now i wrote following code to add the view
when I click on addView button
LayoutInflater inflater= (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
view=inflater.inflate(R.layout.other_layout,null);
mainLayout.addView(view);
the view is added below the main layout.
But I want the view to add in middle of the screen not at the bottom of screen.
How can I do that?
Modify this line and put ur parent view.
view=inflater.inflate(R.layout.other_layout,PARENT_VIEW_OBJECT);
It should work
get the parentLayout like this
parentLayout=(YourParentLayout)view.findViewById(R.id.parentLayout);
then
parentLayout.addView(yourview);
You can check below code, its working fine for me
private View view = null ;
Button addbutton = null;
ViewGroup parent = null;
LayoutInflater inflater = null;
inflater= (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
addbutton = (Button)findViewById(R.id.btnAdd);
parent = (ViewGroup) findViewById(R.id.mainxml);
addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
view = inflater.inflate(R.layout.other, null);
parent.addView(view);
}
});
I would put an empty LinearLayout placeholder at the top of your main layout where you want your view to be and add the view to that instead of the main layout.
You can adjust the placeholder first and modify it's location and looks.
<LinearLayout
android:id="#+id/placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
..../>
<Button
..../>
I would look into using a ViewStub it holds a place until .inflate() is called. That way the layout isn't taking resources until it's needed.

Programmatically add a new layout inside a SwipeView

I will try to explain my question in a very clear and understandable way.
I am currently using the SwipeView here: http://jasonfry.co.uk/?id=23
<uk.co.jasonfry.android.tools.ui.SwipeView
android:id="#+id/swipe_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View android:id="#+id/view1" />
<View android:id="#+id/view2" />
<View android:id="#+id/view3" />
</uk.co.jasonfry.android.tools.ui.SwipeView>
That'quite easy and powerful, and of course working fine.
What I would like to achieve now is to add some of my loayouts programmatically inside this SwipeView.
I have now:
SwipeView svmain=(SwipeView) findViewById(R.id.svmain);
//View v= findViewById(R.layout.anylayout);
svmain.addView(v);
That's crashing because the xml I want to add is not in my main layout.
Any idea?
Just found the answer:
SwipeView svmain=(SwipeView) findViewById(R.id.svmain);
LayoutInflater inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.header, null);
svmain.addView(view);
View view2 = inflater.inflate(R.layout.header, null);
svmain.addView(view2);
View view3 = inflater.inflate(R.layout.header, null);
svmain.addView(view3);

LayoutInflater doesn't seem to be linked with id in layout

I am completely lost with this LayoutInflater. I am trying to link items in code with items located in a remote layout. I have tried three different versions of the inflater creation. None of them work. However, this version seems to be the most widely used. Here is a snippet of the inflater garble:
setContentView(R.layout.browse);
LayoutInflater li = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ImageButton editBrowseButton = (ImageButton) li.inflate(R.layout.row, null).findViewById(R.id.imageButton1);
editBrowseButton.setAlpha(50);
This feels kinda like I missing something. Do I need to return something? The .setAlpha has no meaning. I just put it in to test the inlater. Obviously, it doesn't change the transparency. And if I add an onClickListner, it doesn't work. However, I don't get an exception. The activity starts up fine. Here is the relevant XML code for row.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout1"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusable="true"
>
<TableRow
android:id="#+id/tableRow1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:focusable="true"
>
<TextView
android:id= "#+id/txtItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text = "Item"
android:focusable="true"
/>
</TableRow>
<TableRow
android:id="#+id/tableRow2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:focusable="false"
>
<ImageButton
android:src="#drawable/editbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageButton1"
></ImageButton>
</TableRow>
</LinearLayout>
EDIT_01
New approach tried and failed. Same results. Nothing happens.
setContentView(R.layout.browse);
LayoutInflater li = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup rowView = (ViewGroup) li.inflate(R.layout.row, null);
LinearLayout rowLinLay = (LinearLayout) rowView
.findViewById(R.id.linearLayout1);
TableRow rowTableRow = (TableRow)rowLinLay.findViewById(R.id.tableRow2);
ImageButton editBrowseButton = (ImageButton) rowTableRow
.findViewById(R.id.imageButton1);
EDIT_02
setContentView(R.layout.browse);
ExpandableListView browseView = (ExpandableListView) findViewById(android.R.id.list);
LayoutInflater li = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = (View) li.inflate(R.layout.row, null);
TableRow rowTable = (TableRow) rowView.findViewById(R.id.tableRow2);
ImageButton editBrowseButton = (ImageButton) rowTable
.findViewById(R.id.imageButton1);
editBrowseButton.setAlpha(100);
Now that I can see your whole question :-)
LinearLayout layout = (LinearLayout) li.inflate( R.layout.linearLayout1, null);
TableRow tableRow = (TableRow) linearLayout1.findViewById(R.layout.tableRow2);
ImageButton editBrowseButton = (ImageButton) tableRow.findViewById(R.id.imageButton1);
I'm not sure what are you trying to do. AFAIK LayoutInflater is for "creating views" from resource xml files. Well at least that's what I use it for :D.
First "A TableRow should always be used as a child of a TableLayout" - so the xml looks funny too me - simple LinearLayout would be good. (but that's not on the side)
Anyhow - problem I see with the code is that the view that you inflate is not attached (2nd paramenter is null, and than you leave it hanging).
If you want to duplicate the entry - create it n-times you should do it like this:
setContentView(R.layout.browse);
LayoutInflater li = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout row = li.inflate(R.layout.row, null);
findViewById(/*id of element you want the row to be added to*/).add(row); //now row is attached
final ImageButton editBrowseButton = (ImageButton) row.findViewById(R.id.imageButton1); //so this is live, visible etc
editBrowseButton.setAlpha(50); //this should work than

Android - Dynamically Add Views into View

I have a layout for a view -
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0px"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/items_header"
style="#style/Home.ListHeader" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/items_none"
android:visibility="gone"
style="#style/TextBlock"
android:paddingLeft="6px" />
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/items_list" />
</LinearLayout>
What I want to do, is in my main activity with a layout like this
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="0px"
android:id="#+id/item_wrapper">
</LinearLayout>
I want to loop through my data model and inject multiple views consisting of the first layout into the main layout. I know I can do this by building the controls completely within the code, but I was wondering if there was a way to dynamically build the views so that I can continue using a layout instead of putting everything in code.
Use the LayoutInflater to create a view based on your layout template, and then inject it into the view where you need it.
LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);
// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");
// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
You may have to adjust the index where you want to insert the view.
Additionally, set the LayoutParams according to how you would like it to fit in the parent view. e.g. with FILL_PARENT, or MATCH_PARENT, etc.
See the LayoutInflater class.
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup parent = (ViewGroup)findViewById(R.id.where_you_want_to_insert);
inflater.inflate(R.layout.the_child_view, parent);
It looks like what you really want a ListView with a custom adapter to inflate the specified layout. Using an ArrayAdapter and the method notifyDataSetChanged() you have full control of the Views generation and rendering.
Take a look at these tutorials
http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
http://developerlife.com/tutorials/?p=327
http://www.androidguys.com/2008/07/14/fancy-listviews-part-one/
To make #Mark Fisher's answer more clear, the inserted view being inflated should be a xml file under layout folder but without a layout (ViewGroup) like LinearLayout etc. inside. My example:
res/layout/my_view.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/i_am_id"
android:text="my name"
android:textSize="17sp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
Then, the insertion point should be a layout like LinearLayout:
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/aaa"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/insert_point"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
</RelativeLayout>
Then the code should be
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shopping_cart);
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.my_view, null);
ViewGroup main = (ViewGroup) findViewById(R.id.insert_point);
main.addView(view, 0);
}
The reason I post this very similar answer is that when I tried to implement Mark's solution, I got stuck on what xml file should I use for insert_point and the child view. I used layout in the child view firstly and it was totally not working, which took me several hours to figure out. So hope my exploration can save others' time.
// Parent layout
LinearLayout parentLayout = (LinearLayout)findViewById(R.id.layout);
// Layout inflater
LayoutInflater layoutInflater = getLayoutInflater();
View view;
for (int i = 1; i < 101; i++){
// Add the text layout to the parent layout
view = layoutInflater.inflate(R.layout.text_layout, parentLayout, false);
// In order to get the view we have to use the new view with text_layout in it
TextView textView = (TextView)view.findViewById(R.id.text);
textView.setText("Row " + i);
// Add the text view to the parent layout
parentLayout.addView(textView);
}

Categories

Resources