I have an UI like this:
<RelativeLayout>
<TextView />
<RelativeLayout>
<TextView />
<TextView />
<LinearLayout>
<TextView />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
I want to access all TextViews programmatically and change some attributes but
I don't want use id and findViewById, because I have a multi layout which I want to perform the same changes in them, i.e.: change the fonts of TextViews.
How can I access all the TextViews whether direct or hierarchy of a view, like RelativeLayout in a loop or in a list?
LinearLayout mLinearLayout = (LinearLayout) findViewById(R.id.my_linear_layout);
for(i = 0; i <= mLinearLayout.getChildCount(); i++){
View view = mLinearLayout.getChildAt(i);
if (view instanceof TextView){
TextView textView = (TextView) view;
// TODO do your stuff
}
}
if you have ViewGroups in your RelativeLayout then you need to write a recursive method.
Related
main.xml:
<FrameLayout id="parent">
<ImageView layout_width="match_parent" layout_height="match_parent"/>
</FrameLayout>
ActivityMain.java
onCreate() {
super.onCreate();
setContentView(R.layout.nain);
ViewGroup parent = (ViewGroup) findViewById(R.id.parent);
TextView textView = new TextView(this);
textView.setText("Hello, world");
parent.addView(textView);
// parent.addView(textView, 0);
// parent.addView(textView, 1);
// parent.bringChildToFont(textView);
}
I inflated the code above as the content, and then, how can I add another view to the FrameLayout and it's on the top of the ImageView?
I had tried some several hours, but still don't know how to programmatically add another view to the top of the FrameLayout.
I found that it's easy to achieve the goal by add two children to the XML file. And at the end, I use a ViewStub and complete my work.
But I'm so curious about how to do this without a ViewStub.
my solution:
main.xml:
<FrameLayout id="parent">
<ImageView layout_width="match_parent" layout_height="match_parent"/>
<ViewStub id="stub">
</FrameLayout>
widget_text_view.xml:
<TextView />
ActivityMain.java
onCreate() {
super.onCreate();
setContentView(R.layout.nain);
ViewStub stub = (ViewStub) findViewById(R.id.stub);
stub.setLayoutResource(R.layout.widget_text_view);
TextView textView = (TextView) stub.inflate();
}
yes you can add item to the top of another view. android:layout_gravity attribute. visite This. Or This
I have a layout called view.xml which contains a View called view_related. Basically, in my dictionary app, if there are related words to an entry, I will replace view_related with a LinearLayout that contains a header "Related entries" and a bunch of TextViews representing every related word.
I keep getting a NullPointerException everytime I'm adding a TextView to the LinearLayout in my Activity's onCreate() method, and I don't understand why though my code looks pretty straightforward.
view.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView android:id="#+id/view_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12pt"
android:textColor="#fff"
android:textStyle="bold"
android:background="#990011"
android:padding="10dp"
android:text="lalala word"
/>
<ScrollView android:id="#+id/view_description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/view_header">
<LinearLayout android:id="#+id/view_description_content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="#string/demo_definition"
/>
<!-- THIS WILL BE REPLACED -->
<View android:id="#+id/view_related"
android:layout_width="match_parent"
android:layout_height="wrap_content"></View>
</LinearLayout>
</ScrollView>
</RelativeLayout>
view_related.xml, the LinearLayout that will replace the View element in view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_related_entries"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:id="#+id/view_related_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:textColor="#fff"
android:textStyle="bold"
android:textSize="7pt"
android:background="#000"
android:text="Related entries"
/>
<LinearLayout android:id="#+id/view_related_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</LinearLayout>
</LinearLayout>
And finally, the onCreate method, which for now assumes the related entries are "Hello" and "Goodbye:"
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view);
LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list);
TextView tv = new TextView(this);
tv.setText("Hello");
ll.addView(tv); // NULL POINTER EXCEPTION
tv = new TextView(this);
tv.setText("Goodbye");
ll.addView(tv);
LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = findViewById(R.id.view_related);
ViewGroup parent = (ViewGroup) view.getParent();
int index = parent.indexOfChild(view);
parent.removeView(view);
View llview = li.inflate(R.id.view_related_entries, parent, false);
parent.addView(llview, index);
}
setContentView(R.layout.view);
LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list);
The function findViewById only finds views that are actually set. Your current setContentView does not set an xml that has the id you are looking for in it, so the first line I quoted will not result in anything.
You should either load the correct XML, or inflate the view you are looking for with an inflater
the line (LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list);) will search for view_related_list in view.xml, as in the line before that is the view you are using..
You need to inflate view_related.xml first and then get the view from it..
You're doing a lot of wrong things in your code. First you search for a LinearLayout that isn't in the current layout and also isn't in any inflated layout at that moment. Second, you try to inflate an id reference instead of a layout reference. Last, you should use another approach for what you're trying to do. Your code should be(from what I understood):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view);
LayoutInflater li = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View view = findViewById(R.id.view_related);
ViewGroup parent = (ViewGroup) view.getParent();
int index = parent.indexOfChild(view);
parent.removeView(view);
View llview = li.inflate(R.layout.view_related, parent, false); // is view_related the name of the extra layout file?
parent.addView(llview, index);
LinearLayout ll = (LinearLayout) findViewById(R.id.view_related_list); // or search for it in llview, llview.findViewById(R.id.view_related_list);
TextView tv = new TextView(this);
tv.setText("Hello");
ll.addView(tv); // NULL POINTER EXCEPTION
tv = new TextView(this);
tv.setText("Goodbye");
ll.addView(tv);
}
This is a situation when you should use a ViewStub to add the new layout file. Although, I don't understand why don't you add the new layout file directly in the view.xml if you're going to add the layout's content in the onCreate method.
i think you need to use setContentView(R.layout.view_related); instead of setContentView(R.layout.view);
or another simple thing you can do is take the linear layout in the same layout "view" and make it invisible when not required and visible when required
You may forgetting to declare your Activity in manifest.xml
I created mainLayout with two buttons
add: to add other layout
remove : to remove other layout.
<Button
android:id="#+id/btnAdd"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Add View"
android:onClick="addView" />
<Button
android:id="#+id/btnRemove"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Remove View"
android:onClick="removeView" />
now i wrote following code to add the view
when I click on addView button
LayoutInflater inflater= (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
view=inflater.inflate(R.layout.other_layout,null);
mainLayout.addView(view);
the view is added below the main layout.
But I want the view to add in middle of the screen not at the bottom of screen.
How can I do that?
Modify this line and put ur parent view.
view=inflater.inflate(R.layout.other_layout,PARENT_VIEW_OBJECT);
It should work
get the parentLayout like this
parentLayout=(YourParentLayout)view.findViewById(R.id.parentLayout);
then
parentLayout.addView(yourview);
You can check below code, its working fine for me
private View view = null ;
Button addbutton = null;
ViewGroup parent = null;
LayoutInflater inflater = null;
inflater= (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
addbutton = (Button)findViewById(R.id.btnAdd);
parent = (ViewGroup) findViewById(R.id.mainxml);
addbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
view = inflater.inflate(R.layout.other, null);
parent.addView(view);
}
});
I would put an empty LinearLayout placeholder at the top of your main layout where you want your view to be and add the view to that instead of the main layout.
You can adjust the placeholder first and modify it's location and looks.
<LinearLayout
android:id="#+id/placeholder"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
..../>
<Button
..../>
I would look into using a ViewStub it holds a place until .inflate() is called. That way the layout isn't taking resources until it's needed.
I have a LinearLayout view element inside a ScrollView (main.xml):
<ScrollView ...>
<LinearLayout
android:id="#+id/root"
android:orientation="vertical"
>
<TextView .../>
<EditText .../>
...
</LinearLayout>
</ScrollView>
As you see above, there are also some other elements inside the root LinearLayout .
Now, I would like to programmatically(dynamically) add more views to the LinearLayout (id="root").
I tried the following way to add more child views to this root:
Firstly, I created my child view which is in a separate layout file:
child.xml
<LinearLayout
android:id="#+id/child"
>
<TextView id="mytxt"... />
<ListView id="mylist".../>
</LinearLayout>
Secondly, I inflate & get two instances of above child view, initialize elements inside:
/***inflate 1st child, initialize its elements***/
LinearLayout child_1 = (LinearLayout) inflater.inflate(R.layout.child, null);
TextView txt1 = (TextView)child_1.findViewById(R.id.mytxt);
txt1.setText("CAR");
ListView list1 = (ListView)child_1.findViewById(R.id.mylist);
// Code to initialize 'list1' (I did not paste code here)
/*** inflate 2nd child, initialize its elements ****/
LinearLayout child_2 = (LinearLayout) inflater.inflate(R.layout.child, null);
TextView txt2 = (TextView)child_2.findViewById(R.id.mytxt);
txt2.setText("PLANE");
ListView list2 = (ListView)child_2.findViewById(R.id.mylist);
// Code to initialize 'list2' (I did not paste code here)
Finally, I add them to root LinearLayout:
//get root
View contentView = inflater.inflate(R.layout.main, null);
LinearLayout root = (LinearLayout) contentView.findViewById(R.id.root);
//add child views
root.add(child_1);
root.add(child_2);
When I run my app on device, I can only see child_2 layout without seeing child_1 under 'root', why??
in LinearLayout default orientation is horizontal set it vertical.......
from
http://developer.android.com/reference/android/widget/LinearLayout.html
see
The default orientation is horizontal.
and you set text in txt1.setText("PLANE"); set in txt2.setText("PLANE");
both text set in same textview.....
txt1.setText("CAR");
txt1.setText("PLANE");
How do you create your layout? Do you do it through setContentView(int)? Then you should retrieve that instance by doing this in your activity:
findViewById(R.id.root);
I have 2 layout xml files: "highlights.xml" and "highlights_cell.xml".
Here is a simplified version of each. I've removed the width/height/etc and just kept the important attributes...
highlights.xml
<LinearLayout>
<uk.co.jasonfry.android.tools.ui.SwipeView android:id="#+id/swipe_view" />
<uk.co.jasonfry.android.tools.ui.PageControl android:id="#+id/page_control" />
</LinearLayout>
highlights_cell.xml
<LinearLayout android:orientation="vertical">
<LinearLayout android:id="#+id/linear_layout1" android:orientation="horizontal">
<ImageView android:id="#+id/logo" />
<LinearLayout android:id="#+id/linear_layout2" android:orientation="vertical">
<TextView android:id="#+id/title" />
<TextView android:id="#+id/subtitle" />
</LinearLayout>
</LinearLayout>
<ScrollView android:id="#+id/scroll_view">
<TextView android:id="#+id/description" />
</ScrollView>
</LinearLayout>
The idea is that I want to add several "highlights_cell" to "highlights" through a loop.
I've thrown together some test code as follows but, as it's not working, I suspect that I'm not adding the cell layouts correctly, or perhaps I shouldn't be using "inflater"...
/** Declare shared variables */
SwipeView mSwipeView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
//Initialise layout and variables
super.onCreate(savedInstanceState);
setContentView(R.layout.highlights);
//Setup controls
mSwipeView = (SwipeView) findViewById(R.id.swipe_view);
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
//Loop through collection and add views
for(int i=0; i<7;i++)
{
//Create the itemView to use layout xml for each cell
View itemView = inflater.inflate(R.layout.highlights_cell, null);
//Set values within cell
TextView title = (TextView) itemView.findViewById(R.id.title);
title.setText("HELLO WORLD_" + i);
//add the itemView to main view
mSwipeView.addView(itemView);
}
}
Is this the correct way to add layouts dynamically to a parent layout?
Thanks!
It looks good except for a few things.
Because you are adding views to your custom ViewGroup, you will have to be sure that it correctly lays out and displays its children.
Also, when you add a View to a ViewGroup, you specify the LayoutParams that views can have in that ViewGroup.
Some more info about creating a custom ViewGroup
http://about-android.blogspot.com/2010/05/create-dynamic-view-group.html
custom ViewGroup example?