Using TextView to inflate Layout - android

Upon clicking each TextView they should lead to another layout file to help the user learn about human trafficking. In the onCreate method I have setOnClickListener to my text view. Inflating it is an issue though. Is this called inflating a view? I've seen people recommending the use of fragments for this, using setContentView (from what I've found this shouldn't be used), and using the layout inflater while passing in the layout I want and null. However that doesn't work. How should this code look?
The 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: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"
tools:context="com.example.piatt.worksafe.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Work Safe!"
android:textSize="36sp"
android:layout_centerHorizontal="true"
android:paddingBottom="32dp"
android:id="#+id/title"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="What is Human Trafficing?"
android:layout_below="#+id/title"
android:layout_centerHorizontal="true"
android:textSize="24sp"
android:padding="16dp"
android:id="#+id/whatIsHumanTrafficing"
android:clickable="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How do I get safe labor?"
android:layout_below="#+id/whatIsHumanTrafficing"
android:layout_centerHorizontal="true"
android:textSize="24sp"
android:padding="16dp"
android:id="#+id/howDoIGetSafeLabor"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How do I check that my job / job offer is legal?"
android:layout_below="#+id/howDoIGetSafeLabor"
android:layout_centerHorizontal="true"
android:textSize="24sp"
android:padding="16dp"
android:gravity="center"
android:id="#+id/checkLegality"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How can I get help?"
android:layout_below="#+id/checkLegality"
android:layout_centerHorizontal="true"
android:textSize="24sp"
android:padding="16dp"
android:id="#+id/getHelp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="About us"
android:layout_below="#+id/getHelp"
android:layout_centerHorizontal="true"
android:textSize="16sp"
android:layout_alignParentBottom="true"
android:gravity="bottom"
android:id="#+id/aboutUs"
/>
</RelativeLayout>
The java class:
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView whatIsHumanTrafficing = (TextView) findViewById(R.id.whatIsHumanTrafficing);
whatIsHumanTrafficing.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
//What is this context, why do I need it and where does it come from?
//What is the ViewGroup, why do I need it and where does it come from?
view.inflate(Context context, R.layout.what_is_human_trafficing, ViewGroup root);
}
});
}

Aside: You could read the documentation for View.inflate
What is this context, why do I need it and where does it come from?
What: YourActivity.this (replace with your actual class name)
Why: You need it as a parameter to inflate a View.
What is the ViewGroup, why do I need it and where does it come from?
You probably don't need it; it can be null. It is the ViewGroup to inflate the View into. Like for a ListView, you would load each row into the list as the "group".
Anyways, if you want to dynamically show different layout file based upon what is clicked, yes Fragment's are one way to do that, and so are ViewStub's.
And you aren't actually calling inflate on the TextView because it is a static method. It is equivalent to doing this with a LayoutInflater
View v = LayoutInflater.from(YourActivity.this).inflate(R.layout.your_layout, null);
// TODO: Do something with v

The final code should look like:
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout rl = (RelativeLayout) findViewById(R.id.splashScreenId);
TextView whatIsHumanTrafficing = (TextView) findViewById(R.id.whatIsHumanTrafficing);
whatIsHumanTrafficing.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
MainActivity.this.setContentView(R.layout.what_is_human_trafficing);
}
});
}
Set an on click listener to the text view then within it on MainActivity.this set the content view to the layout you want.

Related

Accessing element from same layout parent

