Trying to dynamically add a TextView to a ScrollView crashes when using an XML layout
This is a very simple example wh开发者_高级运维ere I have a single ScrollView defined in R.layout.main. Then I try to dynamically add a TextView to it.
Unfortunately this crashes.
ScrollView scroll = (ScrollView) this.findViewById(R.id.scrollView1);
TextView tv1 = new TextView(this);
tv1.setText("This is tv1");
scroll.addView(tv1);
setContentView(R.layout.main);
Now I can do something like this:
ScrollView scroll = new ScrollView(this);
TextView tv1 = new TextView(this);
tv1.setText("This is tv1");
scroll.addView(tv1);
setContentView(scroll);
But I'd really like to be able to define some base UI elements in XML, then dynamically add others.
What's the best way to do that?
That is because you are trying to access a view which hasn't been parsed by Android yet.
When you define a layout using XML, then you have to call setContentView
first, passing it the layout file reference so that Android can parse the file. Only then you can access the elements using findViewById
.
That basically means that you should call setContentView
before trying to access any element of your layout.
You must call setContentView before you doing anything else with any views.
This should work.
setContentView(R.layout.main);
ScrollView scroll = (ScrollView) this.findViewById(R.id.scrollView1);
TextView tv1 = new TextView(this);
tv1.setText("This is tv1");
scroll.addView(tv1);
Another way to do this,
You can create a new LinearLayout
inside the ScrollView
, and set the id as say, layoutinside
now
setContentView(R.layout.main);
LinearLayout ll = (LinearLayout) findViewById(R.id.layoutinside);
TextView tv1 = new TextView(this);
tv1.setText("This is tv1");
ll.addView(tv1);
This is working fine for me
findViewById
should only be called after you have called setContentView(R.layout.main);
. Currently scroll
will be null
so I would expect it to throw a NullPointerException
at scroll.addView(tv1);
i Got your problem . You need to set the contentView as like this before
setContentView(R.layout.main);
ScrollView scroll = (ScrollView) this.findViewById(R.id.scrollView1);
TextView tv1 = new TextView(this);
tv1.setText("This is tv1");
scroll.addView(tv1);
While needing to have setContentView()
at the beginning was part of the problem, it turns out that it wasn't the source of the exception.
The actual exception being thrown was IllegalStateException "Scrollview can host only one direct child"
(which Javanator touched on in the comments)
When I looked at the XML for the ScrollView, it looked like this. Eclipse automatically adds a LinearLayout when a ScrollView is added to the layout:
<ScrollView android:id="@+id/scrollView1" android:layout_width="match_parent" android:layout_height="wrap_content">
<LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1" android:layout_height="match_parent"></LinearLayout>
</ScrollView>
So, there are two ways to fix the exception:
1) Remove the LinearLayout from inside the ScrollView. Then, after moving my call to setContentView
to the top, the code in my question works.
2) Instead of adding the TextView to the ScrollView, I can add the TextView to the LinearLayout instead like this:
setContentView(R.layout.main);
LinearLayout ll = (LinearLayout) this.findViewById(R.id.linearLayout1);
TextView tv1 = new TextView(this);
tv1.setText("This is tv1");
ll.addView(tv1);
精彩评论