I am trying to make buttons wrap in a LinearLayout in Android, but they are just continuing off to the right of the view (the word shown in the screenshot should be "HELLO", so I want the "O" to drop down to the next line).
I am adding the buttons programmatically, but even if I code them into the XML layout file, they still don't wrap. Here is the layout file with the LinearLayout container into which I am dynamically adding the buttons:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constrainedWidth="true"
tools:context=".LetterTileView">
<LinearLayout
android:id="#+id/TilesContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constrainedWidth="true"
android:orientation="horizontal">
</LinearLayout>
And here is the code I am using to create and add the tile buttons:
Context context = this;
LinearLayout layout = (LinearLayout) findViewById(R.id.TilesContainer);
LayoutParams params = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT );
params.setMargins(50, 50, 0, 0);
for (int i=0;i<wordLength;i++) {
Button tileButton = new Button(this);
tileButton.setLayoutParams(params);
tileButton.setText(wordStringtoLetters[i]);
tileButton.setId(i);
tileButton.setBackgroundResource(R.drawable.tile_button);
tileButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 36);
layout.addView(tileButton);
}
Any advice would be appreciated. Thanks!
I ended up using FlexboxLayout, which works great for this. Thanks to those who offered suggestions!
First of all, there is no need to use a ConstraintLayout you can use your LinearLayout as the parent layout.
Then for the purpose of displaying all buttons in one line, you have to set weight for the LinearLayout in XML and set weight for the views you add to it.
The xml file should look like:
<LinearLayout
android:id="#+id/TilesContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:weightSum="5"
app:layout_constrainedWidth="true"
android:orientation="horizontal">
</LinearLayout>
And in code you should set weight for each view you by adding ,1.0f to LayoutParam :
Context context = this;
LinearLayout layout = (LinearLayout) findViewById(R.id.TilesContainer);
LayoutParams params = new LayoutParams( LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT,1.0f );
params.setMargins(50, 50, 0, 0);
for (int i=0;i<wordLength;i++) {
Button tileButton = new Button(this);
tileButton.setLayoutParams(params);
tileButton.setText(wordStringtoLetters[i]);
tileButton.setId(i);
tileButton.setBackgroundResource(R.drawable.tile_button);
tileButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 36);
layout.addView(tileButton);
}
I have a webview, a functionality that add a new button to this webview, the problem here is I can't not set the margins to this button and it always show on the top, left of webview.
Or any solutions for my situation: I want to add a control at specify position(x, y) inside a webview, when users scroll on the webview, the control will be scroll as well and always be shown at exactly position I have set before?
My xml layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="#+id/mainLayout"
>
<WebView
android:id="#+id/myWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:visibility="visible">
</WebView>
</LinearLayout>
My code to create new button is:
private void createButton(WebView wv){
//LinearLayout relativeLayout = (LinearLayout)findViewById(R.id.mainLayout);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(60,60, Gravity.TOP);
params.setMargins(50, 50, 0, 0);// Doesn't work at all here
android.widget.Button button = new android.widget.Button(this);
button.setText("Hello button");
button.setLayoutParams(params);
wv.addView(button);
}
Any helps will be thanked in advanced
You have to use WebView.LayoutParams instead of LinearLayout.LayoutParams.
Replace
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(60,60, Gravity.TOP);
params.setMargins(50, 50, 0, 0);
with
WebView.LayoutParams params = new WebView.LayoutParams(60, 60, 50, 50);
I have an xml layout structure something like this:
<?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"
android:id="#+id/ll"
android:layout_marginRight="54dp">
<TextView
android:id="+#id/tv"
....
/>
</LinearLayout
I am trying to programatically increase the marginRight of the linear layout. In my Java code i have something like this:
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(0,0,100,0);
if(something is true){
ll.setLayoutParams(lp);
}
else {
//do nothing
}
I get an null ptr exception on the line ll.setLayoutParams(lp);
"ll" has no parent, so you can't set margin to it, set padding instead, or set margin to the "tv"
I have a vertical LinearLayout with android:layout_height = "fill_parent".
Now, I add multiple child views to it, sometimes 2 views, at other times 3, based on certain parameters from database, dynamically.
I would like to know how can I, programmatically, distribute these dynamically added childviews in the vertical LinearLayout, so that they get distributed uniformly.
BTW, i cannot use GridView as I have to embed this LinearLayout in horizontal ScrollView, and using GridView inside horizontal ScrollView is highly discouraged.
EDIT: Adding source and xml files:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/serverScreensScreen1LL1"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF" >
<ScrollView
android:id="#+id/serverScreensScreen1SV1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
>
<HorizontalScrollView
android:id="#+id/serverScreensScreen1HSV1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
>
<LinearLayout
android:orientation="horizontal"
android:id="#+id/serverScreensScreen1LL2"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</LinearLayout>
</HorizontalScrollView>
</ScrollView>
</LinearLayout> <!-- Main Container -->
SOURCE:
private void drawContent()
{
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(fpfp);
LinearLayout.LayoutParams lp3 = new LinearLayout.LayoutParams(wcwc);
lp3.weight = 0.3F;
LinearLayout ll1 = (LinearLayout) findViewById(R.id.serverScreensScreen1LL2);
for (int i=0; i<20; i++)
{
LinearLayout ll2 = new LinearLayout(this);
ll2.setOrientation(LinearLayout.VERTICAL);
ll2.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
ll2.setWeightSum(1.0F);
LinearLayout ll3 = new LinearLayout(this);
ll3.setOrientation(LinearLayout.VERTICAL);
ll3.setLayoutParams(lp3);
TextView tv1 = new TextView(mContext);
tv1.setText("Sample Text A: " + i);
tv1.setBackgroundColor(Color.rgb(12, 34, 56 + i * 8));
tv1.setLayoutParams(wcwc);
ll3.addView(tv1);
LinearLayout ll4 = new LinearLayout(this);
ll4.setOrientation(LinearLayout.VERTICAL);
ll4.setLayoutParams(lp3);
TextView tv2 = new TextView(mContext);
tv2.setText("Sample Text B: " + i);
tv2.setBackgroundColor(Color.rgb(34, 12 + i * 8, 56));
tv2.setLayoutParams(wcwc);
ll4.addView(tv2);
LinearLayout ll5 = new LinearLayout(this);
ll5.setOrientation(LinearLayout.VERTICAL);
ll5.setLayoutParams(lp3);
TextView tv3 = new TextView(mContext);
tv3.setText("Sample Text C: " + i);
tv3.setBackgroundColor(Color.rgb(56 + i * 8, 34, 12));
tv3.setLayoutParams(wcwc);
ll5.addView(tv3);
ll2.addView(ll3);
ll2.addView(ll4);
ll2.addView(ll5);
ll1.addView(ll2);
}
}
Any suggestions plz...
I am not sure of how you are trying to distribute the views but you can try playing with weights.
Search for android:weightSum inside the LinearLayout's docs.
I try to add a TextView to a LinearLayout dynamically such as in the following code, but it doesn't appear when I run the application?
setContentView(R.layout.advanced);
m_vwJokeLayout=(LinearLayout) this.findViewById(R.id.m_vwJokeLayout);
m_vwJokeEditText=(EditText) this.findViewById(R.id.m_vwJokeEditText);
m_vwJokeButton=(Button) this.findViewById(R.id.m_vwJokeButton);
TextView tv=new TextView(this);
tv.setText("test");
this.m_vwJokeLayout.addView(tv);
What's the problem?
LayoutParams lparams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
TextView tv=new TextView(this);
tv.setLayoutParams(lparams);
tv.setText("test");
this.m_vwJokeLayout.addView(tv);
You can change lparams according to your needs
Here is a more general answer for future viewers of this question. The layout we will make is below:
Method 1: Add TextView to existing LinearLayout
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dynamic_linearlayout);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.ll_example);
// Add textview 1
TextView textView1 = new TextView(this);
textView1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
textView1.setText("programmatically created TextView1");
textView1.setBackgroundColor(0xff66ff66); // hex color 0xAARRGGBB
textView1.setPadding(20, 20, 20, 20);// in pixels (left, top, right, bottom)
linearLayout.addView(textView1);
// Add textview 2
TextView textView2 = new TextView(this);
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.RIGHT;
layoutParams.setMargins(10, 10, 10, 10); // (left, top, right, bottom)
textView2.setLayoutParams(layoutParams);
textView2.setText("programmatically created TextView2");
textView2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
textView2.setBackgroundColor(0xffffdbdb); // hex color 0xAARRGGBB
linearLayout.addView(textView2);
}
Note that for LayoutParams you must specify the kind of layout for the import, as in
import android.widget.LinearLayout.LayoutParams;
Otherwise you need to use LinearLayout.LayoutParams in the code.
Here is the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_example"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff99ccff"
android:orientation="vertical" >
</LinearLayout>
Method 2: Create both LinearLayout and TextView programmatically
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// NOTE: setContentView is below, not here
// Create new LinearLayout
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setBackgroundColor(0xff99ccff);
// Add textviews
TextView textView1 = new TextView(this);
textView1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
textView1.setText("programmatically created TextView1");
textView1.setBackgroundColor(0xff66ff66); // hex color 0xAARRGGBB
textView1.setPadding(20, 20, 20, 20); // in pixels (left, top, right, bottom)
linearLayout.addView(textView1);
TextView textView2 = new TextView(this);
LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.RIGHT;
layoutParams.setMargins(10, 10, 10, 10); // (left, top, right, bottom)
textView2.setLayoutParams(layoutParams);
textView2.setText("programmatically created TextView2");
textView2.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
textView2.setBackgroundColor(0xffffdbdb); // hex color 0xAARRGGBB
linearLayout.addView(textView2);
// Set context view
setContentView(linearLayout);
}
Method 3: Programmatically add one xml layout to another xml layout
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dynamic_linearlayout);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.dynamic_linearlayout_item, null);
FrameLayout container = (FrameLayout) findViewById(R.id.flContainer);
container.addView(view);
}
Here is dynamic_linearlayout.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/flContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
And here is the dynamic_linearlayout_item.xml to add:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_example"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff99ccff"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ff66ff66"
android:padding="20px"
android:text="programmatically created TextView1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffdbdb"
android:layout_gravity="right"
android:layout_margin="10px"
android:textSize="18sp"
android:text="programmatically created TextView2" />
</LinearLayout>
I customized more #Suragch code. My output looks
I wrote a method to stop code redundancy.
public TextView createATextView(int layout_widh, int layout_height, int align,
String text, int fontSize, int margin, int padding) {
TextView textView_item_name = new TextView(this);
// LayoutParams layoutParams = new LayoutParams(
// LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// layoutParams.gravity = Gravity.LEFT;
RelativeLayout.LayoutParams _params = new RelativeLayout.LayoutParams(
layout_widh, layout_height);
_params.setMargins(margin, margin, margin, margin);
_params.addRule(align);
textView_item_name.setLayoutParams(_params);
textView_item_name.setText(text);
textView_item_name.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
textView_item_name.setTextColor(Color.parseColor("#000000"));
// textView1.setBackgroundColor(0xff66ff66); // hex color 0xAARRGGBB
textView_item_name.setPadding(padding, padding, padding, padding);
return textView_item_name;
}
It can be called like
createATextView(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, RelativeLayout.ALIGN_PARENT_RIGHT,
subTotal.toString(), 20, 10, 20);
Now you can add this to a RelativeLayout dynamically. LinearLayout is also same, just add a orientation.
RelativeLayout primary_layout = new RelativeLayout(this);
LayoutParams layoutParam = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
primary_layout.setLayoutParams(layoutParam);
// FOR LINEAR LAYOUT SET ORIENTATION
// primary_layout.setOrientation(LinearLayout.HORIZONTAL);
// FOR BACKGROUND COLOR
primary_layout.setBackgroundColor(0xff99ccff);
primary_layout.addView(createATextView(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, RelativeLayout.ALIGN_LEFT, list[i],
20, 10, 20));
primary_layout.addView(createATextView(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, RelativeLayout.ALIGN_PARENT_RIGHT,
subTotal.toString(), 20, 10, 20));
TextView rowTextView = (TextView)getLayoutInflater().inflate(R.layout.yourTextView, null);
rowTextView.setText(text);
layout.addView(rowTextView);
This is how I'm using this:
private List<Tag> tags = new ArrayList<>();
if(tags.isEmpty()){
Gson gson = new Gson();
Type listType = new TypeToken<List<Tag>>() {
}.getType();
tags = gson.fromJson(tour.getTagsJSONArray(), listType);
}
if (flowLayout != null) {
if(!tags.isEmpty()) {
Log.e(TAG, "setTags: "+ flowLayout.getChildCount() );
flowLayout.removeAllViews();
for (Tag tag : tags) {
FlowLayout.LayoutParams lparams = new FlowLayout.LayoutParams(FlowLayout.LayoutParams.WRAP_CONTENT, FlowLayout.LayoutParams.WRAP_CONTENT);
lparams.setMargins(PixelUtil.dpToPx(this, 0), PixelUtil.dpToPx(this, 5), PixelUtil.dpToPx(this, 10), PixelUtil.dpToPx(this, 5));// llp.setMargins(left, top, right, bottom);
TextView rowTextView = (TextView) getLayoutInflater().inflate(R.layout.tag, null);
rowTextView.setText(tag.getLabel());
rowTextView.setLayoutParams(lparams);
flowLayout.addView(rowTextView);
}
}
Log.e(TAG, "setTags: after "+ flowLayout.getChildCount() );
}
And this is my custom TextView named tag:
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"
android:textAllCaps="true"
fontPath="#string/font_light"
android:background="#drawable/tag_shape"
android:paddingLeft="11dp"
android:paddingTop="6dp"
android:paddingRight="11dp"
android:paddingBottom="6dp">
this is my tag_shape:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#f2f2f2" />
<corners android:radius="15dp" />
</shape>
efect:
In other place I'm adding textviews with language names from dialog with listview:
layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/layoutTest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
</LinearLayout>
</RelativeLayout>
class file:
setContentView(R.layout.layout_dynamic);
layoutTest=(LinearLayout)findViewById(R.id.layoutTest);
TextView textView = new TextView(getApplicationContext());
textView.setText("testDynamic textView");
layoutTest.addView(textView);
If you are using Linearlayout. its params should be "wrap_content" to add dynamic data in your layout xml. if you use match or fill parent then you cannot see the output.
It Should be like this.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>