i have a listview with different components (2 linear layouts and a button) , what i want to do is when i click on a button that's inside one of those linear layouts , i want to access a textview that's inside the other linearlayout , is it possible ?
<?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">
<ListView
android:id="#+id/listV2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/icon"
android:layout_width="85dp"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="150dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/nom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/textCname"
android:textSize="21dp"
android:textStyle="bold" />
<TextView
android:id="#+id/numero"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12dp"
android:textColor="#color/textCother"
android:textStyle="italic" />
<TextView
android:id="#+id/ville"
android:layout_width="match_parent"
android:textColor="#color/textCother"
android:layout_height="wrap_content"
android:textSize="12dp"
android:textStyle="italic" />
</LinearLayout>
<Button
android:layout_width="50dp"
android:layout_height="wrap_content"
android:visibility="invisible" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
>
<ImageView
android:id="#+id/remove"
android:onClick="contactRemove"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/edit"
android:onClick="contactEdit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="22dp"/>
<ImageView
android:onClick="contactCall"
android:id="#+id/call"
android:layout_marginLeft="22dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
what i want to do is access the value of android:id="#+id/numero"
when i click on one of the image views
You can set OnClickListener interface provided by View class. Something like this.
Implement listener on your activity class
public class SpinnerActivity extends AppCompatActivity implements
View.OnClickListener
Declare class level variables for your views
private TextView tvNumero;
private ImageView ivRemove, ivEdit, ivContactCall;
Find initialise value in onCreate() method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gildi_spinner);
tvNumero = (TextView) findViewById(R.id.numero)
ivRemove = (ImageView) findViewById(R.id.remove);
ivEdit = (ImageView) findViewById(R.id.edit);
ivContactCall = (ImageView) findViewById(R.id.contactCall);
ivRemove.setOnClickListener(this);
ivEdit.setOnClickListener(this);
ivContactCall.setOnClickListener(this);
}
Implemented class from Onclickistener, where you get on click event for your registered views
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.remove:
case R.id.edit:
case R.id.contactCall:
Toast.makeText(this, tvNumero.getText().toString(), Toast.LENGTH_SHORT).show();
break;
}
}
NOTE : tvNumero.getText().toString() gives you the value of your desired TextView.
UPDATE :
Firstly replace your ListView with RecyclerView
Refer RecyclerView Example tutorial.
Secondly to achieve onClick for your listed items
Refer recyclerview-onclick tutorial.
Pass context when you create your adapter, Use that context to get the inflated view.
Adapter adapter = new Adapter(this);
Then in Adpater Class constructor :
public Adapter(Context context){
context.findViewById(R.id.textview);//consider this as numero textview
}
Then access it as per your requirement. Hope it helps!

Extending RelativeLayout by inflating from xml?

I want to create a class named TabView which extends RelativeLayout and it is inflated from xml that contains RelativeLayout. The thing is that it doesn't seem to work as I expected. Did I do something wrong in the constructor? I know layoutInflater.inflate returns View object but what do I have to make it equal to? Any advice is apprecited!
private class TabView extends RelativeLayout {
private int mIndex;
public TabView(Context context) {
super(context, null, R.attr.vpiTabPageIndicatorStyle);
LayoutInflater layoutInflater = LayoutInflater.from(context);
layoutInflater.inflate(R.layout.tabview_title_subtitle, null);
}
public int getIndex() {
return mIndex;
}
public void setTitle() {
TextView title = (TextView)findViewById(R.id.title);
title.setText("Followers");
}
public void setSubitle() {
TextView subtitle = (TextView)findViewById(R.id.subtitle);
subtitle.setText("435");
}
}
The following is tabview_title_subtitle.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" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:text="Subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
First, your layout should look like this:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Title"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/title"
android:text="Subtitle"
android:textAppearance="?android:attr/textAppearanceMedium" />
</merge>
In other way you'll end up with RelativeLayout that contains another RelativeLayout
Second. Inflate it like this:
layoutInflater.inflate(R.layout.tabview_title_subtitle, this);
You can see the following blog for creating and using custom views in android.
And probably using
inflater.inflate(R.layout.view_color_options, this, true);
instead of
layoutInflater.inflate(R.layout.tabview_title_subtitle, null);
is what you need to do.
Use:
layoutInflater.inflate(R.layout.tabview_title_subtitle, this);
to actually add the inflated view to TabView(right now you just inflate it and immediately discard it). Also if you want to use your custom view in a xml layout then also implement the constructor that takes a Context and an AttributeSet.

Add a RelativeLayout dynamically to a LinearLayout in Android

