I’m trying to put a matrix (2 x 2) of buttons into a constraint layout and then to put the constraint (with the 4 buttons included) layout into a scroll view and finally to add the scroll view into the main layout. The code is provided here below. Can anyone tell me what do I wrong since finally the bar appears instead of the matrix of buttons? It was planned to have 4 buttons visible, but in fact 2 buttons is appearing. Are there any suggestion how to make the task smarter way. Thank you in advance!
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConstraintLayout layout = findViewById(R.id.layout);
ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(200, 200);
ConstraintLayout constraintLayout = new ConstraintLayout(MainActivity.this);
constraintLayout.setLayoutParams(params);
GradientDrawable shape1 = new GradientDrawable();
shape1.setColor(Color.BLUE);
GradientDrawable shape2 = new GradientDrawable();
shape2.setColor(Color.GREEN);
Button button11 = new Button(MainActivity.this);
Button button12 = new Button(MainActivity.this);
Button button21 = new Button(MainActivity.this);
Button button22 = new Button(MainActivity.this);
ConstraintLayout.LayoutParams params01 = new ConstraintLayout.LayoutParams(100,100);
button11.setLayoutParams(params01);
button11.setX(0);
button11.setY(0);
constraintLayout.addView(button11);
ConstraintLayout.LayoutParams params02 = new ConstraintLayout.LayoutParams(100,100);
button12.setLayoutParams(params02);
button12.setX(100);
button12.setY(0);
constraintLayout.addView(button12);
ConstraintLayout.LayoutParams params03 = new ConstraintLayout.LayoutParams(100,100);
button21.setLayoutParams(params03);
button21.setX(0);
button21.setY(100);
constraintLayout.addView(button21);
ConstraintLayout.LayoutParams params04 = new ConstraintLayout.LayoutParams(100,100);
button22.setLayoutParams(params04);
button22.setX(100);
button22.setY(100);
constraintLayout.addView(button22);
ScrollView SV = new ScrollView(MainActivity.this);
ConstraintLayout.LayoutParams SVparams = new ConstraintLayout.LayoutParams(300,300);
SV.setLayoutParams(SVparams);
constraintLayout.setBackground(shape1);
SV.setBackground(shape2);
SV.addView(constraintLayout);
layout.addView(SV);
}
<?xml version="1.0" encoding="utf-8"?>
<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:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
My solution:
ConstraintLayout.LayoutParams params03 = new ConstraintLayout.LayoutParams(100,100);
params03.topToTop = PARENT_ID;
params03.setMargins(0, 100, 0, 0);
button21.setLayoutParams(params03);
button21.setX(0);
constraintLayout.addView(button21);
ConstraintLayout.LayoutParams params04 = new ConstraintLayout.LayoutParams(100,100);
params04.topToTop = PARENT_ID;
params04.setMargins(0, 100, 0, 0);
button22.setLayoutParams(params04);
button22.setX(100);
constraintLayout.addView(button22);
It looks like there's a bug when you put a ConstraintLayout inside a ScrollView. The ConstraintLayout's height defaults to WRAP_CONTENT. So when you set it to any other heights, it won't change. Also setY does not work. You have to set vertical constraints for the buttons in the bottom row to position them vertically.
Result:
If your target is really just simple 2x2 button grid(matrix), then I'm wondering why should you need to achieve this dynamically, when you can just describe all the layout in xml even if its just a fragment for some more complex view or, say, a list/grid item; moreover, you already have xml describing your ConstraintLayout. So in perspective it may look like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#8FFF0E">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#105BFF">
<Button
android:id="#+id/btnFirst"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="#+id/btnSecond"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toEndOf="#id/btnFirst"
app:layout_constraintTop_toTopOf="parent"/>
<Button
android:id="#+id/btnThird"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/btnFirst"/>
<Button
android:id="#+id/btnFourth"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintStart_toEndOf="#id/btnThird"
app:layout_constraintTop_toBottomOf="#id/btnSecond"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
After having it all in prepared view, you can either operate buttons by ids (either, hiding/showing them or changing their properties).
By the topic - you obviously can do it programmatically with the help of ConstraintSet. Check this one: ConstraintLayout: change constraints programmatically
Related
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);
}
Hi I have a ScrollView and a vertical LinearLayout inside that. Inside each LinearLayout slot I have a horizonal LinearLayout that holds 2 things a word and a number. The problem is some of the words are hidden?? and it takes up half the screen. Thanks for any help.
Layout bounds
for (int i = 0; i < words.size(); i++) {
LinearLayout horizontal = new LinearLayout(context);
horizontal.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout.LayoutParams LLParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
horizontal.setLayoutParams(LLParams);
btnWord.add(i, new Button(context));
btnWord.get(i).setHeight(60);
btnWord.get(i).setWidth(120);
btnWord.get(i).setTypeface(montFont);
btnWord.get(i).setBackgroundColor(Color.WHITE);
btnWord.get(i).setTag(i);
btnWord.get(i).setGravity(Gravity.CENTER);
btnWord.get(i).setText(" " + words.get(i));
btnWord.get(i).setOnClickListener(btnClicked);
horizontal.addView(btnWord.get(i));
wordWeight.add(i, new Button(context));
wordWeight.get(i).setHeight(60);
wordWeight.get(i).setWidth(40);
wordWeight.get(i).setTypeface(montFont);
wordWeight.get(i).setBackgroundColor(Color.WHITE);
wordWeight.get(i).setTag(i);
wordWeight.get(i).setGravity(Gravity.CENTER);
wordWeight.get(i).setText(" " + wordWeights.get(i));
wordWeight.get(i).setOnClickListener(btnClicked);
horizontal.addView(wordWeight.get(i));
linearLayout.addView(horizontal);
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<ScrollView
android:layout_width="match_parent"
style="#android:style/Widget.ScrollView"
android:layout_marginTop="106dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/linearLayout" />
</ScrollView>
</RelativeLayout>
You could try to set the weight of each "item" to 1 so they will equally divide the space on the screen. Something like the snippet below:
LinearLayout ll;
LinearLayout.LayoutParams lp;
lp.weight = 1;
ll.setLayoutParams(lp);
You could also ditch that logic and use a ListView with a custom adapter like I did on this answer, or setup a RecyclerView as you can see on this blog post. It's way easier and more efficient to do either one of those.
More on ListView vs. RecyclerView here.
I tried to add some GUI elements like an ImageView or a TextView to a LinearLayout programmatically. But the elements aren't displayed.
To see if a element is drawn or not, I set a different background color for each element. The result was that I can only see the background color of the LinearLayout. But why?
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
setLayoutParams(params);
setBackgroundColor(Color.RED);
imageView = new ImageView(context);
params = new LinearLayout.LayoutParams(100, 100);
imageView.setLayoutParams(params);
imageView.setBackgroundColor(Color.BLUE);
addView(imageView);
}
}
The strange thing is that I can see the red background color of the LinearLayout but in the size of the ImageView. If I add some other GUI elements like a TextView, I can see how the LinearLayout grows. But I can not see the TextView.
I'm really confused, because this not the first time I do something like this. Can u tell me what I'm doing wrong?
This is a snippet of the layout.xml file:
<LinearLayout android:layout_width="match_parent"
android:layout_height="45dp"
android:id="#+id/bottom_bar"
android:layout_alignParentBottom="true"
android:gravity="bottom">
<FrameLayout android:id="#+id/block_edit_delete_layout"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:background="#drawable/block_edit_delete_selector">
<ImageView android:layout_height="match_parent"
android:layout_width="wrap_content"
android:src="#drawable/block_edit_delete"
android:scaleType="fitXY"
android:contentDescription="#string/delete"/>
</FrameLayout>
<LinearLayout
android:id="#+id/block_edit_progress"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="horizontal"/>
<FrameLayout android:id="#+id/block_edit_random_layout"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:background="#drawable/block_edit_delete_selector">
<ImageView android:layout_height="match_parent"
android:layout_width="wrap_content"
android:src="#drawable/block_edit_random"
android:scaleType="fitXY"
android:contentDescription="#string/random_numbers"/>
</FrameLayout>
</LinearLayout>
The LinearLayout with the ID block_edit_progress is the container layout of multiple instances of the class MyLinearLayout. The instances are added in the code:
for(int i = 0; i < numberOfMyLinearLayouts; i++) {
MyLinearLayout v = new MyLinearLayout(getContext());
addView(v);
}
I hope this helps.
If i convert your code to xml, it would be something like:
<LinearLayout layout_width=wrap_content, layout_height = wrap_content>
<LinearLayout id= MyLinearLayout>//just an idea, syntax may be wrong
<LinearLayout layout_width= 100, layout_width=100>
<ImageView color=BLUE>
</ImageView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Whenever you call setLayoutParams on a View, parameter params you give should be parent element.
Try something like if you want linearlayout to be the parent of your linearlayout, use MATCH_PARENT for width, height if you want your view to span the width, height of view's parent
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
setLayoutParams(lp);//lp is parent view
Also try this, just in case views are getting added to right of your views, and you are not able to see them on screen
yourview.setOrientation(LinearLayout.VERTICAL);
Change the width and height of linear layout to match_parent and see how it changes. wrap_content will only show the content of the linear layout, which seems to be your problem.
I solved the problem. (Or found a workaround)
I moved the complete initialization stuff out of the constructor of the MyLinearLayout. If I then adding a View after the layout has been completely generated, everything works.
Like this:
MyLinearLayout ll = new MyLinearLayout(getContext());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(100, 100);
ll.setLayoutParams(params);
ll.setBackgroundColor(Color.RED);
ImageView v = new ImageView(getContext());
params = new LinearLayout.LayoutParams(50, 50);
v.setLayoutParams(params);
v.setBackgroundColor(Color.GREEN);
ll.addView(v);
addView(ll);
I don't know why the other way doesn't work. Thanks for the fast answers!
I want to figure out how to position views programmatically in android. Lets say for example we have this XML code.
<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"
android:id="#+id/mainLayout">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="121dp"
android:layout_marginTop="140dp"
android:text="Results" /></RelativeLayout>
How can I achieve this layout programmatically in android? because I want to have a random position of my textview.
use the RelativeLayout.LayoutParams with the setLayoutParams Method of the TextBox
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams)textView1.getLayoutParams();
p.leftMargin = xxx; // in PX
p.topMargin = xxx; // in PX
textView1.setLayoutParams(p)
look up dp to px conversion if u want to use dp values
check this..
RelativeLayout main = new RelativeLayout(this);
main.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
TextView textV = new TextView(this);
textV.setGravity(Gravity.LEFT);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(121, 140, 0, 0);
textV.setLayoutParams(layoutParams);
text.setText("Result ");
main .addView(text);
LinearLayout standardtoolbar = new LinearLayout(context);
standardtoolbar.setMinimumWidth(10);
standardtoolbar.setMinimumHeight(50);
Bitmap toolbarBackgroundImage = SkinManager.getInstance().getImageBitmap("BarBackground");
Drawable d = new BitmapDrawable(toolbarBackgroundImage);
standardtoolbar.setBackgroundDrawable(d);
RelativeLayout.LayoutParams lpstandardtool = new RelativeLayout.LayoutParams(5, LayoutParams.WRAP_CONTENT);
lpstandardtool.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
toolbarLayout.addView(standardtoolbar, 0);
/*toolbarLayout.getScrollX();
toolbarLayout.scrollBy(5, 0);
toolbarLayout.setScrollBarStyle(0);
*/
ScrollView scroll = new ScrollView(AppController.getInstance().getCurrentActivity());
scroll.addView(toolbarLayout);
the scroll view is not working for the given layout. The commented code was written for horizontal scroll view. But its not working.
in your xml file example.xml
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:layout_width="wrap_content>
<LinearLayout android:id="layout" android:layout_height="wrap_content" android:layout_width="wrap_content" android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
in java code
LinearLayout standardtoolbar = (LinearLayout)findViewById(R.id.layout);
.
.
.
layout.addView(standardtoolbar, 0);