Hi I am studying android.
I make mine sweeper game now.
Getting the level info of game from the user, I try creating views dynamically in android for the first time.
When I click the button "READY", buttons are created dynamically.
When an easy game is selected, 60 buttons, when intermediate, 81 buttons, and when difficult, 135 buttons are created.
But the activity stops really frequently.
I want to know more reliable way to make views.
Here is code to create them. Thanks a lot
public void makeMineFarm(int level) {
int rowNum = EASY_ROW;
int colNum = EASY_COLUMN;
switch (level) {
case 1:
break;
case 2:
rowNum = MEDIUM_ROW;
colNum = MEDIUM_COLUMN;
break;
case 3:
rowNum = DIFFICULT_ROW;
colNum = DIFFICULT_COLUMN;
break;
}
tableRow = new TableRow[rowNum];
buttons = new MineButton[rowNum][colNum];
int[] valArr = getMineValue(rowNum, colNum);
for (int i = 0; i < rowNum; i++) {
tableRow[i] = new TableRow(this);
TableRow.LayoutParams layoutParams = new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
tableRow[i].setLayoutParams(layoutParams);
for (int j = 0; j < colNum; j++) {
buttons[i][j] = new MineButton(this);
TableRow.LayoutParams lp = new TableRow.LayoutParams();
lp.width = 120;
lp.height = 120;
lp.setMargins(-5, -5, -5, -5);
buttons[i][j].setLayoutParams(lp);
buttons[i][j].setTextSize(18);
if (valArr[colNum * i + j] == -1) {
buttons[i][j].setValue("#");
} else {
buttons[i][j].setValue(Integer.toString(valArr[colNum * i + j]));
}
buttons[i][j].setOnClickListener(new OnMineButtonClickListener(this, buttons[i][j]));
tableRow[i].addView(buttons[i][j]);
}
tableLayout.addView(tableRow[i]);
}
}
Related
I working on a table feature right now and I don't know how to change the oriƫntation of a table.
This is my horizontal view, this is what I expect for the horizontal view:
And my code for the horizontal view.:
private void setupTable() {
setStretchAllColumns(true);
setBackground(borderDrawable(mTableBorderWidth));
setPadding(mTableBorderWidth, mTableBorderWidth, mTableBorderWidth, mTableBorderWidth);
for (int currentRow = 0; currentRow <= 1; currentRow++) {
tableRow = new TableRow(mContext);
if (currentRow == 0) {
for (int h = 0; h < tableData.field_options.options.size(); h++) {
textView = new TextView(mContext);
textView.setTextColor(mTextColor);
textView.setBackground(borderDrawable(mTextViewBorderWidth));
textView.setText(tableData.field_options.options.get(h).label);
textView.setGravity(Gravity.CENTER);
textView.setPadding(0, 6, 0, 6);
textView.setTypeface(Typeface.DEFAULT_BOLD);
tableRow.addView(textView);
}
} else {
for (int currentColumn = 0; currentColumn < tableData.field_options.options.size(); currentColumn++) {
editText = new EditText(mContext);
editText.setTextColor(mTextColor);
editText.setBackground(borderDrawable(mTextViewBorderWidth));
editText.setGravity(Gravity.CENTER);
editText.setPadding(0, 6, 0, 6);
tableRow.addView(editText);
}
}
addView(tableRow);
}
}
And this is my vertical view right now:
My code of the vertical table. I set the orientation here with Linear.Vertical but it doesn't help:
private void setupVerticalTable() {
setStretchAllColumns(true);
setOrientation(LinearLayout.VERTICAL);
setBackground(borderDrawable(mTableBorderWidth));
setPadding(mTableBorderWidth, mTableBorderWidth, mTableBorderWidth, mTableBorderWidth);
for (int h = 0; h < tableData.field_options.options.size(); h++) {
tableRow = new TableRow(mContext);
textView = new TextView(mContext);
textView.setTextColor(mTextColor);
textView.setBackground(borderDrawable(mTextViewBorderWidth));
textView.setText(tableData.field_options.options.get(h).label);
textView.setGravity(Gravity.CENTER);
textView.setPadding(0, 6, 0, 6);
textView.setTypeface(Typeface.DEFAULT_BOLD);
tableRow.addView(textView);
addView(tableRow);
}
for (int currentColumn = 0; currentColumn < tableData.field_options.options.size(); currentColumn++) {
editText = new EditText(mContext);
tableRow = new TableRow(mContext);
editText.setTextColor(mTextColor);
editText.setBackground(borderDrawable(mTextViewBorderWidth));
editText.setGravity(Gravity.CENTER);
editText.setPadding(0, 6, 0, 6);
tableRow.addView(editText);
addView(tableRow);
}
}
And what I want is this:
I hope someone can help me to solve this view. I don't know how to solve this problem. I tried a lot.
I think changing these 2 tables programmatically is your problem, this is of course not the wrong way but probably harder way. You can prepare 2 tables in your XML file. One table is for portrait mode, vertical table. Other one is for landscape mode, horizontal table. You can work much more easily with this way. You can check the phone orientation and make visible the desired table, make gone the other table runtime. Or you can prepare 2 separate layouts also for portrait mode and landscape mode also.
I am making an app where i need to display a seat layout containing 900 to 1200 seats. I had managed to generate a 900 seat layout by creating LinearLayouts with customized TextViews programatically by looping. But I'm pretty sure that is definitely not the way to do it.
Here is what I was doing:
// Seat Layout
LinearLayout linearLayoutSeatContainer;
static final LinearLayout[] rows = new LinearLayout[30];
static final TextView[][] seats = new TextView[30][30];
static final View[][] spaceVertical = new View[30][4];
static final View[] spaceHorizontal = new View[4];
// Populating the screen with seats
for (int i = 0; i < 30; i++) {
rows[i] = new LinearLayout(this);
rows[i].setOrientation(LinearLayout.HORIZONTAL);
// Each loop creates a row of seats
for (int j = 0; j < 30; j++) {
// To add horizontal space after every 10 seats
if (j % 10 == 0) {
spaceVertical[i][(j / 10)] = new View(this);
spaceVertical[i][(j / 10)].setLayoutParams(spaceVerticalParams);
rows[i].addView(spaceVertical[i][(j / 10)]);
}
seats[i][j] = new TextView(this);
seats[i][j].setId(i * 100 + j);
seats[i][j].setLayoutParams(textViewParams);
seats[i][j].setBackgroundResource(R.drawable.seat_circle_empty);
seats[i][j].setClickable(true);
seats[i][j].setOnClickListener(this);
// TODO: Delete randomized code for disabled seats
Random rand = new Random();
int num = rand.nextInt(20);
if (num % 5 == 0 && (i != 0 && j != 0))
seats[i][j].setEnabled(false);
rows[i].addView(seats[i][j]);
}
// Adding the last vertical space between screen and the last seat
spaceVertical[i][3] = new View(this);
spaceVertical[i][3].setLayoutParams(spaceVerticalParams);
rows[i].addView(spaceVertical[i][3]);
// To add horizontal space after every 10 rows of seats
if (i % 10 == 0) {
spaceHorizontal[i / 10] = new View(this);
spaceHorizontal[i / 10].setLayoutParams(spaceHorizontalParams);
linearLayoutSeatContainer.addView(spaceHorizontal[i / 10]);
}
linearLayoutSeatContainer.addView(rows[i]);
}
// Adding the last horizontal space between screen and the last row
spaceHorizontal[3] = new View(this);
spaceHorizontal[3].setLayoutParams(spaceHorizontalParams);
linearLayoutSeatContainer.addView(spaceHorizontal[3]);
Please ignore that bit with the randomization, that was for testing purposes. I know this is not the way of doing things. Please point me towards the right direction.
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
}
}
Im creating several buttons by using this function:
private void setlayout(Integer numbers_of_buttons){
// creating LinearLayout
LinearLayout linLayout = new LinearLayout(this);
// creating LayoutParams
LinearLayout.LayoutParams linLayoutParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
// set LinearLayout as a root element of the screen
setContentView(linLayout, linLayoutParam);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
Button[] butArray = new Button[numbers_of_buttons];
for (int i = 0; i < numbers_of_buttons; i++)
{
butArray[i] = new Button(this);
butArray[i].setLayoutParams(params);
RelativeLayout.LayoutParams Btnparams = (RelativeLayout.LayoutParams) butArray[i].getLayoutParams();
butArray[i].setText("i ... " + i);
butArray[i].setId(i); // Setting the ids
butArray[i].setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_launcher, 0, 0);
butArray[i].setBackgroundColor(Color.TRANSPARENT);
if (i != 0) {
Btnparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, butArray[i -1].getId());
}
butArray[i].setOnClickListener(listener);
linLayout.addView(butArray[i], Btnparams);
}
}
Which is called when I click something in my NavigationDrawer and the parameter: numbers_of_buttons is retrieved by some query done in the sqlite database.
My only issues is that if numbers_of_buttons is > 7 i.e. (25) i can see only 7 of them.
This is because my scrren width is 720pixel (Nexus7).
So how am I suppose to handle this ?
My idea is
- calculate the widthness of the screen
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
System.out.println("DisplayWidth -> " + metrics.widthPixels);
if getLeft() of last button create is > screenwidth than go to next row.
Can't find a way to do the second pseudocode.
EDIT - 1
private void setlayout(Integer numbers_of_buttons){
FlowLayout flowLayout = new FlowLayout(this);
setContentView(flowLayout);
Button[] butArray = new Button[numbers_of_buttons];
for (int i = 0; i < numbers_of_buttons; i++)
{
butArray[i] = new Button(this);
butArray[i].setText("i ... " + i);
butArray[i].setId(i);
butArray[i].setCompoundDrawablesWithIntrinsicBounds(0, R.mipmap.ic_launcher, 0, 0);
butArray[i].setBackgroundColor(Color.TRANSPARENT);
butArray[i].setOnClickListener(listener);
flowLayout.addView(butArray[i]);
}
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.
}
});
}
}