So I have an XML layout1 which is just a LinearLayout with three text views. I also have another XML layout2 with ScrollView and a LinearLayout inside it. I'm using this for loop to create several of the layout2 inside the LinearLayout of the ScrollView. It's working fine but I want to be able to set the text of each of the TextViews within the for loop. I'm not sure how to access these TextViews as I can only set one id within the XML file, will that not cause problems if I tried to access their id inside the for loop?
private void setUpResults() {
for (int i = 1; i < totalQuestions; i++) {
parent.addView(LayoutInflater.from(getBaseContext()).inflate(
R.layout.result_block, null));
}
}
Here is the result_block xml file (layout1) :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/layoutSelectedAnswer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/border"
android:orientation="horizontal"
android:paddingBottom="#dimen/option_padding_bottom"
android:paddingTop="#dimen/option_padding_top" >
<TextView
android:id="#+id/tvOptionALabel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option_a"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
<TextView
android:id="#+id/tvSelectedAnswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
</LinearLayout>
<LinearLayout
android:id="#+id/layoutCorrectAnswer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/border"
android:orientation="horizontal"
android:paddingBottom="#dimen/option_padding_bottom"
android:paddingTop="#dimen/option_padding_top" >
<TextView
android:id="#+id/tvOptionBLabel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option_b"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
<TextView
android:id="#+id/tvCorrectAnswer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="#string/option"
android:textColor="#color/white"
android:textSize="#dimen/option_text_size" />
</LinearLayout>
</LinearLayout>
Let's say I wanted to set the TextView with the id as tvCorrectAnswer to a different String value in each loop, how should I access it?
Sure, you can do it like this:
private void setUpResults () {
LayoutInflater i = LayoutInflater.from(getBaseContext());
for (int i = 1 /* should be zero? */; i < totalQuestions; i++) {
View view = i.inflate(R.layout.result_block, parent, false);
TextView correctAnswer = (TextView) view.findViewById(R.id.tvSelectedAnswer);
correctAnswer.setText("My Answer Text");
parent.addView(view);
}
}
The key is, inflate using the parent as the container, but don't attach it (the false parameter). Then you'll get a reference to the inflated view, which you can then directly reference to do your findViewById() calls (which will limit the search to that particular ViewGroup). Then add it to the parent and continue to the next item.
Once you have added all your views in your ViewGroup you can use ViewGroup.getChildAt(int) to get a one of the views you have inserted. Once you get one of the views you can access any of its inner views. Something like this.
for(int i = 0; i < parentView.getChildCount();++i) {
View v = parentView.getChildAt(i);
Textview tv = (TextView) v.findViewById(R.id.tvOptionALabel2);
//And so on...
}
Related
This is my Layout , I have nested Linear layout inside another linear layout which is nested inside an Scroll view. Now i want to add an Linear layout dynamically (I may even add upto 10) inside android:id="#+id/formLayout" i.e beneth android:id="#+id/secondLayout"
Original Layout :
<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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="420dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<!-- LinearLayout Inside ScrollView -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/formLayout"
android:orientation="vertical">
<!-- Serial Layout -->
<LinearLayout
android:id="#+id/secondLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="horizontal"
android:weightSum="2">
<android.support.design.widget.TextInputLayout
android:id="#+id/serialno_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:paddingEnd="10dp"
android:paddingLeft="10dp"
android:paddingStart="10dp">
<AutoCompleteTextView
android:id="#+id/fieldSerial"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:hint="#string/txt_sno_text"
android:singleLine="true"
android:textIsSelectable="false"
android:textSize="15sp" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>
Dynamic Layout needs to be added :
<LinearLayout
android:id="#+id/sixthLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="horizontal"
android:weightSum="2">
<android.support.design.widget.TextInputLayout
android:id="#+id/attr2_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:paddingEnd="10dp"
android:paddingLeft="10dp"
android:paddingStart="10dp">
<EditText
android:id="#+id/fieldAttr2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:hint="Attribute 2"
android:textSize="15sp" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
Can some one help me with this ?
Use the LayoutInflater to create a view based on your layout template, and then inject it into the view where you need it.
public static NavigableMap<Integer, String> navigableMap = new TreeMap<Integer, String>();
public static int count = 0; // to count no of views added
public static void add_new(final Activity activity)
{
final LinearLayout linearLayoutForm = (LinearLayout) activity.findViewById(R.id.formLayout);
final LinearLayout newView = (LinearLayout) activity.getLayoutInflater().inflate(R.layout.view_to_add, null);
newView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
final EditText edit_new = (EditText) newView.findViewById(R.id.fieldAttr2);
edit_new.setId(id++); // It will assign a different id to edittext each time while adding new view.
Log.i("actv id",edit_new.getId()+""); // You can check the id assigned to it here.
// use a Hashmap or navigable map (helpful if want to navigate through map)
// to store the values inserted in edittext along with its ids.
edit_new.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
navigableMap.put(edit_new.getId(), edit_new.getText().toString());
Log.i("navigablemap", navigableMap.toString());
}
});
// you can get values directly through map by referencing its ids.
// OR
EditText actv_uc = (EditText) linearLayoutForm.findViewById(navigableMap.lastKey());
// Provide the id of edittext you want to access
actv_uc.getText(); // to get value of EditText
actv_uc.setText("");
linearLayoutForm.addView(newView);
count++;
}
Call this function whenever you want to add new view. If you are calling this in Activity, then there is no need to pass Activity object as parameter. but if you are using this in fragment, then need to pass a Parent Activity object to function.
Very easy and helpful tutorial for adding views dynamically :-
http://android-er.blogspot.in/2013/05/add-and-remove-view-dynamically.html
Hope this will help you. Thank you
Try this:
LinearLayout myRoot = (LinearLayout) findViewById(R.id.formLayout);
LayoutInflater inf = LayoutInflater.from(yourContext);
View child;
for (int i = 0; i < 10; i++) {
child = inf.inflate(R.layout.your_added_layout, null);
child.setId("textView"+i);
// can set layoutparam if needed.
myRoot.addView(child);
}
I have this XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/button_bar"
style="?android:buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#color/md_green_400" />
<Button
android:id="#+id/action_button"
style="?android:attr/borderlessButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#color/md_green_400" />
</LinearLayout>
It´s just a buttonBar with two borderless buttons. It works. However, I don't want that, I need to inflate these buttons from a JSONArray. So I did this:
for (int b = 0; b < buttons.length(); b++) {
final JSONObject button = buttons.getJSONObject(b);
LinearLayout buttonBar = (LinearLayout) child.findViewById(R.id.button_bar);
View buttonChild = getLayoutInflater().inflate(R.layout.flat_button, null);
Button action = (Button) buttonChild.findViewById(R.id.action_button);
action.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {}
});
action.setText(button.getString("descricao"));
action.setTextColor(Color.parseColor(button.getString("text_color")));
buttonBar.addView(buttonChild);
}
It works too, but the buttons get a left alignment. I want they justified.
Why it works when I let them fixed but not when I inflate them?
OBS: The "button_bar" is A XML just with a LinearLayout and the "ActionButton" is just a XML with a Button.
This is the root of your problem:
View buttonChild = getLayoutInflater().inflate(R.layout.flat_button, null);
If you don't provide the parent view to the inflate() method, any LayoutParams attributes (e.g. layout_gravity) will be discarded since the parent is the one to interpret those attributes.
You can fix this by changing it to:
View buttonChild = getLayoutInflater().inflate(
R.layout.flat_button, buttonBar, false);
Which will give it the parent you're attaching it to, but not attach it to the hierarchy yet (you do that below with addView()).
LinearLayout lay1 = (LinearLayout) findViewById(R.id.lay1);
for(int i=0;i<list1.size();i++) {
View child = lay1.getChildAt(i);
LinearLayout lay3 = (LinearLayout) child.findViewById(R.id.lay3);
for (j = 0; j <list2.size(); j++) {
View child1 = lay3.getChildAt(j);
// View hiddenInfo11 = getActivity().getLayoutInflater().inflate(R.layout.add_inner_item, lay3 , false);
final TextView name = (TextView) child1.findViewById(R.id.name);
name.setText("new");
}
}
XML Layout:
<LinearLayout
android:id="#+id/lay1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:id="#+id/lay2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:background="#color/white"
android:orientation="horizontal">
</LinearLayout>
add_item.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="match_parent"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/lay3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
add_inner_item.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="match_parent"
android:orientation="horizontal"
>
<TextView android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" />
</LinearLayout>
Added View Dynamically using the following method.
for(int i=0;i<list.size();i++) {
View hiddenInfo = getActivity().getLayoutInflater().inflate(R.layout.add_item, lay, false);
LinearLayout lay3 = (LinearLayout) hiddenInfo.findViewById(R.id.lay3);
lay1.addView(hiddenInfo);
for (j = 0; j < list2.size(); j++) {
View hiddenInfo1 = getActivity().getLayoutInflater().inflate(R.layout.add_inner_item, lay3, false);
final TextView name = (TextView) hiddenInfo1.findViewById(R.id.name);
name.setText(list2.get(j).get("Name"));
lay3.addView(hiddenInfo1);
}
I have one Layout with creating dynamically and I want to update the child textview from outside of the button click view.I have tried this code.But nothing is changed.Can anyone give suggestion to this sample.
You are looking for "lay2" inside the "lay1" container. According to your XML layout, they are not nested, so you won't be able to find it this way. Change it to this:
LinearLayout lay2 = (LinearLayout) findViewById(R.id.lay2);
You should get the actual lay2 container. I'm not sure whether the text views are there though since I have seen your code for the views' creation.
EDIT:
I've not specified a parent - you should use the Activity for this. Something like:
LinearLayout lay2 = (LinearLayout) MyActivity.this.findViewById(R.id.lay2);
I Have activity that get some data from the internet, and shows it to the screen.
I'm using scroll view cause it's long text, I also want different text style for a different data,so I use few textViews with a different style and to show it on the Activity screen,
my problem is that scroll view can handle only one view, so how can I use scrolling to show different style of Text view, I tried to add LinearLayout to the scrollView and add all the textViews dynamically in code to this LinearLayout ,but I'm getting exception - scroll view can host only one direct child.
The code below:
/** this is the function, which called from the onClick method.
wanted data object contains 2 strings title message and the message itself.
When debug the code i can see that there's two String values in each loop.
but i cant add the linearLayout to my scrollView - exception ScrollView can host only one direct child */
private void showResult(ArrayList<WantedData> result) {
// TODO Auto-generated method stub
TextView title;
TextView data;
scrollLayout = (LinearLayout) findViewById(R.id.LlScrollView);
for (WantedData curr : result) {
if (curr.getTitle() == null) {
break;
}
title = new TextView(this);
title.setText(curr.getTitle());
scrollLayout.addView(title, LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
data = new TextView(this);
data.setText(curr.getData());
scrollLayout.addView(data, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
}
scroll.addView(scrollLayout, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
//at the onCreate method - scroll = (ScrollView) findViewById(R.id.SvShowTextFromServer);
}
the xml file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<include
android:id="#+id/layout_reffernce"
layout="#layout/explore" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enter City" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="#+id/EtCity"
android:layout_width="210dp"
android:layout_height="wrap_content"
android:layout_weight="0.14"
android:orientation="vertical" >
<requestFocus />
</EditText>
<Button
android:id="#+id/bSearchCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search" />
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enter State" />
<EditText
android:id="#+id/EtState"
android:layout_width="253dp"
android:layout_height="wrap_content"
android:orientation="vertical" />
</LinearLayout>
<ScrollView
android:id="#+id/SvShowTextFromServer"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/LlScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/backround"
android:orientation="vertical" >
</LinearLayout>
</ScrollView>
</LinearLayout>
The problem is double creating of container in ScrollView. You should not create it in activity, but take already defined from xml:
LinearLayout scrollContainer = (LinearLayout)findViewById(R.id.LlScrollView);
for (...) {
//create here some text
scrollLayout.addView(text);
}
If you have defined a LinearLayout in XML you don't have to create a new LinearLayout in your code but you have to retrieve the existing one in this way
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.LlScrollView);
Otherwise you have to remove the LinearLayout in your XML and add all by code.
I am using Layout inflator in my application to suit my requirements. I have text view, edittext and button in the layout. Here is my xml file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearlayoutid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/textviewid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<EditText
android:id="#+id/edittextid"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/linearlayoutid"
android:layout_centerHorizontal="true"
android:text="button" />
I want to generate 'n' number of text views and pass the values from database.
I used layout inflator here and below is my code
setContentView(R.layout.activity_main);
LinearLayout lv = (LinearLayout) findViewById(R.id.linearlayoutid);
View v = null;
for (int i = 0; i < 41; i++) {
v = LayoutInflater.from(this).inflate(R.layout.activity_main, null);
lv.addView(v);
}
// EditText editText = (EditText) v.findViewById(R.id.edittextid);
final TextView[] myTextViews = new TextView[41];
for (int i = 0; i < 41; i++) {
TextView tv = (TextView) v.findViewById(R.id.textviewid);
d = mydb.getValues();
myTextViews[i] = tv;
tv.setText(d.get(i));
Log.d(tag,"run"+d.get(i));
}
Its is generating 'n' number of text views dynamically but the problem is I am not able to display text using 'setText' . Its blank completely . Can anyone please tell me where I am making mistake? I want to pass the dynamic value and not the hard coded one. Any help would be great !! Thanks
If you want show list of some data, will be better to use List view.
Or you can use RecyclerView.
You can find more information about this layouts and how use it on Internet.