Which will be the better way to create a Vertical Lineal layout with four or more buttons in each row
The problems I have face are the following:
Setting the id of each button manually will result in a lot of repetitive code, more resources usage and you will have to change everyone to add a feature or change something (I think using an adapter will be the most efficient way, but...)
From what I know using a CustomAdapter don't help you set a unique ID to the buttons
Can you use an adapter to set a different id for each button dipending of the row?
Example:
second button of third row: r3b2
fifth button of first row: r1b5
Thanks.
You can create the buttons programmatically in our Activity class like this
LinearLayout layout = (LinearLayout) view.findViewById(R.id.layout); // the layout in which u want to display the buttons
layout.setOrientation(LinearLayout.VERTICAL);
int count = 1;
for (int i = 0; i < 5; i++) { // i = row count
LinearLayout row = new LinearLayout(getActivity());
row.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 7; j++) { // j = column count (create 7 buttons in each row)
int id = count;
final Button btnTag = new Button(getActivity());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
params.weight = 1;
params.gravity = Gravity.CENTER;
btnTag.setLayoutParams(params);
btnTag.setBackgroundColor(Color.parseColor("#ffffff"));
String dateSuffix = count + getDayNumberSuffix(count);
btnTag.setTag(dateSuffix);
btnTag.setId(id);
btnTag.setText(count + "");
btnTag.setTextSize(12.0f);
btnTag.setOnClickListener(getOnClickDoSomething(btnTag, count));
row.addView(btnTag);
count++;
}
layout.addView(row);
}
View.OnClickListener getOnClickDoSomething(final Button btnTag, final int count) {
return new View.OnClickListener() {
public void onClick(View v) {
// here you can do what u want to do on button click
}
}
Related
I need to create a table layout and add rows dynamically from Java code behind. I have already read questions here, but they are mentioning to add table rows in an already created table layout (from xml).
I need to create the table layout as well as add data to it dynamically.
Can anyone please provide some inputs?
For now, I have linear layout code in place which adds button from code behind one below the other, I need to place it under a tabular format now.
To add three buttons to TableRow use the code below
TableLayout tableLayout = new TableLayout(this);
for (int i = 0; i < 10; i++)
{
TableRow tableRow = new TableRow(this);
Button button = new Button(this);
button.setText("1");
tableRow.addView(button);
button = new Button(this);
button.setText("2");
tableRow.addView(button);
button = new Button(this);
button.setText("3");
tableRow.addView(button);
tableLayout.addView(tableRow);
}
setContentView(tableLayout);
Add the code below to your onCreate() method in you Activity class:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TableLayout tableLayout = new TableLayout(this);
for (int i = 0; i < 5; i++)
{
TableRow tableRow = new TableRow(this);
for (int j = 0; j < 3; j++)
{
Button button = new Button(this);
button.setText(""+j);
tableRow.addView(button);
}
tableLayout.addView(tableRow);
}
setContentView(tableLayout);
}
The code will add five rows with three buttons with the text 1 to 3 to the table.
Add the following code below your init() method:
for (int i = 0; i < GetGlobal.totalrow; i++) {
TableRow tbrow = new TableRow(this);
// tbrow.setLayoutParams(tableRowParams);
TextView t1v = new TextView(this);
t1v.setText(JSONParser.heading[i].replace('"', ' '));
t1v.setBackgroundResource(R.drawable.diamond_detail1);
t1v.setPadding(5, 3, 5, 3);
t1v.setMinHeight(50);
t1v.setTypeface(Typeface.SERIF);
t1v.setTextColor(Color.parseColor("#FFFFFF"));
t1v.setGravity(Gravity.FILL);
tbrow.addView(t1v);
at the moment I have a list of buttons showing up in a ScrollView however all the buttons are on the left hand side and go down in one column.
I would like these buttons to be shown in columns of 3, so 3 buttons in one row when I add row dynamically
Here is the current code I have to display these buttons
// Find the ScrollView
ScrollView scrollView = (ScrollView)
findViewById(R.id.scrollView);
// Create a LinearLayout element
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
// Add Buttons
for (int i = 0; i < 3; i++) {
linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 20; j++) {
Button button = new Button(this);
button.setText("Some text");
linearLayout.addView(button);
}
}
// Add the LinearLayout element to the ScrollView
scrollView.addView(linearLayout);
}
I tried setting layout parameters for the buttons however it didn't change anything
Any ideas?
Thanks
Try this logic
// Find the ScrollView
ScrollView scrollView = (ScrollView)findViewById(R.id.scrollView);
// Create a LinearLayout element
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
// Add Buttons
for (int i = 0; i < 20; i++) {
LinearLayout linearLayoutChild = new LinearLayout(this);
linearLayoutChild.setOrientation(LinearLayout.HORIZONTAL);
linearLayoutChild.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
for (int j = 0; j < 3; j++) {
Button button = new Button(this);
button.setText("Some text");
linearLayoutChild.addView(button);
}
linearLayout.addView(linearLayoutChild);
}
// Add the LinearLayout element to the ScrollView
scrollView.addView(linearLayout);
Unless and until it is required I will prefer GridView or RecyclerView over Dynamic view adding
I’ve been trying to create a minesweeper game in android, and so far, all has gone accordingly. However, I’m currently stuck on the part where I have to randomly place the mines within the game board.
I’ve tried a few things that I could think of, but none of which worked, except one. However, it doesn’t give me the results that I want. Here is how I am drawing the game board (using a 2D array of buttons).
final Button currentButton = new Button(this);
final int bombState = R.drawable.bomb_state;
final Button[][] buttonArray = new Button[6][6];
final int mine = R.drawable.bomb;
final Random rand = new Random();
final int number = 36;
int button;
int row;
//create new Linear Layout
RelativeLayout linearLayout = new RelativeLayout(this);
//creating the layout Params
LayoutParams linLayoutParam = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
//set layout background
linearLayout.setBackgroundDrawable(getWallpaper());
//set LinearLayout as a root element of the screen
setContentView(linearLayout, linLayoutParam);
//create a new Table Layout for the game grid
TableLayout mineGrid = new TableLayout(this);
/*
* creates TableRows and Buttons using the for loop
* then add the buttons into the rows and the rows
* into the TableLayout
*/
for(row = 0; row < 6; row++){
//create new Table Row
TableRow currentRow = new TableRow(this);
for(button = 0; button < 6; button++){
//create new Button
for(int id = 0; id < number; id++){
currentButton.setId(id);
}
currentButton.setText(" ");
//storing the buttons into the array of Buttons
buttonArray[row][button] = currentButton;
if(currentButton.isClickable()){
currentButton.setOnClickListener(new OnClickListener() {
/*
* (non-Javadoc)
* #see android.view.View.OnClickListener#onClick(android.view.View)
*/
public void onClick(View v) {
try
{
for(int i = 0; i < 10; i++){
if(rand.nextInt(10) == i){
currentButton.setBackgroundResource(mine);
restart.setBackgroundResource(bombState);
}
}
} catch(Exception e)
{
Toast.makeText(Game.this,e.getMessage() + "Error : ",
Toast.LENGTH_SHORT).show();
}
}
});
}
//store the button into the Table Row
currentRow.addView(currentButton);
}
//add the newly created row into the table
mineGrid.addView(currentRow);
}
linearLayout.addView(score, params3);
linearLayout.addView(mineGrid, params);
}
What the above code gives me, is a 6x6 grid made up of buttons.
And the following is where I’m trying to randomly place n amount of mines within the board.
try
{
for(int i = 0; i < 10; i++){
if(rand.nextInt(10) == i){
currentButton.setBackgroundResource(mine);
restart.setBackgroundResource(bombState);
}
}
}
Unfortunately, this fills the whole board with mines, instead of only placing n amount of mine on the board. I know am missing something when I try to randomly set the mines! Can anyone advise me as to where I’m going wrong and help point me in the right direction?
Please ask me anything for clarification.
Thanks in advance.
You basically, on every click of a button try to place a mine instead placing them when you create buttons. Maybe You could add to a list, id of a buttons which are mines and only check if user has clicked on one of those buttons.
ArrayList<Integer> mines = new ArrayList<Integer>();
.
.
.
currentButton.setText(" ");
if(rand.nextInt(2)==1)
mines.add(currentButton.id);
and in onClick() You check if currentButton.id is in mines list and if it is, display appropriate image.
I have a ScrollView and I want to insert a user specified number of HorizontalScrollViews. So what user says he wants to have a matrix of 5x5 elements, I want to insert 5 HorizontalScrollViews with 5 EditText objects each. My program adds the first line just as it's supposed to, but the rest not.
for (int i = 0; i < number; i++) {
LinearLayout ll = new LinearLayout(this);
ll.setLayoutParams(par2);
HorizontalScrollView row = new HorizontalScrollView(this);
row.setLayoutParams(par1);
row.addView(ll);
for (int j = 0; j < number; j++) {
EditText txt = new EditText(this);
txt.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
txt.setHint(i+","+j);
ll.addView(txt);
}
latout_in_scrollview.addView(row);
}
Any ideas why? Thanks!
EDIT:
The 1:1 code im using
LinearLayout dijkstra_rows;
FrameLayout.LayoutParams par1 = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
LinearLayout.LayoutParams par2 = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_dijkstra);
dijkstra_rows = (LinearLayout) findViewById(R.id.dijkstra_rows);
Bundle extras = getIntent().getExtras();
number = extras.getInt("vertexes");
for (int i = 0; i < number; i++) {
LinearLayout ll = new LinearLayout(this);
ll.setLayoutParams(par2);
HorizontalScrollView row = new HorizontalScrollView(this);
row.setLayoutParams(par1);
row.addView(ll);
for (int j = 0; j < number; j++) {
EditText txt = new EditText(this);
txt.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
txt.setHint(i+","+j);
ll.addView(txt);
}
dijkstra_rows.addView(row);
}
}
ScrollView can contain only one childView. You can put any layout as per your requirement. I generally use Relative Layout...
Then add views dynamically to relative layout
viewLayout = (ViewGroup) mView.findViewById(R.id.YOUR_RELATIVE_LAYOUT_ID);
View lastCard = viewLayout.getChildAt(viewLayout.getChildCount() - 1);
// INFLATE YOUR NEW VIEW YOU WANT TO ADD
CardView cardView = (CardView)
LayoutInflater.from(getContext()).inflate(R.layout.card_nearest_stop, null);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
//Set id to view
int id = 125;
if (lastCard != null) {
params.addRule(RelativeLayout.BELOW, lastCard.getId());
id = lastCard.getId() + 125;
}
cardView.setLayoutParams(params);
cardView.setId(id);
viewLayout.addView(cardView);
ScrollView is a single element container.
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.
You are adding multiple LinearLayouts here
for (int i = 0; i < number; i++) {
LinearLayout ll = new LinearLayout(this);
.
.
}
You should have only one out of this loop. Then add this one to your scrollView, in Loop you can add muliple HorizontolScrollViews to this LinearLayout
Good Morning everyone,
I'm facing yet another problem in my path of learning Android. I made a dynamic TableLayout with the content of an CSV file. I need that when I click/touch a row in the table, the color should change, and later with a click of a button get the content of the same line. Now I'm stucked with the first part and of course I have no clue about how to get the data of the row.
I declared the table inside a LinearLayout that is also inside of a ScrollView in my layout with the following properties:
<ScrollView
android:id="#+id/scrollMotors"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_marginLeft="50dp"
android:layout_marginRight="50dp"
android:layout_marginTop="90dp"
android:layout_marginBottom="50dp" >
<LinearLayout
android:id="#+id/layoutMotors"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TableLayout
android:id="#+id/tableMotors"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_vertical"
android:stretchColumns="*" >
</TableLayout>
</LinearLayout>
</ScrollView>
After in my java code, I declared the creation of the line:
//Initialization of my table
my_tableMotors = (TableLayout) findViewById(R.id.tableMotors);
//This is an ArrayList<ArrayList<String>> that contains the lines of the CSV file,
//I use this variable as a dynamic Matrix because my CSV file can change its dimensions.
m = valuesFile.size();
for (n = 0 ; n < m ; n++)
{
//Declaration and initialization of my rows
final TableRow line = new TableRow(MotorActivity.this);
//Setting the parameters of my row
line.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
line.setFocusable(true);
line.setFocusableInTouchMode(true);
line.setClickable(true);
//Initialization of my TextViews that are gonna be the content of each one of the rows in the dynamic TableLayout
myCol1 = new TextView(MotorActivity.this);
myCol2 = new TextView(MotorActivity.this);
myCol3 = new TextView(MotorActivity.this);
myCol4 = new TextView(MotorActivity.this);
j = valuesFile.get(n).size();
for (i = 0 ; i < j ; i++)
{
switch(i)
{
case 0:
if (n == 0)
{
myCol1.setText("Line");
}
else
{
myCol1.setText(valuesFile.get(n).get(i)); //Sets value for the column
}
line.addView(myCol1);
break;
case 1:
myCol2.setText(valuesFile.get(n).get(i)); //Sets value for the column
line.addView(myCol2);
break;
case 2:
myCol3.setText(valuesFile.get(n).get(i)); //Sets value for the column
line.addView(myCol3);
break;
case 3:
myCol4.setText(valuesFile.get(n).get(i)); //I use this variable for some other purpose
break;
}
}
my_tableMotors.addView(line);
}
my_tableMotors.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {onClickedRow(); }});
}
From what I've seen and read here, the best is to use a setOnClickListener and that's what I did using a bit of two different answers that I found here:
public void onClickedRow()
{
m = my_tableMotors.getChildCount();
for (n = 0 ; n < m ; n++)
{
if (my_tableMotors.getChildAt(n).hasFocus())
{
my_tableMotors.setBackgroundColor(myColor);
}
}
}
Now I can't get any focus at the tableLayout at all, so please if you see something wrong in my code or if you know how to help me with this I would appreciate it a lot!!!!
Many thanks in advance :).
EDIT 1
I found the way to get the focus. I changed the method not to the whole TableLayout but only to the TableRow, so ended up as this:
*Before*
my_tableMotors = (TableLayout) findViewById(R.id.tableMotors);
m = valuesFile.size();
for (n = 0 ; n < m ; n++)
{
//Declaration and initialization of my rows
final TableRow line = new TableRow(MotorActivity.this);
/*Other declarations*/
j = valuesFile.get(n).size();
for (i = 0 ; i < j ; i++)
{
/*Code*/
}
my_tableMotors.addView(line);
}
my_tableMotors.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {onClickedRow(); }});
}
*After*
my_tableMotors = (TableLayout) findViewById(R.id.tableMotors);
m = valuesFile.size();
for (n = 0 ; n < m ; n++)
{
//Declaration and initialization of my rows
final TableRow line = new TableRow(MotorActivity.this);
/*Other declarations*/
j = valuesFile.get(n).size();
for (i = 0 ; i < j ; i++)
{
/*Code*/
}
line.setOnClickListener(new View.OnClickListener() {public void onClick(View v) {onClickedRow(); }});
my_tableMotors.addView(line);
}
I also made the change on how to set the color of the line:
*Before*
my_tableMotors.setBackgroundColor(myColor);
*After*
my_tableMotors.getChildAt(n).setBackgroundResource(R.drawable.myColor);
Now I'm busy finding out how to get the data from the TableRow. As soon as I get that solve or an answer from you I think I have my problem solved!!!
EDIT 2
With the help of #Luksprog I could find an answer to my problem of retrieving the content!!! I did used the next code using his solution:
public void onClickedRow()
{
TableRow clickedRow = new TableRow(MotorActivity.this);
m = my_tableMotors.getChildCount();
for (n = 1 ; n < m ; n++)
{
if (my_tableMotors.getChildAt(n).isFocused())
{
my_tableMotors.getChildAt(n).setBackgroundResource(R.drawable.highlightTableRow);
clickedRow = (TableRow) my_tableMotors.getChildAt(n);
j = clickedRow.getChildCount();
for (i = 0; i < j ; i++)
{
switch(i)
{
case 0:
myField1 = (TextView) clickedRow.getChildAt(i);
break;
case 1:
myField2 = (TextView) clickedRow.getChildAt(i);
break;
case 2:
myField3 = (TextView) clickedRow.getChildAt(i);
break;
}
}
}
}
}
Don't set the OnClickListener on the TableLayout instead set it to each TableRow that you create in that for loop:
for (n = 0 ; n < m ; n++) {
//Declaration and initialization of my rows
final TableRow line = new TableRow(MotorActivity.this);
line.setOnClickListener(mListener);
line.setId(1000 + n);
// ...
where mListener is:
OnClickListener mListener = new OnClickListener() {
public void onClick(View v) {
// v is the TableRow that was clicked
v.setBackgroundColor(Color.RED);
// mClickedPosition is a int field representing the clicked row(to know the position later)
// if you allow more than one row to be clicked at one time, use a list of ints
// or something like this
mClickedPosition = v.getId() - 1000;
}
}
To later retrieve the content of the row you would use the mClickedPosition variable:
TableRow clickedRow = (TableRow) my_tableMotors.getChildAt(mClickedPosition);
// having the child TableRow that was clicked you could extract any data you want from it
// of course you could simply use the mClickedPosition to extract the data from whatever data structure you have(I'm looking at valuesFile)
You can modify the following code according to your requirement.
Here Your go:-
public void createTable() {
TableLayout table = (TableLayout) findViewById(R.id.tableMotors);
table.removeAllViewsInLayout();
List<String> namesList = new ArrayList<String>();
namesList.add("name");
namesList.add("name2");
namesList.add("name3");
// display dynamic table rows
for (int counter = 0; counter < namesList.size(); counter++) {
TableRow row = new TableRow(this);
// add the index view to the row
TextView index = new TextView(this);
index.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
index.setId(100);
index.setTextColor(Color.RED);
String indexString = String.valueOf(counter + 1);
index.setText(indexString);
// textview to display names
final TextView nameView = new TextView(this);
nameView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
nameView.setId(0);
nameView.setText(namesList.get(counter));
nameView.setTextColor(Color.RED);
RelativeLayout relativeRowContent = new RelativeLayout(this);
// set the layout params for the control to be added
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT,
android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp.setMargins(10, 0, 0, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
relativeRowContent.addView(index, rlp);
// add the divider after index
final TextView indexDivider = new TextView(this);
indexDivider.setWidth(1);
indexDivider.setId(101);
indexDivider.setHeight(80);
indexDivider.setBackgroundColor(Color.GRAY);
// display the index
rlp = new RelativeLayout.LayoutParams(
android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT,
android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp.setMargins(80, 0, 0, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
relativeRowContent.addView(indexDivider, rlp);
// set the layout params for the control to be added
rlp = new RelativeLayout.LayoutParams(
android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT,
android.widget.RelativeLayout.LayoutParams.WRAP_CONTENT);
rlp.setMargins(10, 0, 0, 0);
rlp.addRule(RelativeLayout.RIGHT_OF, indexDivider.getId());
relativeRowContent.addView(nameView, rlp);
// finally add the relative row content layout in the table row.
row.addView(relativeRowContent);
/* row.setBackgroundResource(R.drawable.row_border_light); */
// add the row to the table.
table.addView(row, new TableLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(TestActivity.this,
"" + nameView.getText().toString(),
Toast.LENGTH_SHORT).show();
// or do something more use full here.
}
});
}
}