I have been trying for a while to work out how to dynamically create a RelativeLayout with multiple views inside (e.g. TextView, ProgressBar) a LinearLayout to create a RelativeLayout beneath the previous one after every button click. Please can anyone look at my code and see if there is anything that I can do to solve this issue.
Here is the code:
activity_test_container.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/frag1ScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/testLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".TestContainerActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/testContainerTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/testContainerTextView1"
android:layout_marginBottom="16dp"
android:text="TextView2" />
<TextView
android:id="#+id/testContainerTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="TextView1" />
<Button
android:id="#+id/testContainerButton1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/testContainerTextView2"
android:text="Button" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
container.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/containerLayout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:layout_marginBottom="16dp"
android:background="#color/display_panels" >
<ProgressBar
android:id="#+id/containerProgressBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/containerImageButton2"
android:max="100"
android:progress="40" />
<TextView
android:id="#+id/containerTextView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/containerTextView6"
android:layout_alignLeft="#+id/containerProgressBar1"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/containerTextView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/containerProgressBar1"
android:layout_centerHorizontal="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
<ImageButton
android:id="#+id/containerImageButton2"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#+id/containerTextView6"
android:background="#color/display_panels"
android:contentDescription="Okay icon"
android:src="#drawable/ic_green_ok" />
</RelativeLayout>
TestContainerActivity.java
public class TestContainerActivity extends Activity implements OnClickListener {
LinearLayout containerLayout;
Button testButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.test_container, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v==testButton){
createNewLayout();
}
}
public void createNewLayout(){
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View addView = layoutInflater.inflate(R.layout.container, null);
containerLayout.addView(addView);
}
}
I'm not entirely sure what you're problem is, but I suspect it's that the rows are not showing up at all because I don't see where you attach the listener to the Button. To handle a click event, an OnClickListener needs to be set on your View. Though this is commonly done with Buttons, OnClickListeners can be set on any view, so any size/shape widget can be made clickable. This is done with the setOnClickListener method of a View. There are multiple ways to do this, try modifying your onCreate like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
testButton.setOnClickListener(this);
}
An alternative method to setting your listener would be to create the listener in onCreate rather than using the Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_container);
testButton = (Button)findViewById(R.id.testContainerButton1);
containerLayout = (LinearLayout)findViewById(R.id.testLayout);
testButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createNewLayout();
}
});
}
In this case, you wouldn't need to have your Activity implement OnClickListener. I usually only will do something like that if I have many buttons with similar functionality, where creating listeners for each will cause a performance hit. For more isolated cases like this, I prefer to set individual Listeners since the performance difference will be negligible, but that's just my personal preference.
Hope this helps! If your problem was actually based somewhere else, please modify your question and I'll try my best to assist! Also, keep in mind that you can use the Log class to post information about execution in your LogCat output. It really helps with debugging! I suspect that if you put some logging in your listener and createNewLayout() right now, you'd see that the logging never happens because those methods are never called.

myView.setLayoutParams(otherView.getLayoutParams()); Not working, why?

Got my TextView in the xml:
<TextView
android:id="#+id/myTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="left"
android:text="TextView"/>
I want to create multiple TextViews but i want to look them the same as this.
So I tried:
TextView newTextView = new TextView(this);
newTextView.setLayoutParams(myTextView.getLayoutParams());
I think this should get all the layout parameters from myTextView straigthlghly(?) from the xml, and pass them to newTextView to set them.
My problem is: Nothing happens. It does not take effect, why?
here's a sample project which shows that it works.
you can see that it works by looking at the preview of the visual editor , which looks different than what is shown at runtime.
i think that your mistake was that you didn't set 0px (or 0dp, zero is still zero) for the weighted views.
main.xml (layout) :
<?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:id="#+id/container">
<TextView android:id="#+id/textView1" android:layout_width="wrap_content"
android:layout_height="0px" android:text="TextView1"
android:layout_weight="1" android:background="#ffff0000" />
<TextView android:id="#+id/textView2" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="TextView2"
android:background="#ff00ff00" />
</LinearLayout>
TestActivity.java :
public class TestActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView tv1=(TextView)findViewById(R.id.textView1);
final TextView tv2=(TextView)findViewById(R.id.textView2);
final LayoutParams layoutParams=tv1.getLayoutParams();
tv2.setLayoutParams(layoutParams);
// adding textView programatically:
final TextView tv3=new TextView(this);
tv3.setText("textView3");
tv3.setBackgroundColor(0xff0000ff);
tv3.setLayoutParams(layoutParams);
final ViewGroup root=(ViewGroup)findViewById(R.id.container);
root.addView(tv3);
}
}

