I've been looking for hours on how to get all TableRow's in a TableLayout. I already know how to add and delete rows dynamically, but I need to loop over all the rows and selectively delete some of them.
I think I can come up with a work around, but I'm trying to avoid crude hacks in my app.
Have you tried using getChildCount() and getChildAt(int) respectively?
Should be fairly easy in a loop:
for(int i = 0, j = table.getChildCount(); i < j; i++) {
View view = table.getChildAt(i);
if (view instanceof TableRow) {
// then, you can remove the the row you want...
// for instance...
TableRow row = (TableRow) view;
if( something you want to check ) {
table.removeViewAt(i);
// or...
table.removeView(row);
}
}
}
if you have other type view
TableLayout layout = (TableLayout) findViewById(R.id.IdTable);
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
if (child instanceof TableRow) {
TableRow row = (TableRow) child;
for (int x = 0; x < row.getChildCount(); x++) {
View view = row.getChildAt(x);
view.setEnabled(false);
}
}
}
I have been looking for the same thing for a while. For me, I was looking to how to check views in my table layout. I did this by:
//This will iterate through your table layout and get the total amount of cells.
for(int i = 0; i < table.getChildCount(); i++)
{
//Remember that .getChildAt() method returns a View, so you would have to cast a specific control.
TableRow row = (TableRow) table.getChildAt(i);
//This will iterate through the table row.
for(int j = 0; j < row.getChildCount(); j++)
{
Button btn = (Button) row.getChildAt(j);
//Do what you need to do.
}
}
If you try to remove TableRows the ID Counter will decrease so pls use this loop for removing ... else if you dont want to remove you can use some of the loops above :D
TableLayout table = (TableLayout) findViewById(R.id.tblScores);
for(int i = 0; i < table.getChildCount(); i = 0)
{
View child = table.getChildAt(0);
if (child != null && child instanceof TableRow)
{
TableRow row = (TableRow) child;
row.removeAllViews();
table.removeViewAt(i);
}
}
This clears all rows!
I think your main problem is if you remove rows that all rows will be newly placed so that the row with the ID = 5 is now ID = 4 if you delete the row with ID = 3
so maybe you have to reset the counter and iterate again or you generate the table new after you cleared all rows
for(int i = 0, j < table.getChildCount(); i < j; i++){
// then, you can remove the the row you want...
// for instance...
TableRow row = (TableRow) table.getChildAt(i);
if( something you want to check ) {
removeViewAt(i);
// or...
removeView(row);
}
}
Related
I am creating UI layout dynamically inside the RecyclerView which causes out of memory issue when the application is used for long time.Ui being re created on scrolling up and down. How can i prevent the creation of views on scrolling? my code looks as follows.
LinearLayout container = (LinearLayout) getBaseView().findViewById(R.id.container);
container.removeAllViews();
int position = 0;
for (int i= 0; i<content.size()/2;i ++) {
LinearLayout ln = new LinearLayout(getBaseView().getContext());
ln.setWeightSum(2);
ln.setGravity(Gravity.CENTER);
for (int j = 0; j<COLUMN_COUNT; j++) {
VIOPlayListItemView tile = new VIOPlayListItemView(getBaseView().getContext());
tile.setTag(position);
tile.setGravity(Gravity.CENTER);
ln.addView(tile);
if (position <content.size()) {
tile.setData(content.get(position));
}
position ++;
}
container.addView(ln);
}
}
So I'm trying to create a GridView style layout in Android without actually using a custom Gridview adapter, since I don't want it to scroll. I've tried just turning scrolling off, but it ruins my layout since I'm adding other elements around it in a vertical LinearLayout.
My next experiment was to use a TableLayout and then just add inflated layouts as table cells, but I'm also having an issue with this. Here is a test that I am running for a brief proof of concept:
TableRow trackingActivityRow = new TableRow(getActivity());
for(int j = 0; j < trackingActivities.size(); j ++) {
TrackingActivity trackingActivity = trackingActivities.get(j);
View trackingActivityCell = getActivity().getLayoutInflater()
.inflate(R.layout.table_cell_tracking_activity, trackingActivityRow, true);
TextView txtDescription = (TextView)trackingActivityCell.findViewById(R.id.txtDescription);
txtDescription.setText(trackingActivity.getDescription());
}
tableLayout.addView(trackingActivityRow);
It seems to create the number of cells correctly, but it doesn't want to set the text like it should be. Furthermore, I'm having an issue of logic when it comes to creating a new row for every 4 TrackingActivities.
If anyone has any input it would be appreciated.
/Update/
Here is a graphic of the issue. The cell with "Walk" in it is displaying correctly, but the other cells only display the placeholder text inside the textview which should have been replaced.
I created a customized GridView based on a tablelayout with a listadapter.
Simplified version of the setAdapterMethod in the extended TableLayout:
int itemPos = -1;
int numRows = (int) Math.ceil((double) adapter.getCount() / (double) mNumColumns);
for (int yPos = 0; yPos < numRows; yPos++) {
//Create new row
TableRow tableRow = new TableRow(this.getContext());
for (int xPos = 0; xPos < mNumColumns; xPos++) {
itemPos++;
View itemView = adapter.getView(itemPos, null, tableRow);
tableRow.addView(itemView);
}
this.addView(tableRow, new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
}
I am developing an android app. I need to populate my list with images. I want to insert image in table layout row by row using array. Can you guide me how to do it? Thank you.
Use this code and make changes according to your code
TableLayout table = new TableLayout(this);
for (int i = 0; i < mRows; i++) {
TableRow tr = new TableRow(mContext);
tr.setLayoutParams(new TableRow.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
for (int j = 0; j < mCols; j++) {
ImageView view = new ImageView(this);
view.setImageResource(R.drawable.star_on)
tr.addView(view);
}
table.addView(tr);
}
Suppose in my LinearLayout (say parentLayout) there are 5 other LinearLayouts (say childLayout), where only one of them are visible at the moment. The other layouts depend on some external event to make them visible. How do I count the number of childLayout in the parentLayout that are visible ?
You can iterate over the children of the parent layout and check their visibility. Something like this:
LinearLaout parent = ...;
int childCount = parent.getChildCount();
int count = 0;
for(int i = 0; i < childCount; i++) {
if(parent.getChildAt(i).getVisibility() == View.VISIBLE) {
count++;
}
}
System.out.println("Visible children: " + count);
here is a funntion that returns number of visible childs in ViewGroup like LinearLayout, RelativeLayout, ScrollView, ..etc
private int countVisible(ViewGroup myLayout)
{
if(myLayout==null) return 0;
int count = 0;
for(int i=0;i<myLayout.getChildCount();i++)
{
if(myLayout.getChildAt(i).getVisibility()==View.VISIBLE)
count++;
}
return count;
}
If you are using Kotlin just use extention:
fun LinearLayout.visibleChildCount(): Int {
var childVisible = 0
children.iterator().forEach {
if(it.isVisible) ++childVisible
}
return childVisible
}
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.
}
});
}
}