Add buttons dynamically to ScrollView android - java

So I want to add x amount of buttons to a layout in android (where x is usually between 4 and 24), and I can achieve this using the code below, but it doesn't scroll so it cuts off some of the buttons
I am using a fragment, which contains a LinearLayout and BottomNavigation, and one of those navigation options leads to the fragment contained below
At the moment my.xml file looks like:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/units_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
And my code:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_course_units, container, false);
final LinearLayout unitsBtns = (LinearLayout) view.findViewById(R.id.units_group);
//I actually get this from a volley request but didn't want to include all the code
String[] units = {"1", "2", "3", "4", "5", "6", "7", "8"};
for(int i = 0; i < units.length; i++){
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
);
params.setMargins(0, 30, 0, 0);
Button b = new Button(getActivity());
b.setLayoutParams(params);
b.setText(units[i]);
b.setId(i);
b.setBackgroundColor(Color.WHITE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
// STUFF HERE
} catch (Exception e) {
e.printStackTrace();
}
}
});
unitsBtns.addView(b);
}
return view;
}
Is there any way to get the buttons to be scrollable? I have tried to put the scrollView around the parent of this too and it still doesn't seem to work.
Note: I am still pretty new to developing native Android apps so please correct me if I'm doing something incorrectly

when you have to use ScrollView you should give android:layout_height="wrap_content" in child view of ScrollView then only you have to scroll your view
You should use user LinearLayout like this
<LinearLayout
android:id="#+id/units_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:orientation="vertical">
</LinearLayout>
here also you have to replace
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
Note: when you give match_parent in height attribute, it will limit your view to device screen
hope it will help you.. :)

Here's a working example (horizontal) :
<HorizontalScrollView
android:id="#+id/hsv1"
android:scrollbars="none"
android:background="#0d47a1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/hsvLayout1"
android:background="#0d47a1"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</LinearLayout>
</HorizontalScrollView>
Get ScrollView and Layout:
HorizontalScrollView hsv1 = (HorizontalScrollView) findViewById( R.id.hsv1 );
LinearLayout layout = (LinearLayout) hsv1.findViewById( R.id.hsvLayout1 );
layout.removeAllViews();
Create a button dynamically:
Button myButton = new Button (this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT );
lp.setMargins( 20, 0, 20, 0 );
myButton.setLayoutParams(lp);
myButton.setTextColor( Color.YELLOW );
myButton.setGravity( Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL );
myButton.setText( "Hello World !" );
Add button to layout:
layout.addView(myButton);

Related

Dynamic buttons dont show in android studio using fragments

Im trying to dynamicaly add buttons to a fragment, but they do not show.
This is the listCharacter.java:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_list_character, container, false);
context = view.getContext();
for (int i = 1; i <= 20; i++) {
LinearLayout layout = new LinearLayout(context);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
Button firstBtn = new Button(this.context);
firstBtn.setId(i);
final int id_ = firstBtn.getId();
/**
* The text is not updated(?)
*/
firstBtn.setText("button " + id_);
/**
* it does not add 20 button, might be on top of each other
*/
layout.addView(firstBtn, params);
firstBtn = view.findViewById(R.id.characterNameBtn);
firstBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Toast.makeText(view.getContext(),
"Button clicked index = " + id_, Toast.LENGTH_SHORT)
.show();
Navigation.findNavController(view).navigate(R.id.action_listCharacter_to_loadCharacter);
}
});
}
return view;
}
And this is the fragment_list_character.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background"
tools:context=".listCharacter"
android:orientation="vertical">
<LinearLayout
android:id="#+id/list_character_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
<Button
android:id="#+id/characterNameBtn"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#66000000"
android:fontFamily="#font/main"
android:gravity="center"
android:padding="5dp"
android:text=""
android:textColor="#fff"
android:textSize="40sp"
/>
</LinearLayout>
</LinearLayout>
I dont get any error messages atm, but i cant see the buttons when i run the program.
The on click works and it says it has id 20.
You're adding the buttons to a LinearLayout that you are recreating each time through your loop.
for (int i = 1; i <= 20; i++) {
LinearLayout layout = new LinearLayout(context);
...
layout.addView(firstBtn, params)
....
}
layout is never added to the view that is returned. You will need to add the buttons to the view or to a child of the view that you return to see them on the screen. I think that there are a few other issues, but this would be the first one to address.

Create multi LinearLayout that contains ConstraintLayout programmatically?

