scrollview = (ScrollView)findViewById(R.id.detailedScrollView);
for (Quotation quotation : object.quotes){
TextView quote = new TextView(this);
quote.setText(quotation.getQuote());
quote.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
scrollview.addView(quote);
}
Let's say there are three quotes, then I want to have three textViews. However, the code above crashes my app. Any obvious mistakes? Here's the error I'm getting:
11-06 17:35:53.214: E/AndroidRuntime(1430): java.lang.IllegalStateException: ScrollView can host only one direct child
You can't add views directly inside a scrollview. A scrollview can only contain a single layout object. What you have to do is to add a linearlayout in your scrollview, then add the textview to the linearlayout
Layout container for a view hierarchy that can be scrolled by the user, allowing it to be larger than the physical display. A ScrollView is a FrameLayout, meaning you should place one child in it containing the entire contents to scroll; this child may itself be a layout manager with a complex hierarchy of objects. A child that is often used is a LinearLayout in a vertical orientation, presenting a vertical array of top-level items that the user can scroll through.
The TextView class also takes care of its own scrolling, so does not require a ScrollView, but using the two together is possible to achieve the effect of a text view within a larger container. Please more detail
With best regards,
Psycho
You need to add a "LinearLayout" (or "RelativeLayout") inside ScrollView.
Say you have the layout xml as follows:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linearlayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
</LinearLayout>
</ScrollView>
And now you want to add the 'TextView' programmatically, which is as follows:
LinearLayout linearLayout =(LinearLayout) this.findViewById(R.id.linearlayout1);
for (Quotation quotation : object.quotes){
TextView quote = new TextView(this);
quote.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
quote.setPadding(4, 0, 4, 0); //left,top,right,bottom
quote.setText(quotation.getQuote());
linearLayout.addView(quote);
}
Related
I'm inflating views inside a linearlayout dynamically, however once the linear layout reaches the end of the first row, it cuts off the rest and doesn't start on the second row.
for(int a = 0; a < mSkills.get(i).size(); a++){
View singleSkill = LayoutInflater.from(mContext)
.inflate(R.layout.singleskill, holder.mSkillLayout, false);
TextView skillText = singleSkill.findViewById(R.id.singleskilltext);
skillText.setText(mSkills.get(i).get(a));
holder.mSkillLayout.addView(skillText);
}
For the linear layout I have it set to wrap_content for the height:
<LinearLayout
android:id="#+id/ll_skills"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#+id/tv_description"
android:layout_margin="16dp"/>
I've tried setting it to a defined height e.g 300dp however that doesn't work either.
How can I make the layout start on the second row, once the first is full?
Linear Layout can either fill views horizontally or vertically so the 2nd row you are expecting cant to be done with linear layout only. you can try a horizontal scroll view for that to scroll horizontally. For the exact view-like flow that you described, you can use this 3rd party https://github.com/nex3z/FlowLayout
It can manage the flow of your dynamically inflated view such as if there is no space in the first line then it will put the next view in the second line.
also, you can use material design library chips https://material.io/components/chips/#usage
LinearLayout works exactly how it has to be because you specify it as horizontal. For such behavior, you need RecyclerView With GridLayoutManager or create your own layout;).
Actually it's doing exactly as it should be, LinearLayout is Linear!, and place its subviews in a single horizontal or vertical row.
My advice to you is that create dynamic horizontal LinearLayout as you already doing with TextViews. and put every 3 or 4 textviews (depending on screen size) inside it.
and put all LinearLayouts inside one vertical LinearLayout...
Of course in your case, it's not a good idea, the best thing you can do is to use recycler view. but I consider you have problem with that.
I am trying to achieve a dynamic list of textviews like in the image below :-
Here is my code :-
LayerDrawable dashboardResShape_community= (LayerDrawable) getResources().getDrawable(R.drawable.upcomingtask_tags_shape);
// The background effect is by the layer list drawable from the above code
LinearLayout tags_view2=(LinearLayout)findViewById(R.id.tags_view);
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.setMargins(10, 2, 2, 2);
TextView[] tx = new TextView[15];
for(int i=0; i<15; i++) {
tx[i] = new TextView(getActivity());
tx[i].setPadding(8, 4, 8, 4);
tx[i].setBackground(dashboardResShape_community);
tx[i].setLayoutParams(lp);
tx[i].setText("Tag"+i);
tags_view2.addView(tx[i]);
}
and in my xml there is only a linear layout :-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tags_view"
android:orientation="horizontal" >
</LinearLayout>
This is what i achieve :-
When i am adding 15 textviews, only 8 are shown like below, the rest should come in the next line but they are not.
If i add more textviews, it goes out of screen but i want to add the textview in the second line when the first line is full. What i am doing wrong here?
Its LinearLayout's limitation.
If you want the explained behavior than
You have to make your own Layout/View refer this link or
Impliment LinearLayout Horizontal orientation with wrapping children like this
you cannot get more text views on next line after linear layout is filled( screen width ), you already the made linear layout orientation as horizontal. Better solution add one more linear layout or use relative (do some child count coding and set parameters). The best solution i prefer for u is table layout. Easier to code code and handle
What you can do is add as many textviews as will fit on the screen to your linearlayout, but then when a textview would go off the screen, you could add another linearlayout below the one that you already had, and then add on to that. You could keep doing that and you would end up with no textviews goind off the screen. You could also try using a gridview.
Here is what this layout looks like:
http://developer.android.com/guide/topics/ui/layout/gridview.html
And here is the documentation:
http://developer.android.com/reference/android/widget/GridView.html
I am adding views dynamically in a linear layout as follows:
xml:
<LinearLayout
android:id="#+id/part1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:gravity="right"
android:orientation="horizontal" >
</LinearLayout>
java:
View linearLayout = findViewById(R.id.part1);
((LinearLayout) linearLayout).removeAllViews();
for (int i = 0; i < 15; i ++){
TextView tv = new TextView(this);
tv.setText(String.valueOf(i));
LinearLayout.LayoutParams lay = new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tv.setLayoutParams(lay);
tv.setBackgroundResource(R.drawable.msg);
tv.setId(i);
((LinearLayout) linearLayout).addView(tv);
}
Now i have two questions:
1) the text views are added horizontally correctly but if not fitting screensize, some of them won't appear, how to force it to continue adding in a new line once the horizontal space is full ?
2) textviews are added from left to right, how to add them from right to left ?
thanks
You need to understand how ViewGroups work, in this case, LinearLayout will add items horizontally or vertically without making position calculations for you unless you explicitly specify (jumping to next line is not one of them...), think of it as an item holder that will show items only on the space you specify for it (thats why some of the elements disappear...), by default the way LinearLayout arrange items is from left to right or up to down, if this do not fit your needs, you could go for any of the ViewGroup options android has, the most important might be:
RelativeLayout
FrameLayout
TableLayout
AbsoluteLayout(not recommended)
If you need some sort of Free Draw on the screen, you can always go for a View object, override onDraw, and play with the canvas of that object...
Regards!
I have the following:
-A map with Strings like:["Color: blue","Size: big"] called detailsArray
An existing ScrollView with a LinearLayout and existing TextViews:
<ScrollView>
<LinearLayout>
<TextView
android:text="something: else"
/>
</LinearLayout>
</ScrollView>
I've ommited common fields like width, height, xml schemas on purpose.
Now I want to add textViews programmatically.
I don't know hoy many are they:
TextView detail;
LinearLayout llay = (LinearLayout)fragmentView.findViewById(R.id.container);
for (int i = 0; i < detailsArray.length; i++) {
detail = new TextView(fragmentView.getContext());
detail.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
detail.setText(detailsArray[i]);
llay.addView(detail);
}
ScrollView sv = (ScrollView) fragmentView.findViewById(R.id.scroll_view);
sv.addView(llay);
But I'm getting an exception:
04-17 12:38:09.975: E/AndroidRuntime(3361): Caused by: java.lang.IllegalStateException: ScrollView can host only one direct child
What should I do?
Thank you in advance.
You should remove sv.addView(llay); as you are basically adding the linear layout twice to the same ScrollView - that the exception you are getting and why when you removeAllViews in the beginning it solves the issue.
After you finish the for loop call
sv.invalidate();
sv.requestLayout();
should make it refresh it's content.
I would like to take an existing ScrollView with a view in it, and add more views, dynamically (at runtime) to the ScrollView container.
Is it possible to add these views without having to create a new layout and inflate it? If so, what's the general process for adding these views dynamically?
For the sake of this question, assume the views are TextView...
Thanks!
A ScrollView can only have one child, so it doesn't make sense to add more children to it directly. Lets say your ScrollView has a LinearLayout inside of it, then you can add more views to the LinearLayout:
LinearLayout layout = findViewById(R.id.my_linear_layout);
TextView textView = new TextView(this);
layout.addView(textView);