What does LayoutInflater in Android do?

What is the use of LayoutInflater in Android?
The LayoutInflater class is used to instantiate the contents of layout XML files into their corresponding View objects.
In other words, it takes an XML file as input and builds the View objects from it.
What does LayoutInflator do?
When I first started Android programming, I was really confused by LayoutInflater and findViewById. Sometimes we used one and sometimes the other.
LayoutInflater is used to create a new View (or Layout) object from one of your xml layouts.
findViewById just gives you a reference to a view than has already been created. You might think that you haven't created any views yet, but whenever you call setContentView in onCreate, the activity's layout along with its subviews gets inflated (created) behind the scenes.
So if the view already exists, then use findViewById. If not, then create it with a LayoutInflater.
Example
Here is a mini project I made that shows both LayoutInflater and findViewById in action. With no special code, the layout looks like this.
The blue square is a custom layout inserted into the main layout with include (see here for more). It was inflated automatically because it is part of the content view. As you can see, there is nothing special about the code.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
Now let's inflate (create) another copy of our custom layout and add it in.
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
To inflate the new view layout, all I did was tell the inflater the name of my xml file (my_layout), the parent layout that I want to add it to (mainLayout), and that I don't actually want to add it yet (false). (I could also set the parent to null, but then the layout parameters of my custom layout's root view would be ignored.)
Here it is again in context.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// inflate the main layout for the activity
setContentView(R.layout.activity_main);
// get a reference to the already created main layout
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.activity_main_layout);
// inflate (create) another copy of our custom layout
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
// make changes to our custom layout and its subviews
myLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorAccent));
TextView textView = (TextView) myLayout.findViewById(R.id.textView);
textView.setText("New Layout");
// add our custom layout to the main layout
mainLayout.addView(myLayout);
}
}
Notice how findViewById is used only after a layout has already been inflated.
Supplemental Code
Here is the xml for the example above.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/activity_main_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- Here is the inserted layout -->
<include layout="#layout/my_layout"/>
</LinearLayout>
my_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#color/colorPrimary">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="5dp"
android:textColor="#android:color/white"
android:text="My Layout"/>
</RelativeLayout>
When do you need LayoutInflater
The most common time most people use it is in a RecyclerView. (See these RecyclerView examples for a list or a grid.) You have to inflate a new layout for every single visible item in the list or grid.
You also can use a layout inflater if you have a complex layout that you want to add programmatically (like we did in our example). You could do it all in code, but it is much easier to define it in xml first and then just inflate it.
When you use a custom view in a ListView you must define the row layout.
You create an xml where you place android widgets and then in the adapter's code you have to do something like this:
public MyAdapter(Context context, List<MyObject> objects) extends ArrayAdapter {
super(context, 1, objects);
/* We get the inflator in the constructor */
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
/* We inflate the xml which gives us a view */
view = mInflater.inflate(R.layout.my_list_custom_row, parent, false);
/* Get the item in the adapter */
MyObject myObject = getItem(position);
/* Get the widget with id name which is defined in the xml of the row */
TextView name = (TextView) view.findViewById(R.id.name);
/* Populate the row's xml with info from the item */
name.setText(myObject.getName());
/* Return the generated view */
return view;
}
Read more in the official documentation.
LayoutInflater.inflate() provides a means to convert a res/layout/*.xml file defining a view into an actual View object usable in your application source code.
basic two steps: get the inflater and then inflate the resource
How do you get the inflater?
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
How do you get the view assuming the xml file is "list_item.xml"?
View view = inflater.inflate(R.layout.list_item, parent, false);
Here is another example similar to the previous one, but extended to further demonstrate inflate parameters and dynamic behavior it can provide.
Suppose your ListView row layout can have variable number of TextViews. So first you inflate the base item View (just like the previous example), and then loop dynamically adding TextViews at run-time. Using android:layout_weight additionally aligns everything perfectly.
Here are the Layouts resources:
list_layout.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="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="#+id/field1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
<TextView
android:id="#+id/field2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
</LinearLayout>
schedule_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
Override getView method in extension of BaseAdapter class
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = activity.getLayoutInflater();
View lst_item_view = inflater.inflate(R.layout.list_layout, null);
TextView t1 = (TextView) lst_item_view.findViewById(R.id.field1);
TextView t2 = (TextView) lst_item_view.findViewById(R.id.field2);
t1.setText("some value");
t2.setText("another value");
// dinamically add TextViews for each item in ArrayList list_schedule
for(int i = 0; i < list_schedule.size(); i++){
View schedule_view = inflater.inflate(R.layout.schedule_layout, (ViewGroup) lst_item_view, false);
((TextView)schedule_view).setText(list_schedule.get(i));
((ViewGroup) lst_item_view).addView(schedule_view);
}
return lst_item_view;
}
Note different inflate method calls:
inflater.inflate(R.layout.list_layout, null); // no parent
inflater.inflate(R.layout.schedule_layout, (ViewGroup) lst_item_view, false); // with parent preserving LayoutParams
This class is used to instantiate layout XML file into its corresponding View objects. It is never be used directly -- use getLayoutInflater() or getSystemService(String) to retrieve a standard LayoutInflater instance that is already hooked up to the current context and correctly configured for the device you are running on. For example:
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
Reference: http://developer.android.com/reference/android/view/LayoutInflater.html
LayoutInflater is a class used to instantiate layout XML file into its corresponding view objects which can be used in Java programs.
In simple terms, there are two ways to create UI in android. One is a static way and another is dynamic or programmatically.
Suppose we have a simple layout main.xml having one textview and one edittext as follows.
<?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:id="#+id/layout1"
>
<TextView
android:id="#+id/namelabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter your name"
android:textAppearance="?android:attr/textAppearanceLarge" >
</TextView>
<EditText
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="14dp"
android:ems="10">
</EditText>
</LinearLayout>
We can display this layout in static way by
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
A dynamic way of creating a view means the view is not mentioned in our main.xml but we want to show with this in run time. For example, we have another XML in layout folder as footer.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/TextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Add your record"
android:textSize="24sp" >
</TextView>
We want to show this textbox in run time within our main UI. So here we will inflate text.xml. See how:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TextView t = (TextView)inflater.inflate(R.layout.footer,null);
lLayout = (LinearLayout)findViewById(R.id.layout1);
lLayout.addView(t);
Here I have used getSystemService (String) to retrieve a LayoutInflater instance. I can use getLayoutInflator() too to inflate instead of using getSystemService (String) like below:
LayoutInflator inflater = getLayoutInflater();
TextView t = (TextView) inflater.inflate(R.layout.footer, null);
lLayout.addView(t);
Inflating means reading the XML file that describes a layout (or GUI element) and to create the actual objects that correspond to it, and thus make the object visible within an Android app.
final Dialog mDateTimeDialog = new Dialog(MainActivity.this);
// Inflate the root layout
final RelativeLayout mDateTimeDialogView = (RelativeLayout) getLayoutInflater().inflate(R.layout.date_time_dialog, null);
// Grab widget instance
final DateTimePicker mDateTimePicker = (DateTimePicker) mDateTimeDialogView.findViewById(R.id.DateTimePicker);
This file could saved as date_time_dialog.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/DateTimeDialog" android:layout_width="100px"
android:layout_height="wrap_content">
<com.dt.datetimepicker.DateTimePicker
android:id="#+id/DateTimePicker" android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout android:id="#+id/ControlButtons"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_below="#+id/DateTimePicker"
android:padding="5dip">
<Button android:id="#+id/SetDateTime" android:layout_width="0dip"
android:text="#android:string/ok" android:layout_weight="1"
android:layout_height="wrap_content"
/>
<Button android:id="#+id/ResetDateTime" android:layout_width="0dip"
android:text="Reset" android:layout_weight="1"
android:layout_height="wrap_content"
/>
<Button android:id="#+id/CancelDialog" android:layout_width="0dip"
android:text="#android:string/cancel" android:layout_weight="1"
android:layout_height="wrap_content"
/>
</LinearLayout>
This file could saved as date_time_picker.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="wrap_content" `enter code here`
android:padding="5dip" android:id="#+id/DateTimePicker">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:baselineAligned="true"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/month_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="1dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/month_plus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_up_final"/>
<EditText
android:id="#+id/month_display"
android:layout_width="45dp"
android:layout_height="35dp"
android:background="#drawable/picker_middle"
android:focusable="false"
android:gravity="center"
android:singleLine="true"
android:textColor="#000000">
</EditText>
<Button
android:id="#+id/month_minus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_down_final"/>
</LinearLayout>
<LinearLayout
android:id="#+id/date_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0.5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/date_plus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_up_final"/>
<EditText
android:id="#+id/date_display"
android:layout_width="45dp"
android:layout_height="35dp"
android:background="#drawable/picker_middle"
android:gravity="center"
android:focusable="false"
android:inputType="number"
android:textColor="#000000"
android:singleLine="true"/>
<Button
android:id="#+id/date_minus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_down_final"/>
</LinearLayout>
<LinearLayout
android:id="#+id/year_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0.5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/year_plus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_up_final"/>
<EditText
android:id="#+id/year_display"
android:layout_width="45dp"
android:layout_height="35dp"
android:background="#drawable/picker_middle"
android:gravity="center"
android:focusable="false"
android:inputType="number"
android:textColor="#000000"
android:singleLine="true"/>
<Button
android:id="#+id/year_minus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_down_final"/>
</LinearLayout>
<LinearLayout
android:id="#+id/hour_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/hour_plus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_up_final"/>
<EditText
android:id="#+id/hour_display"
android:layout_width="45dp"
android:layout_height="35dp"
android:background="#drawable/picker_middle"
android:gravity="center"
android:focusable="false"
android:inputType="number"
android:textColor="#000000"
android:singleLine="true">
</EditText>
<Button
android:id="#+id/hour_minus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_down_final"/>
</LinearLayout>
<LinearLayout
android:id="#+id/min_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0.35dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/min_plus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_up_final"/>
<EditText
android:id="#+id/min_display"
android:layout_width="45dp"
android:layout_height="35dp"
android:background="#drawable/picker_middle"
android:gravity="center"
android:focusable="false"
android:inputType="number"
android:textColor="#000000"
android:singleLine="true"/>
<Button
android:id="#+id/min_minus"
android:layout_width="45dp"
android:layout_height="45dp"
android:background="#drawable/image_button_down_final"/>
</LinearLayout>
<LinearLayout
android:id="#+id/meridiem_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="0.35dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:gravity="center"
android:orientation="vertical">
<ToggleButton
android:id="#+id/toggle_display"
style="#style/SpecialToggleButton"
android:layout_width="40dp"
android:layout_height="32dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="45dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:padding="5dp"
android:gravity="center"
android:textOn="#string/meridiem_AM"
android:textOff="#string/meridiem_PM"
android:checked="true"/>
<!-- android:checked="true" -->
</LinearLayout>
</LinearLayout>
</RelativeLayout>
The MainActivity class saved as MainActivity.java:
public class MainActivity extends Activity {
EditText editText;
Button button_click;
public static Activity me = null;
String meridiem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText)findViewById(R.id.edittext1);
button_click = (Button)findViewById(R.id.button1);
button_click.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view){
final Dialog mDateTimeDialog = new Dialog(MainActivity.this);
final RelativeLayout mDateTimeDialogView = (RelativeLayout) getLayoutInflater().inflate(R.layout.date_time_dialog, null);
final DateTimePicker mDateTimePicker = (DateTimePicker) mDateTimeDialogView.findViewById(R.id.DateTimePicker);
// mDateTimePicker.setDateChangedListener();
((Button) mDateTimeDialogView.findViewById(R.id.SetDateTime)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mDateTimePicker.clearFocus();
int hour = mDateTimePicker.getHour();
String result_string = mDateTimePicker.getMonth() +" "+ String.valueOf(mDateTimePicker.getDay()) + ", " + String.valueOf(mDateTimePicker.getYear())
+ " " +(mDateTimePicker.getHour()<=9? String.valueOf("0"+mDateTimePicker.getHour()) : String.valueOf(mDateTimePicker.getHour())) + ":" + (mDateTimePicker.getMinute()<=9?String.valueOf("0"+mDateTimePicker.getMinute()):String.valueOf(mDateTimePicker.getMinute()))+" "+mDateTimePicker.getMeridiem();
editText.setText(result_string);
mDateTimeDialog.dismiss();
}
});
// Cancel the dialog when the "Cancel" button is clicked
((Button) mDateTimeDialogView.findViewById(R.id.CancelDialog)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mDateTimeDialog.cancel();
}
});
// Reset Date and Time pickers when the "Reset" button is clicked
((Button) mDateTimeDialogView.findViewById(R.id.ResetDateTime)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mDateTimePicker.reset();
}
});
// Setup TimePicker
// No title on the dialog window
mDateTimeDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// Set the dialog content view
mDateTimeDialog.setContentView(mDateTimeDialogView);
// Display the dialog
mDateTimeDialog.show();
}
});
}
}
What inflater does
It takes a xml layout as input (say) and converts it to View object.
Why needed
Let us think a scenario where we need to create a custom listview. Now each row should be custom. But how can we do it. Its not possible to assign a xml layout to a row of listview. So, we create a View object. Thus we can access the elements in it (textview,imageview etc) and also assign the object as row of listview
So, whenever we need to assign view type object somewhere and we have our custom xml design we just convert it to object by inflater and use it.
here is an example for geting a refrence for the root View of a layout ,
inflating it and using it with setContentView(View view)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater li=getLayoutInflater();
View rootView=li.inflate(R.layout.activity_main,null);
setContentView(rootView);
}
Layout inflater is a class that reads the xml appearance description and convert them into java based View objects.
LayoutInflater creates View objects based on layouts defined in XML. There are several different ways to use LayoutInflater, including creating custom Views, inflating Fragment views into Activity views, creating Dialogs, or simply inflating a layout file View into an Activity.
There are a lot of misconceptions about how the inflation process works. I think this comes from poor of the documentation for the inflate() method. If you want to learn about the inflate() method in detail, I wrote a blog post about it here:
https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/
my customize list hope it illustrate concept
public class second extends ListActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
// TextView textview=(TextView)findViewById(R.id.textView1);
// textview.setText(getIntent().getExtras().getString("value"));
setListAdapter(new MyAdapter(this,R.layout.list_item,R.id.textView1, getResources().getStringArray(R.array.counteries)));
}
private class MyAdapter extends ArrayAdapter<String>{
public MyAdapter(Context context, int resource, int textViewResourceId,
String[] objects) {
super(context, resource, textViewResourceId, objects);
// TODO Auto-generated constructor stub
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater=(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row=inflater.inflate(R.layout.list_item,parent,false);
String[]items=getResources().getStringArray(R.array.counteries);
ImageView iv=(ImageView) row.findViewById(R.id.imageView1);
TextView tv=(TextView) row.findViewById(R.id.textView1);
tv.setText(items[position]);
if(items[position].equals("unitedstates")){
iv.setImageResource(R.drawable.usa);
}else if(items[position].equals("Russia")){
iv.setImageResource(R.drawable.russia);
}else if(items[position].equals("Japan")){
iv.setImageResource(R.drawable.japan);
}
// TODO Auto-generated method stub
return row;
}
}
}
LayoutInflater is a fundamental component in Android. You must use it all the time to turn xml files into view hierarchies.
Inflater actually some sort of convert to data, views, instances, to visible UI representation.. ..thus it make use of data feed into from maybe adapters, etc. programmatically. then integrating it with an xml you defined, that tells it how the data should be represented in UI

Categories

Resources