I want to create a list of things. Clearly, there is just a LinearLayout including ConstraintLayout and I want to duplicate LinearLayout because of that if I do not use LinearLayout as a parent of ConstraintLayout, components are overlap. I want to use LinearLayout as a row, ConstraintLayout as a area that contains components.
To sum up, I want to create LinearLayout instead of just creating ConstraintLayout. For now I can only create ConstraintLayout inside LinearLayout. I just want to create LinearLayout that includes ConstraintLayout each loop.
My XML codes here:
<LinearLayout
android:id="#+id/ParentLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ContainerConstraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="15dp"
android:paddingBottom="25dp" >
</android.support.constraint.ConstraintLayout>
</LinearLayout>
My Java Codes here:
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState){
ConstraintLayout constraintLayout = Objects.requireNonNull(getView()).findViewById(R.id.ContainerConstraintLayout);
TextView[] title_textview = new TextView[5];
CircleImageView circle_images[] = new CircleImageView[10];
for(int i = 0; i < 5; i++){
circle_images[i] = new CircleImageView(thiscontext);
circle_images[i].setId(View.generateViewId());
circle_images[i].setBackgroundResource(R.drawable.waiter);
circle_images[i].setPadding(10, 10, 10, 10);
circle_images[i].setLayoutParams(new ConstraintLayout.LayoutParams(100, 100));
constraintLayout.addView(circle_images[i]);
title_textview[i] = new TextView(thiscontext);
title_textview[i].setId(View.generateViewId());
title_textview[i].setText("Title: " + i);
title_textview[i].setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
constraintLayout.addView(title_textview[i]);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(constraintLayout);
constraintSet.connect(title_textview[i].getId(), ConstraintSet.TOP, constraintLayout.getId(), ConstraintSet.TOP);
constraintSet.connect(title_textview[i].getId(), ConstraintSet.END, constraintLayout.getId(), ConstraintSet.END);
constraintSet.applyTo(constraintLayout);
}
}

How to put programmatically created Horizontally Scrolling view with XML created Layout in Android?

In my app a user can select multiple images from gallery then he can view it within the app.
I have three buttons within a Relative Layout
<RelativeLayout 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"
tools:context="com.codenemesis.multipleimg.MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="imageSelector"
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="up"
android:text="Upload"/>
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="viewclick"
android:text="View Images" />
To show the images I programmatically created ImageView array within HorizontalScrollView set to WRAP_CONTENT but the problem is when I click on view button HorizontalScrollView span over the whole screen like this.
I want to show HorizontalScrollView below view button. How can I do it?
Here is how I created HorizontalScrollView
HorizontalScrollView horizontalScrollView = new HorizontalScrollView(this);
LinearLayout linearLayout = new LinearLayout(this);
ViewGroup.LayoutParams prams = new ViewGroup.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
linearLayout.setLayoutParams(prams);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
horizontalScrollView.addView(linearLayout);
// mArrayUri is the arraylist of images selected from gallery
int b = mArrayUri.size();
int c = 0;
ImageView[] imageViews = new ImageView[mArrayUri.size()];
while (c < mArrayUri.size()) {
imageViews[c] = new ImageView(this);
imageViews[c].setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
imageViews[c].setPadding(10,0,10,0);
imageViews[c].setImageURI(mArrayUri.get(c));
linearLayout.addView(imageViews[c]);
c++;
// Set context view
setContentView(horizontalScrollView);
The code in your xml file should be like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.test.myapplication.MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="select images"
android:onClick="imageSelector"/>
<Button
android:id="#+id/button2"
android:layout_toRightOf="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="up"
android:text="Upload"/>
<Button
android:id="#+id/button3"
android:layout_toRightOf="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="viewclick"
android:text="View Images" />
<RelativeLayout
android:id="#+id/parent_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/button"
android:layout_marginTop="10dp"
>
</RelativeLayout>
The code in you java file should be like this
public class MainActivity extends AppCompatActivity {
RelativeLayout relativeLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeLayout=findViewById(R.id.parent_panel);
}
public void imageSelector(View view)
{
}
public void up(View view)
{
}
public void viewclick(View view)
{
HorizontalScrollView horizontalScrollView =
new HorizontalScrollView(this);
LinearLayout linearLayout = new LinearLayout(this);
ViewGroup.LayoutParams prams = new ViewGroup.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
linearLayout.setLayoutParams(prams);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
horizontalScrollView.addView(linearLayout);
// mArrayUri is the arraylist of images selected from gallery
int b = mArrayUri.size();
int c = 0;
ImageView[] imageViews = new ImageView[mArrayUri.size()];
while (c < mArrayUri.size()) {
imageViews[c] = new ImageView(this);
imageViews[c].setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
imageViews[c].setPadding(10, 0, 10, 0);
imageViews[c].setImageURI(mArrayUri.get(c));
linearLayout.addView(imageViews[c]);
c++;
}
relativeLayout.addView(horizontalScrollView);
}
}
This should do the trick for you.

How to create a scroll list of custom relative layouts not stacking upon each other in Android Studio?

