Array of image button and textview in android - android

I am trying to create an array in which each item will have an image button and below that image button will be a text view in center . Can anybody tell me how to do this. I tried the below code but not getting it worked
but=new ImageButton(this);
but.setFocusableInTouchMode(true);
but.setId(1);
imbrelp= new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
rel.addView(but,imbrelp);
tv= new TextView(this);
tvrelp= new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
tvrelp.addRule(RelativeLayout.BELOW, but.getId());
tvrelp.addRule(RelativeLayout.CENTER_HORIZONTAL, but.getId());
rel.addView(tv, tvrelp);
setContentView(rel);

I would avoid trying to create a RelativeLayout in code. It's going to be too messy for what you want to do. Instead, create an xml layout file for your individual item, and then inflate it for each item in your array.
Container layout in res/layout/main.xml:
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
Item layout in res/layout/item.xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageButton
android:id="#+id/image_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/my_image" />
<TextView
android:id="#+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/image_button"
android:layout_centerHorizontal="true"
android:text="#string/my_text" />
</RelativeLayout>
Code in your activity:
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.main);
ViewGroup container = (ViewGroup) findViewById(R.layout.container);
LayoutInflater inflater = LayoutInflater.from(this);
Item[] items = getMyArrayOfItems();
for (Item i : items) {
View itemView = inflater.inflate(R.layout.item, container, false);
ImageButton button = (ImageButton) itemView.findViewById(R.id.image_button);
TextView textView = (TextView) itemView.findViewById(R.id.text_view);
// TODO set the text and images
container.addView(itemView);
}
}

Related

Add multiple custom views to layout programmatically

If I for example have empty layout like this:
layout1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
And some other Layout like this:
layout2.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<TextView
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView 1" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
android:layout_weight="1"/>
</LinearLayout>
I would like to add layout2.xml to layout1.xml programmatically. I would need to have multiple different version layout2.xml which I would add when I want. Each one would have different text on TextView and Buttons.
In case of regular Android View I would usually do it similarly like this with addView:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv1 = new TextView(this);
tv1.setText("HELLO");
my_linear_layout.addView(tv1);
Button btn2 = new Button(this);
bt2.setText("WORLD");
my_linear_layout.addView(btn2);
}
How can I do it if I don't have something simple like TextView or Button, and if I have my own XML defined View?
Would it be possible to somehow put all the views inside adapter like for a ListView and then get it when needed and just call addView on those Views?
You can inflate the layout2.xml file, edit the texts, and add it to the first layout:
public class MyActivity extends Activity {
private ViewGroup mLinearLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
mLinearLayout = (ViewGroup) findViewById(R.id.linear_layout);
addLayout("This is text 1", "This is first button", "This is second Button");
}
private void addLayout(String textViewText, String buttonText1, String buttonText2) {
View layout2 = LayoutInflater.from(this).inflate(R.layout.layout2, mLinearLayout, false);
TextView textView = (TextView) layout2.findViewById(R.id.button1);
Button button1 = (Button) layout2.findViewById(R.id.button2);
Button button2 = (Button) layout2.findViewById(R.id.button3);
textView1.setText(textViewText);
button1.setText(buttonText1);
button2.setText(buttonText2);
mLinearLayout.addView(layout2);
}
}
You may want to change android:layout_height of the layout2.xml root view to wrap_content.
If you are using ViewBinding, here is how it would look like for the addLayout function :
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), mLinearLayout, false);
binding.getTextView1().setText(textViewText);
binding.getButton1().setText(buttonText1);
binding.getButton2().setText(buttonText2);
mLinearLayout.addView(binding.getRoot());
layout1.xml contains ScrollView as parent layout and main LinearLayout as child if no row item more screen size ScrollView handle overflow item with scroll:
layout1.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/my_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
Use LayoutInflater to add row item to parent LinearLayout:
private LinearLayout my_linear_layout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout1);
my_linear_layout = (LinearLayout) findViewById(R.id.my_linear_layout);
for (int i = 1; i <= 5; i++) {
View view = LayoutInflater.from(this).inflate(R.layout.layout2, null);
TextView button1 = (TextView) view.findViewById(R.id.button1);
Button button2 = (Button) view.findViewById(R.id.button2);
TextView button3 = (TextView) view.findViewById(R.id.button3);
button1.setText("HELLO " + i);
button2.setText("HELLO " + i);
button3.setText("HELLO " + i);
my_linear_layout.addView(view);
}
}
Try this method
Add id to LinearLayout 'layout1.xml':
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/firstlayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
</LinearLayout>
In onCreate:
LinearLayout firstlayout = (LinearLayout) findViewById(R.id.firstlayout);
LinearLayout secondlayoout = (LinearLayout) this.getLayoutInflater().inflate(R.layout.layout2, null); // inflating view from xml
TextView btn1 = (TextView) secondlayoout.findViewById(R.id.button1);
btn1.setText("TEST");
firstlayout.addView(secondlayoout);
You can achieve this for view binding by using below.
val layoutBindingView: LayoutBinding =
LayoutBinding.inflate(layoutInflater)
layoutBindingView.textView.text = "TextOne"
val layoutBindingView: LayoutBinding =
LayoutBinding.inflate(layoutInflater)
layoutBindingView.textView.text = "Text Two"

Progress bar inside of each list view item is not displayed well

