For the last few days, I've been trying to figure out how to make a list of buttons that are below each other, and fill the entire width of the screen dynamically. So for example:
(I cheaply just took an pre-existing screen shot that had one button and edited it in paint.net to make it look like the buttons are stacked.)
So, essentially, I have a list of strings from R that include the button's names and I need to list them like that. I've been looking around and if I did find anything it was outdated (and didn't work)
This is what I have so far (its a little messy because it contains many attempts at making this happen)
LinearLayout layout = (LinearLayout) findViewById(R.id.mainLayout);
Field[] fields = R.raw.class.getFields();
for(int count=0; count < fields.length; count++){
String filename = fields[count].getName();
try {
Button button = new Button(this);
button.setText(filename);
button.setId(startID + 1 + count); //this variable is offscreen
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//finish later
}
});
button.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
layout.addView(button);
} catch (Exception e) {
Toast.makeText(MainActivity.this, "Exception.", Toast.LENGTH_LONG).show();
}
}
(this is in onCreate() fyi)
So, if anyone has any solutions/ideas on how I can do this, please share. I'm fairly new to creating android applications.
Java
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
String[] items = {"item 1", "item 2", "item 3", "item 4", "item 5"};
for (int i = 0; i < items.length; i++) {
Button btn = new Button(this);
btn.setText(items[i]);
btn.setId(i);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(10, 10, 10, 10);
btn.setLayoutParams(params);
layout.addView(btn);
}
Xml
<LinearLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
A simple example
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">
<LinearLayout
android:id="#+id/linear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="vertical">
</LinearLayout>
</RelativeLayout>
Java:
String[] names = { "button1", "button2", "button3", "button4" };
LinearLayout layout = (LinearLayout) findViewById(R.id.linear);
for (int i = 0; i < 4; i++) {
Button button = new Button(this);
button.setText(names[i]);
button.setId(i);
button.setBackgroundColor(Color.BLUE);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params.setMargins(20, 0, 20, 20); // (left, top, right, bottom)
button.setLayoutParams(params);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// finish later
}
});
layout.addView(button);
You might be better off learning how to use ListViews, and using Adapters to populate the ListView with Buttons containing the data from your array.
Bear in mind that for the solution you and Sajith Sageer offered, when there are too many buttons created, the buttons will extend past the screen, making them unreachable unless you wrap the LinearLayout in a ScrollView.
Related
I'm working on a project where I have a parent LinearLayout with id=linear_parent created on activity_main.xml. Inside this parent layout, n numbers of LinearLayouts are created programmatically base on user input at EditText (id=no_of_views_input).
And inside the each of these Linearlayouts, there are more child views (imageView, edit, button) created programmatically.
Suppose a user enters 4 no_of_views_input, the views heirarchy would be something like,
============
linear_parent
linearLayout //position 1
imageView
edit
button
linearLayout //position 2
imageView
edit
button
linearLayout //position 3
imageView
edit
button
linearLayout //position 4
imageView
edit
button
===========
After these layouts and views are created, I want to rearrange the LinearLayouts, base on user input from child id=edit.
Suppose the user enters 1 on edit at LinearLayout position 3 , what I want is, the current LinearLayout at position 3 must be added to position 1 along with its children, and finally remove the old Linearlayout which was at position 3. (would be currently at position 4 if indexes are shifted down).
activity_main.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:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linear_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:orientation="vertical">
<!-- Views are added here programmatically -->
</LinearLayout>
<EditText
android:id="#+id/no_of_views_input"
android:layout_width="100dp"
android:layout_height="40dp"
android:hint="Number of view to add"/>
<Button
android:id="#+id/add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
LinearLayout linear_parent;
Button add_button;
EditText no_of_views_input;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
linear_parent = findViewById(R.id.linear_parent);
add_button= findViewById(R.id.add_button);
no_of_views_input= findViewById(R.id.no_of_views_input);
no_of_views_input.setInputType(InputType.TYPE_CLASS_NUMBER);
add_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!no_of_views_input.getText().toString().isEmpty()) {
String no_of_views_temp = no_of_views_input.getText().toString();
int no_of_views = Integer.parseInt(no_of_views_temp);
for (int i = 0; i < no_of_views; i++) {
LinearLayout linearLayout = new LinearLayout(MainActivity.this);
LinearLayout.LayoutParams lp_ll = new LinearLayout.LayoutParams(600, 1500);
lp_ll.setMargins(0, 50, 0, 0);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setId(View.generateViewId()); // id = 1, 2, 3, 4, ...
int linearLayoutID = linearLayout.getId();
linearLayout.setLayoutParams(lp_ll);
ImageView imageView = new ImageView(MainActivity.this);
LinearLayout.LayoutParams lp_image = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 800);
imageView.setBackgroundColor(Color.Yellow);
imageView.setLayoutParams(lp_image);
EditText edit = new EditText(MainActivity.this);
LinearLayout.LayoutParams lp_edit = new LinearLayout.LayoutParams(300, ViewGroup.LayoutParams.WRAP_CONTENT);
edit.setBackgroundColor(Color.WHITE);
edit.setInputType(InputType.TYPE_CLASS_NUMBER);
edit.setHint("move to index");
edit.setLayoutParams(lp_edit);
Button button = new Button(MainActivity.this);
LinearLayout.LayoutParams lp_button= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
button.setBackgroundColor(Color.BLUE);
button.setText("Move");
button.setLayoutParams(lp_button);
linear_parent.addView(linearLayout);
linearLayout.addView(imageView);
linearLayout.addView(edit);
linearLayout.addView(button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String indexTarget_temp = edit.getText().toString();
int indexTarget = Integer.parseInt(indexTarget_temp );
int childCount = linear_parent.getChildCount();
int currentLinearLayoutPos = linear_parent.indexOfChild(linearLayout);
try {
linear_parent.addView(linearLayout, indexTarget - 1); //adding current linearLayout to indexTarget
//error occurs this line
linear_parent.removeView(linear_parent.getChildAt(currentLinearLayoutPos + 1)); //removing linearLayout at old index
}
catch(IllegalStateException e) {
e.printStackTrace();
}
}
});
}
}else {
Toast.makeText(MainActivity.this, "Enter index no", Toast.LENGTH_SHORT).show();
}
}
});
}
}
The error I'm getting is
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
Any help would be highly appreciated.
Try to remove the child from its parent before adding it as a subview:
try {
if (linearLayout.getParent() != null) {
// Remove child from parent
((ViewGroup) linearLayout.getParent()).removeView(linearLayout)
}
linear_parent.addView(linearLayout, indexTarget - 1);
}
catch(IllegalStateException e) {
e.printStackTrace();
}
However, consider switching to a RecyclerView.
It would simplify your code structure.
I'm making a game in where the platform will add new button in each level the user has cleared. but I cant add new xml tag in the project on runtime. I'm a little lost of what to use or how to implement.
run = (Button)findViewById(R.id.btnRunChallengeMode);
run.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newForm = new Intent(Form2.this,Form2.class);
buttonPanel = (LinearLayout)findViewById(R.id.LinearButtonPanel);
Button newButton = new Button(null);
newButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
newButton.setId(a);
newButton.setText("Button " + a);
buttonPanel.addView(newButton);
a++;
startActivity(newForm);
}
});
below is the xml code
<HorizontalScrollView
android:id="#+id/buttonPanelChallengeMode"
android:layout_width="match_parent"
android:layout_height="180dp"
android:layout_below="#+id/IDE"
android:layout_marginBottom="3dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="#color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="8dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/LinearButtonPanel">
</LinearLayout>
</HorizontalScrollView>
This is because after adding the button to the layout you are starting the new Activity no matter it's the same activity. Whenever activity is created it will always use the initial xml format. I think you are under the impression that adding new button will persist and becomes a part of XML. That's not true, if you want to start the new activity. Set new Button value in Bundle, then in onCreate check the existence of bundle. If exist's then add a new button.
int buttonId = -1;
protected void onCreate(Bundle b){
//set the layout related stuff first
Bundle b = getIntent().getExtras();
if(b!= null && (b.getInt(NEW_BUTTON_KEY, -1)!=-1)){
buttonPanel = (LinearLayout)findViewById(R.id.LinearButtonPanel);
for(int i = 0; i< b.getInt(NEW_BUTTON_KEY, -1); i++)
Button newButton = new Button(this);
newButton.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
newButton.setId(i);
newButton.setText("Button " + i);
buttonPanel.addView(newButton);
}
}
By the way why are you making new activity? Just add the button in the same activity, otherwise your activity stack will become massic with every level.
Button newButton = new Button(null);
You give to the context null, i suggest you to give proper context. Also you can set tag for button with newButton.setTag(value)
Your Code is not true
you create a button and add to a LinearLayout and after that you call startActivity for load an Activity. So You reset the LinearLayout and buttons clear from that.
you should :
run = (Button)findViewById(R.id.btnRunChallengeMode);
run.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newForm = new Intent(Form2.this,Form2.class);
newForm.putExtra("a", a);
startActivity(newForm);
}
});
and in the create , get Extras :
String a = getIntent().getIntExtra("a");
now you can create the button.
How do I get the background behind my pop up menu to dim after I click the button that opens the popup menu? Looked at other code samples but no luck! Would really appreciate any advice!
final Button Bel = (Button) findViewById(R.id.btnBel);
final ImageView Phone = (ImageView)findViewById(R.id.imgPhone);
relativeLayout = (RelativeLayout) findViewById(R.id.relative);
Bel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bel.setVisibility(View.GONE);
Phone.setVisibility(View.GONE);
layoutInflater = (LayoutInflater) getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
ViewGroup container = (ViewGroup) layoutInflater.inflate(R.layout.popup_menu, null);
popupWindow = new PopupWindow(container, 1000, 850, true);
popupWindow.showAtLocation(relativeLayout, Gravity.NO_GRAVITY, 221, 4000);
btnBelNuCall = (Button) container.findViewById(R.id.btnBelNu);
btnClosePopUp = (Button) container.findViewById(R.id.btnAnnuleren);
btnBelNuCall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:0900-33-44-55-6"));
startActivity(callIntent);
checkPermission();
}
});
btnClosePopUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
Bel.setVisibility(View.VISIBLE);
Phone.setVisibility(View.VISIBLE);
}
});
}
});
1. Create A Layout That Covers Everything In Your Main Layout
I don't know what your XML File looks like, but put something like this at the top of it:
<LinearLayout android:id="dim_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#70000000"
android:visibility="invisible"/>
Note: Depending on your XML file, you may need to alter this for it to be placed on top of all other components.
This will create a layout covering everything in your main layout with a background of color #70000000 which is black with an alpha level of 70. Changing the 70 at the beginning of the hex code will allow you to modify how transparent you want it to be.
2. Show Layout When Popup Is Activated
LinearLayout dim_layout = (LinearLayout) findViewById(R.id.dim_layout);
popupWindow = new PopupWindow(container, 1000, 850, true);
dim_layout.setVisibility(View.VISIBLE);
popupWindow.showAtLocation(relativeLayout, Gravity.NO_GRAVITY, 221, 4000);
3. Hide Layout When Popup Is Deactivated
btnClosePopUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupWindow.dismiss();
Bel.setVisibility(View.VISIBLE);
Phone.setVisibility(View.VISIBLE);
dim_layout.setVisibility(View.INVISIBLE);
}
});
Give an Id to your root tag and in your class, give it the dim background color. For example in your layout activity
<?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="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#F4F4F4"
android:orientation="vertical"
android:id="#+id/main_screen">
in your class
mainView = findViewById(R.id.main_screen);
mainView.setBackgroundColor(Color.parseColor("#30000000"));
I am trying to set the left margin for first RelativeLayout, and
I have this xml code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/market_layout"
android:orientation="horizontal">
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/horizontalScrollView"
android:layout_gravity="center_horizontal"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/market_linear_layout_in_hsv">
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
In this java code insert in LinearLayout with id = market_linear_layout_in_hsv inserting RelativeLayout including some view (Button, TextView, ImageView):
market_ll = (LinearLayout)findViewById(R.id.market_linear_layout_in_hsv);
RelativeLayout.LayoutParams TVParams = new RelativeLayout.LayoutParams(RLwrapContent, RLwrapContent );
RelativeLayout.LayoutParams IVParams = new RelativeLayout.LayoutParams(250, 400);
RelativeLayout.LayoutParams BParams = new RelativeLayout.LayoutParams(RLwrapContent, RLwrapContent);
RelativeLayout.LayoutParams RLParams = new RelativeLayout.LayoutParams(RLMatchParent, RLMatchParent);
TVParams.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
TVParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
IVParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
IVParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
BParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
BParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
if (folder.exists()) {
String[] files = folder.list();
relationsIdMarket = new ArrayList<RelationsIdMarket>(files.length);
for (int i = 0; i < files.length; i++){
RLParams.setMargins(i == 0?150:0, 0, 0, 0);//here i set on first iteration left margin 150
RelationsIdMarket rim = new RelationsIdMarket();
rim.idProduct = i;
rim.idTextView = ViewIdGenerator.generateViewId();
rim.idImageView = ViewIdGenerator.generateViewId();
rim.idButton = ViewIdGenerator.generateViewId();
TextView tv = new TextView(this);
tv.setText("name");
tv.setId(rim.idTextView);
ImageView iv = new ImageView(this);
if(GeneralData.images.size() == i)
GeneralData.images.add(BitmapFactory.decodeFile(pathToImg+"/"+files[i]));
iv.setImageBitmap(GeneralData.images.get(i));
iv.setId(rim.idImageView);
iv.setImageBitmap(rp.bmp);
Button btn = new Button(this);
btn.setText("open");
btn.setOnClickListener(this);
btn.setId(rim.idButton);
RelativeLayout rl = new RelativeLayout(this);
rl.addView(tv, TVParams);
rl.addView(iv, IVParams);
rl.addView(btn, BParams);
rl.setPadding(50, 0, 50, 0);
market_ll.addView(rl, RLParams);
relationsIdMarket.add(rim);
}
}
But I haven't been able to get this working. Any help is appreciated.
I am corrected my code as follows:
ViewGroup.MarginLayoutParams mlp = new ViewGroup.MarginLayoutParams(RLMatchParent, RLMatchParent);
if (folder.exists()) {
String[] files = folder.list();
relationsIdMarket = new ArrayList<RelationsIdMarket>(files.length);
for (int i = 0; i < files.length; i++){
mlp.leftMargin = i==0?100:0;
RelationsIdMarket rim = new RelationsIdMarket();
rim.idProduct = i;
rim.idTextView = ViewIdGenerator.generateViewId();
rim.idImageView = ViewIdGenerator.generateViewId();
rim.idButton = ViewIdGenerator.generateViewId();
TextView tv = new TextView(this);
tv.setText("Название");
tv.setId(rim.idTextView);
ImageView iv = new ImageView(this);
if(GeneralData.images.size() == i)
GeneralData.images.add(BitmapFactory.decodeFile(pathToImg+"/"+files[i]));
iv.setImageBitmap(GeneralData.images.get(i));
iv.setId(rim.idImageView);
iv.setImageBitmap(rp.bmp);
Button btn = new Button(this);
btn.setText("Открыть");
btn.setOnClickListener(this);
btn.setId(rim.idButton);
RelativeLayout rl = new RelativeLayout(this);
rl.addView(tv, TVParams);
rl.addView(iv, IVParams);
rl.addView(btn, BParams);
rl.setPadding(50, 0, 50, 0);
market_ll.addView(rl, mlp);
relationsIdMarket.add(rim);
}
}
But The problem is not solved.
Use android:layout_marginLeft within your first linear layout.
Android RelativeLayout inherits from android.view.ViewGroup.MarginLayoutParams which provides methods to set margins for layouts.
Ref Source
I am new in java and android programing. I want to add rows(include some text box) to table layout by code and delete some of them.and finaly get their text box valus.how can i do it?
Here is a simple example to do what you want:
Layout:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/table"
android:layout_width="match_parent"
android:layout_height="match_parent">
</TableLayout>
Activity:
public class TableLayoutActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.table_layout);
final TableLayout tableLayout = (TableLayout) findViewById(R.id.table);
for (int i = 0; i < 5; i++) {
// Creation row
final TableRow tableRow = new TableRow(this);
tableRow.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT));
// Creation textView
final TextView text = new TextView(this);
text.setText("Test" + i);
text.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
// Creation button
final Button button = new Button(this);
button.setText("Delete");
button.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final TableRow parent = (TableRow) v.getParent();
tableLayout.removeView(parent);
}
});
tableRow.addView(text);
tableRow.addView(button);
tableLayout.addView(tableRow);
}
}
}
I recently got the same problem. I fixed it like this.
Suppose your TableLayout is called table and als has this id in the xml layout.
<TableLayout
android:id="#+id/table"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
Suppose you have a list of Person objects, this is the way to populate the table:
ArrayList<Person> persons = getPersonList(); // --> suppose getting the list from this function
TableLayout table = (TableLayout) findViewById(R.id.table);
for(Person person : persons) {
TableRow row = new TableRow(this);
TextView tvName = new TextView(this);
TextView tvAge = new TextView(this);
TextView tvMail = new TextView(this);
tvName.setText(person.getName());
tvAge.setText(String.valueOf(person.getAge());
tvMail.setText(person.getMail());
row.addView(tvName);
row.addView(tvAge);
row.addView(tvMail);
table.addView(row);
}
This basically means that each person has its own row. For every property of your person, 1 column is used.
Regards