I want to create a scroll view list which would show "boxes" or more accurately custom made layouts (I'm using a custom class that extends a RelativeLayout - basically shows different pieces of information, some are static like places' working hours and some change dynamically and will be pulled from a server).
Though I encountered a problem - I (for the sake of seeing if my solution works) created 5 boxes and added them to the scroll view list but it seems like they are stacked upon each other. What's the proper way to make them appear one under another without manually tweaking their position coordinates? I was using addView() for that purpose but it doesn't work as intended for me or I use it poorly. If you know the answer, please briefly describe how this should be done.
Thanks in advance!
EDIT, here goes the code:
public class RestaurantBox extends RelativeLayout {
RestaurantBox (Context context){
super(context);
this.setBackgroundColor(context.getResources().getColor(R.color.colorAccent));
TextView restaurantName = new TextView(context);
restaurantName.setText("Test Restaurant");
RelativeLayout.LayoutParams restNameParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
this.addView(restaurantName, restNameParams);
restaurantName.setTypeface(null, Typeface.BOLD);
TextView freeSpots = new TextView(context);
freeSpots.setText("15/20");
RelativeLayout.LayoutParams freeSpotParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
freeSpotParams.topMargin = restNameParams.bottomMargin + 50;
this.addView(freeSpots, freeSpotParams);
TextView book = new TextView(this.getContext());
RelativeLayout.LayoutParams bookParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
book.setText("Book");
bookParams.setMargins(0,freeSpotParams.bottomMargin + 100,0,0);
this.addView(book, bookParams);
}
}
public class BrowseRestaurants extends AppCompatActivity {
int restaurantCount;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browse_restaurants);
Intent intent = getIntent();
String login = intent.getStringExtra("LOGIN");
TextView text = (TextView) findViewById(R.id.txtWelcomeUser);
text.setText("Welcome, " + login);
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relLayoutRestaurants);
RestaurantBox initRBox = new RestaurantBox(this);
initRBox.setTop(0);
initRBox.setBottom(300);
relativeLayout.addView(initRBox);
for(int i=1;i<5;i++){
final View view = relativeLayout.getChildAt(i-1);
RestaurantBox restaurantBox = new RestaurantBox(this);
restaurantBox.setTop(view.getBottom() + 50);
restaurantBox.setBottom(restaurantBox.getTop() + 300);
relativeLayout.addView(restaurantBox);
}
}
}
<!-- activity_browse_restaurants.xml-->
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:fillViewport="true"
android:orientation="vertical"
tools:context="com.konrad.rezerwacje1.BrowseRestaurants">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollViewRestaurants"
android:layout_below="#+id/txtWelcomeUser"
android:layout_alignParentStart="true">
<RelativeLayout
android:id="#+id/relLayoutRestaurants"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="65dp"
android:orientation="vertical">
</RelativeLayout>
</ScrollView>
<TextView
android:id="#+id/txtLogout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Logout"
android:textColor="#android:color/holo_red_dark"
android:textSize="18sp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true" />
<TextView
android:id="#+id/txtWelcomeUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="#style/TextAppearance.AppCompat.Display1"
android:textColor="#android:color/holo_blue_dark"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="9dp" />
</RelativeLayout
>
you are adding view in RelativeLayout so view stacking on each other so change it to LinearLayout in activity_browse_restaurants.xml
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollViewRestaurants"
android:layout_below="#+id/txtWelcomeUser"
android:layout_alignParentStart="true">
<LinearLayout
android:id="#+id/relLayoutRestaurants"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="65dp"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
now make changes according to in BrowseRestaurants.class
replace
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relLayoutRestaurants);
with
LinearLayout relativeLayout = (LinearLayout) findViewById(R.id.relLayoutRestaurants);
else will be fine if you want to change variable name its up to u, let me know if any problem

Android programmatically added button has match parent width and height

I'm trying to add this button
Button dalsi_akce = new Button(this);
dalsi_akce.setGravity(Gravity.CENTER);
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
dalsi_akce.setLayoutParams(p);
setContentView(dalsi_akce);
dalsi_akce.setText("test");
button appears but is full match parent. I have this button over whole display. How to set width and height of button?
You are setting the activity's content to be a button. That's why it spans over the whole activity and is simply wrong.
Instead create your activity's layout (an xml file) and set it with setContentView. Then you can programatically add a button to the content.
Example:
your activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewGroup viewGroup = (ViewGroup) findViewById(R.id.myLayout);
Button dalsi_akce = new Button(this);
dalsi_akce.setGravity(Gravity.CENTER);
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
dalsi_akce.setLayoutParams(p);
dalsi_akce.setText("test");
viewGroup.addView(dalsi_akce);
}
main.xml:
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
android:id="#+id/myLayout"
tools:context=".MyActivity">
</RelativeLayout>
First of all you should define your content view as a RelativeLayout or LinearLayout, then add your button to this layout. Also You can another constructor of RelativeLayout.LayoutParams class:
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(200, 70);
actually you use this constructor :
public LayoutParams(int w, int h) {
super(w, h);
}
It would be easier if you just created your layout in layout.xml, and then customize your buttons as you wish in code. For example you could do the following:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id"#+id/left_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:text="Left"/>
</RelativeLayout>
This would give you one button that is only as big as its contents in the top right corner.

Categories