I created a ListView, each list item contains a progress bar. When scrolling this list view all progress bars are displayed and scrolled well, EXCEPT very first item with progress bar, which stays always on top. The visual effect is following here: when scrolling down, all progress bars are scrolled well, but additionally new progress bar is always drawn at the fixed position where the first progress bar has been originally displayed. Does anybody know how to get rid of this?
Layout planner_main.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants">
<include layout="#layout/planner_row"/>
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<include layout="#layout/parent_view"/>
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/no_entries"
android:textSize="38sp"
android:visibility="gone"/>
</RelativeLayout>
Layout planner_row.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_layout"
android:layout_width="wrap_content"
android:layout_height="50dp">
<TextView
android:id="#+id/category_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:textColor="#color/black"
android:textSize="18sp">
</TextView>
<TextView
android:id="#+id/category_spent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/category_name"
android:layout_centerVertical="true"
android:textColor="#color/black"
android:textSize="18sp" >
</TextView>
<ProgressBar
android:id="#+id/category_bar"
android:layout_width="200dp"
android:layout_height="15dp"
android:layout_below="#id/category_name"
style="#android:style/Widget.ProgressBar.Horizontal"
android:max="100" />
<TextView
android:id="#+id/category_limit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/category_bar"
android:layout_below="#id/category_spent"
android:layout_centerVertical="true"
android:textColor="#color/black"
android:textSize="18sp" >
</TextView>
</RelativeLayout>
Adapter's main part:
public class PlannerListAdapter extends SimpleCursorAdapter {
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final PlannerViewHolder holder;
// create a new row view
if (convertView == null) {
convertView = inflater.inflate(R.layout.planner_row, parent, false);
// find children views
TextView tvName = (TextView) convertView.findViewById(R.id.category_name);
TextView tvLimit = (TextView) convertView.findViewById(R.id.category_limit);
TextView tvSpent = (TextView) convertView.findViewById(R.id.category_spent);
ProgressBar bar = (ProgressBar) convertView.findViewById(R.id.category_bar);
holder = new PlannerViewHolder(tvName, tvLimit, tvSpent, bar);
// tag the row with it's children views
convertView.setTag(holder);
} else { // reuse existing row view
holder = (PlannerViewHolder)convertView.getTag();
}
if (dataCursor.moveToPosition(position)) {
holder.tvCategory.setText(dataCursor.getString(1));
holder.bar.setProgress(50);
}
return convertView;
}
...
public static class PlannerViewHolder {
private ProgressBar bar;
private TextView tvCategory, tvLimit, tvSpent;
public PlannerViewHolder(TextView tv1, TextView tv2, TextView tv3, ProgressBar b) {
tvCategory = tv1;
tvLimit = tv2;
tvSpent = tv3;
bar = b;
}
}
}
Activity's code which uses adapter:
#Override
public void onCreate(Bundle savedInstanceState) {
setLayout(R.layout.planner_main);
super.onCreate(savedInstanceState);
...
listView = (ListView)findViewById(android.R.id.list);
Cursor c = db.getCategoriesData();
adapter = new PlannerListAdapter(context, c, new String[] { Data.Categories.NAME, Data.Categories.LIMIT }, new int[] { R.id.category_name, R.id.category_limit });
listView.setAdapter(adapter);

Add the same view multiple times to a ViewFlipper with different information in the view

I have a viewflipper that I want to populate with the same layout multiple times, but in each layout I need to display different text and a different background image, based on some array. So far, it just replaces the first view every time with the different text/ backgrounds. For now, I've predefined the arrays. Any help is greatly appreciated.
The code for the viewflipper:
private int numcards = 3;
private String creditnum[] = {"***********2451", "***********2452", "***********2453"};
private int carddraw[] = {R.drawable.fullcredit_blue, R.drawable.fullcredit_green, R.drawable.fullcredit_silver};
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.show_cards);
viewFlipper = (ViewFlipper) findViewById(R.id.viewflipper);
gestureDetector = new GestureDetector(this);
for (int i = 0; i < numcards; i++)
{
viewFlipper.addView(View.inflate(this, R.layout.card_scroll_item, null), new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
Typeface tf = Typeface.createFromAsset(getAssets(),"fonts/credit.otf");
Button creditbtn = (Button) findViewById(R.id.credit_button);
creditbtn.setBackgroundResource(carddraw[i]);
TextView txtname = (TextView) findViewById(R.id.credit_type);
txtname.setText("Visa");
TextView txtnumber = (TextView) findViewById(R.id.credit_number);
txtnumber.setText(creditnum[i]);
txtnumber.setTypeface(tf);
}
}
And the xml for the view that i'm inflating:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/credit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="104dp" android:layout_marginBottom="220dp" android:layout_alignParentBottom="true"/>
<TextView
android:id="#+id/credit_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/credit_button"
android:layout_alignTop="#+id/credit_button"
android:layout_marginRight="22dp"
android:layout_marginTop="21dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" android:typeface="normal"/>
<TextView
android:id="#+id/credit_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/credit_button"
android:layout_alignRight="#+id/credit_type"
android:layout_centerVertical="true"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" android:layout_marginLeft="15dp" android:layout_marginBottom="30dp"/>
The problem is that you aren't holding on to the view you're adding, so findViewById is being called on the Activity's content view, which will always return the first view with that ID. Try this:
View view = View.inflate(this, R.layout.card_scroll_item, null);
viewFlipper.addView(view);
Button creditbtn = (Button) view.findViewById(R.id.credit_button);
creditbtn.setBackgroundResource(carddraw[i]);
TextView txtname = (TextView) view.findViewById(R.id.credit_type);
txtname.setText("Visa");
TextView txtnumber = (TextView) view.findViewById(R.id.credit_number);
txtnumber.setText(creditnum[i]);
txtnumber.setTypeface(tf);
Those layout params are redundant, as you have them defined in your XML.

Inflating TextView and LinearLayout programmatically

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

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