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.
Related
Hi i am trying to add TextView with drawableLeft to GridLayout.
I am adding this TextView in an Loop. The TextView are getting added properly but the are not aligned properly. Each textview should take equal width in one horizontal row which is not happening.
Following is the code i am using
GridLayout gridLayout = new GridLayout(getContext());
gridLayout.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gridLayout.setColumnCount(2);
gridLayout.setRowCount(3);
TextView titleText;
for (int i = 0; facilities != null && i < facilities.size(); i++) {
titleText = new TextView(getContext());
titleText.setText(facilities.get(i));
gridLayout.addView(titleText, i);
titleText.setCompoundDrawablesWithIntrinsicBounds(rightIc, 0, 0, 0);
}
For this you have to dynamically set the column width for the views. This will finally align each view properly with equal amount of space.
GridLayout gridLayout = new GridLayout(getContext());
gridLayout.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gridLayout.setColumnCount(2);
gridLayout.setRowCount(3);
TextView titleText;
for (int i = 0; facilities != null && i < facilities.size(); i++) {
titleText = new TextView(getContext());
titleText.setText(facilities.get(i));
gridLayout.addView(titleText, i);
titleText.setCompoundDrawablesWithIntrinsicBounds(rightIc, 0, 0, 0);
GridLayout.LayoutParams param =new GridLayout.LayoutParams();
param.height = LayoutParams.WRAP_CONTENT;
param.width = LayoutParams.WRAP_CONTENT;
param.rightMargin = 5;
param.topMargin = 5;
param.setGravity(Gravity.CENTER);
param.columnSpec = GridLayout.spec(c);
param.rowSpec = GridLayout.spec(r);
titleText.setLayoutParams (param);
}
The following code sample should give each text view equal height and width, and order the TextViews left-to-right and then top-to-bottom.
The critical part is explicitly providing the GridLayout.LayoutParams, setting height/width to 0 and defining the row/column specs with weights set to 1 so that the height and width will be automatically calculated based on the weights.
Also notice I set the number of rows as a function of the number of facilities, so that if your list grows you'll have more rows.
if (facilities == null) {
// In this case there is nothing to display. You can adjust this part to your needs.
return;
}
GridLayout gridLayout = new GridLayout(getContext());
gridLayout.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gridLayout.setColumnCount(2);
gridLayout.setRowCount(facilities.size() / 2);
for (int i = 0; i < facilities.size(); i++) {
TextView titleText = new TextView(getContext());
titleText.setText(facilities.get(i));
titleText.setCompoundDrawablesWithIntrinsicBounds(rightIc, 0, 0, 0);
GridLayout.LayoutParams layoutParams = new GridLayout.LayoutParams();
layoutParams.height = 0;
layoutParams.width = 0;
int currentCol = i % 2;
int currentRow = i / 2;
// The last parameter in the specs is the weight, which gives equal size to the cells
layoutParams.columnSpec = GridLayout.spec(currentCol, 1, 1);
layoutParams.rowSpec = GridLayout.spec(currentRow, 1, 1);
// Optional, if you want the text to be centered within the cell
layoutParams.setGravity(Gravity.CENTER);
gridLayout.addView(titleText, layoutParams);
}
Basically that is the column and row count. I have re wrotten the complete logic
GridLayout gridLayout = new GridLayout(getContext());
int total = facilities.size();
int column = 2;
int row = total / column;
gridLayout.setAlignmentMode(GridLayout.ALIGN_BOUNDS);
gridLayout.setColumnCount(column);
gridLayout.setRowCount(row + 1);
TextView titleText;
for(int i =0, c = 0, r = 0; i < total; i++, c++)
{
if(c == column)
{
c = 0;
r++;
}
titleText = new TextView(getContext());
titleText.setText(facilities.get(i));
gridLayout.addView(titleText, i);
titleText.setCompoundDrawablesWithIntrinsicBounds(rightIc, 0, 0, 0);
GridLayout.LayoutParams param =new GridLayout.LayoutParams();
param.height = LayoutParams.WRAP_CONTENT;
param.width = LayoutParams.WRAP_CONTENT;
param.rightMargin = 5;
param.topMargin = 5;
param.setGravity(Gravity.CENTER);
param.columnSpec = GridLayout.spec(c);
param.rowSpec = GridLayout.spec(r);
titleText.setLayoutParams (param);
}
That's may be because of your dynamic text length is not fixed so each textview not take same space Check this
int height=getContext().getResources().getDimension(R.dimen.activity_horizontal_margin); //set size of dimen in required resolution
titleText .setLayoutParams(new LinearLayout.LayoutParams(0, height, height));
My solution:
GridLayout gl = findViewById( R.id.grid_layout );
TextView tv = new TextView( this );
tv.setText( ""+cursor.getInt( column ) ); //for example
GridLayout.LayoutParams lp = new GridLayout.LayoutParams();
lp.columnSpec = GridLayout.spec( GridLayout.UNDEFINED, 1, GridLayout.FILL ); //for stretch a child to column use GridLayout.FILL
gl.addView( tv, lp );
//DO NOT USE lp.setGravity( ... );
//FOR ALIGN TEXT USE tv.setTextAlignment( ... );
I'm trying to learn how to write Android programs, and I'm having trouble figuring out how padding works, in particular in a FrameLayout within a TableLayout.
private void fillTable(int nrows, int ncols) {
final int CENTER = 0x11; // used for "gravity" parameters
TableLayout table = (TableLayout) this.findViewById(R.id.tablelayout);
int counter = 1;
TextView text;
for (int i = 0; i < nrows; i++) {
TableRow row = new TableRow(this);
table.addView(row);
for (int j = 0; j < ncols; j++) {
View cell;
text = new TextView(this);
text.setTextColor(Color.BLUE);
text.setText(Integer.toString(counter++));
text.setGravity(CENTER);
if (i == 2 && j == 2) {
FrameLayout frame = new FrameLayout(this);
text.setLayoutParams(new FrameLayout.LayoutParams(90, 45, CENTER));
frame.setPadding(0, 0, 0, 0);
frame.addView(text);
cell = frame;
} else {
cell = text;
}
cell.setBackgroundColor((i + j) % 2 == 0 ? Color.YELLOW : Color.WHITE);
row.addView(cell);
cell.setLayoutParams(new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1F/ncols));
}
row.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 1F/nrows));
}
}
tablelayout just looks like this:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tablelayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</TableLayout>
I'm calling this with nrows=12 and ncols=5. I'm running on an emulator whose width is 720 pixels. If I change if (i==2&&j==2) to if (false), so that only an array of TextView is displayed, the columns are even, as I expect. However, with the code as written, the middle column is wider than the others.
I've also tried this adding android:stretchColumns="*" to the tablelayout definition and removing the weight parameter from cell.setLayoutParams, and the results are the same.
Assuming I have a reason to want to specify pixels for text.setLayoutParams (because of what I plan to do later), how would I get the column widths to be the same? Since 90*5 is well under 720, I don't understand why, or where, the extra width is being added.
Whenever you are dealing with weights, you must let the option take care of the remaining space. In this case width. Just set the width of each element to 0:
cell.setLayoutParams(new TableRow.LayoutParams(0, LayoutParams.MATCH_PARENT, 1F/ncols));
The title says it all.
I am making an application in which i have to add dynamic buttons in a linear layout i have tried:
testButtons = new Button[caseDetails.length()];
for (int i = 0; i < caseDetails.length(); i++) {
temp = caseDetails.getJSONObject(i);
Log.e("TEMP " + i, temp.toString());
testButtons[i] = new Button(this) ;
testButtons[i].setText("Hello Hi");
testButtons[i].setHeight(LayoutParams.WRAP_CONTENT);
testButtons[i].setWidth(LayoutParams.WRAP_CONTENT);
testButtons[i].setPadding(20, 20, 20, 20);
testLayout.addView(testButtons[i]);
}
All i can see on emulator is two buttons with no text. Why is this happening?
had the same problem.. try this..
testButtons = new Button[caseDetails.length()];
for (int i = 0; i < caseDetails.length(); i++) {
temp = caseDetails.getJSONObject(i);
testButtons[i] = new Button(this) ;
testButtons[i].setText("Hello Hi");
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
testButtons[i].setPadding(20, 20, 20, 20);
testLayout.addView(testButtons[i], lp);
}
also make sure your linearLayout's orientation is vertical. Good Luck! :)
I am creating a Android app. This Android App will have objects that are dynamic. These objects are Places with a Address or Lat/Long, and distance from current location, and a ETA. What I would like to do is add with objects on a TableLayout with borders, but I need to be able to dynamically add rows as the number of places increase.
I understand somewhat how to do this for a fixed hardcoded number of items on the xml, but what would be the best way when the number of objects is coming from the Activity.java file?
Below is a screenshot of the TableLayout I would like:
So the object would be a place with a address, distance and direction.
but I need to be able to dynamically add rows as the number of places increase.
This isn't difficult, when you have a new object append a TableRow with the data to the TableLayout.
I understand somewhat how to do this for a fixed hardcoded number of items on the xml, but what would be the best way when the number of objects is coming from the Activity.java file?
I don't think there is a best way (or what you consider best way). You either:
Insert fake views to act as dividers. This would be easier to implement visually but it will also increase the memory consumption of your app, with bad consequences if the number of rows is big. (1)
Or use drawables for the backgrounds to simulate the borders (like nine-patch images). This would be simpler then inserting additional views but you need a bit more talent to make it look well. (2)
Some examples for your image:
(1)
private static final int DIVIDER_SIZE = 2;
// rowsCount the number of rows to add to the TableLayout
private void buildOldSchool(TableLayout table, int rowsCount) {
View divider;
for (int i = 0; i < rowsCount; i++) {
TableRow row = new TableRow(this);
for (int j = 0; j < 7; j++) {
if (j % 2 == 0) {
divider = new View(this);
divider.setLayoutParams(new TableLayout.LayoutParams(
DIVIDER_SIZE, TableLayout.LayoutParams.MATCH_PARENT));
divider.setBackgroundColor(Color.GREEN);
row.addView(divider, new TableRow.LayoutParams(
DIVIDER_SIZE, TableRow.LayoutParams.MATCH_PARENT));
continue;
}
TextView tv = new TextView(this);
tv.setText("DX"); // dummy data
row.addView(tv, new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT));
}
divider = new View(this);
divider.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT, DIVIDER_SIZE));
divider.setBackgroundColor(Color.GREEN);
if (i == 0) {
table.addView(divider);
divider = new View(this);
divider.setLayoutParams(new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT, DIVIDER_SIZE));
divider.setBackgroundColor(Color.GREEN);
}
table.addView(row);
table.addView(divider);
}
}
(2) or with images:
private void buildWithDrawables(TableLayout table, int rowsCount) {
for (int i = 0; i < rowsCount; i++) {
TableRow row = new TableRow(this);
row.setBackgroundResource(i == 0 ? R.drawable.firstrow
: R.drawable.normalrow);
for (int j = 0; j < 3; j++) {
TextView tv = new TextView(this);
tv.setBackgroundResource(j == 2 ? R.drawable.extra
: R.drawable.cell);
tv.setText("DX");
row.addView(tv, new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT));
}
table.addView(row);
}
}
Where the images are:
R.drawable.cell:
R.drawable.extra (a visually transparent drawable which replicates the nine-patch above):
R.drawable.normalrow:
R.drawable.firstrow:
Ignore my design skills.
If your foresee a large number of rows I would advise you to use a ListView, which you could pretty easy make it to look like a table with borders.
Couldn't figure out the vertical line, but something you can build upon
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ScrollView sv = new ScrollView(this);
TableLayout ll=new TableLayout(this);
HorizontalScrollView hsv = new HorizontalScrollView(this);
for(int i=1;i<5;i++) {
TableRow tbrow=new TableRow(this);
for(int j=1;j<=3;j++) {
TextView tv1=new TextView(this);
tv1.setText("Element :"+ i + "" + j);
tbrow.addView(tv1);
}
ll.addView(tbrow);
View v = new View(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 5);
v.setLayoutParams(params);
v.setBackgroundColor(getResources().getColor(android.R.color.white));
ll.addView(v);
}
hsv.addView(ll);
sv.addView(hsv);
setContentView(sv);
}
I am trying to add a series of images to the current RelativeLayout at runtime below another TextView. So far, I get it to display partially correct, but not exactly right. I can't get them to move to another row. I hope someone can give me a hand and show me the correct way. The series of image will appear below this TextView(R.id.date):
TextView date = (TextView) findViewById(R.id.date);
//// image view start //////
int photos = Integer.parseInt(total_photo);
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.relative_layout_b);
for (int i = 0; i < limit; i++){
final ImageView imageView = new ImageView (this);
imageView.setId(i);
imageView.setImageResource(R.drawable.photo_frame);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
imageView.setPadding(10, 10, 0, 0);
imageView.setAdjustViewBounds(true);
imageView.setMaxHeight(80);
imageView.setMaxWidth(80);
lp.addRule(RelativeLayout.BELOW, R.id.date);
lp.addRule(RelativeLayout.RIGHT_OF, imageView.getId() - 1);
imageView.setLayoutParams(lp);
mainLayout.addView(imageView);
}
Right now, it only display total photo quantity - 1 (i.e.: when there is 5, it only display 4); and I would like to get each row to display 5 and will move to the next row immediately if it reach 6, 11, 16....etc. This layout is nested inside a ScrollView and in a RelativeLayout because I have quite a few views in it. So, I will have to stick with RelativeLayout for this.
If I understood what you're trying to do, see if the code below position the ImageViews like you want(I don't know how efficient it is):
private static final int ROW_ITEMS = 5; // 5 ImageViews per row
// ...
RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.relative_layout_b);
int limit = 13; // I assume that limit is the number of ImageView that you'll put in the layout
int rows = limit / ROW_ITEMS; // the number of rows that results from limit
int leftOver = limit % ROW_ITEMS; // see if we have incomplete rows
if (leftOver != 0) {
rows += 1;
}
int id = 1000; // the ids of the ImageViews 1000, 1001, 1002 etc
int belowId = R.id.date; // this id will be used to position the ImageView on another row
while (rows > 0) {
int realItemsPerRow = ROW_ITEMS;
if (leftOver != 0 & rows == 1) {
realItemsPerRow = Math.min(ROW_ITEMS, leftOver);
}
for (int i = 0; i < realItemsPerRow; i++) {
final ImageView imageView = new ImageView(this);
imageView.setId(id);
imageView.setImageResource(R.drawable.ic_launcher);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
imageView.setPadding(10, 10, 0, 0);
imageView.setAdjustViewBounds(true);
imageView.setMaxHeight(80);
imageView.setMaxWidth(80);
if (i == 0) {
lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
} else {
lp.addRule(RelativeLayout.RIGHT_OF, imageView.getId() - 1);
}
lp.addRule(RelativeLayout.BELOW, belowId);
imageView.setLayoutParams(lp);
mainLayout.addView(imageView);
id++;
}
belowId = id - 1;
rows--;
}
Also, as kcoppock already said in his comment, it might be worth looking at the GridView for efficiency.