To prevent it, we can call removeGlobalOnLayoutListener() (deprecated in API level 16) or removeOnGlobalLayoutListener() (for API Level >= 16) after layout.
MainActivity.java
package com.example.androidtouchview;
import com.example.androidtouchview.MyView.OnToggledListener;
import android.support.v7.app.ActionBarActivity;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.GridLayout;
import android.widget.Toast;
import android.os.Bundle;
public class MainActivity extends ActionBarActivity
implements OnToggledListener{
int numberOfGlobalLayoutCalled = 0;
MyView[] myViews;
GridLayout myGridLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myGridLayout = (GridLayout)findViewById(R.id.mygrid);
int numOfCol = myGridLayout.getColumnCount();
int numOfRow = myGridLayout.getRowCount();
myViews = new MyView[numOfCol*numOfRow];
for(int yPos=0; yPos<numOfRow; yPos++){
for(int xPos=0; xPos<numOfCol; xPos++){
MyView tView = new MyView(this, xPos, yPos);
tView.setOnToggledListener(this);
myViews[yPos*numOfCol + xPos] = tView;
myGridLayout.addView(tView);
}
}
myGridLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener(){
@Override
public void onGlobalLayout() {
final int MARGIN = 5;
int pWidth = myGridLayout.getWidth();
int pHeight = myGridLayout.getHeight();
int numOfCol = myGridLayout.getColumnCount();
int numOfRow = myGridLayout.getRowCount();
int w = pWidth/numOfCol;
int h = pHeight/numOfRow;
for(int yPos=0; yPos<numOfRow; yPos++){
for(int xPos=0; xPos<numOfCol; xPos++){
GridLayout.LayoutParams params =
(GridLayout.LayoutParams)myViews[yPos*numOfCol + xPos].getLayoutParams();
params.width = w - 2*MARGIN;
params.height = h - 2*MARGIN;
params.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);
myViews[yPos*numOfCol + xPos].setLayoutParams(params);
}
}
Toast.makeText(MainActivity.this,
"numberOfGlobalLayoutCalled = " + numberOfGlobalLayoutCalled,
Toast.LENGTH_SHORT).show();
numberOfGlobalLayoutCalled++;
//deprecated in API level 16
myGridLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//for API Level >= 16
//myGridLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}});
}
@Override
public void OnToggled(MyView v, boolean touchOn) {
//get the id string
String idString = v.getIdX() + ":" + v.getIdY();
Toast.makeText(MainActivity.this,
"Toogled:\n" +
idString + "\n" +
touchOn,
Toast.LENGTH_SHORT).show();
}
}
Hi, can you show the MYview class?
ReplyDeleteHello Andrea Petreti,
ReplyDeleteMyView.java in last post, Insert view to GridLayout dynamically, with even width and height.
Hello thanks for your help with that code, I'm having some troubles... I implemented it and it works perfect, the thing that I don't understand....
ReplyDeleteI'm wondering if I can avoid this getViewTreeObserver().addOnGlobalLayoutListener or it must be there on MainActivity to create the GridLayout? the problem is that I don't want t fill of my screen so if I put this android:layout_height="400dp" and I put GridLayout 7x7 it says :vertical constraints: y3-y0>=1749, y3-y2<=400, y2-y1<=400, y1-y0<=400 are inconsistent; permanently removing: y3-y2<=400. Also I'm having problems to get the row column I posted a question on StackOverflow, please help me... http://stackoverflow.com/questions/36061027/girdlayout-getting-row-and-column
Thanks...
the solution presented her (removing the listener at the end of onGlobalLayout() did not work for us in cases where the soft keyboard was retracting just when we were layouting, resulting in the layout not growing for the newly added space.
ReplyDeleteso the solution for us is to execute the layout adjustment when they need to, i.e. when width and/or height change; so on the second call it will exit without triggering layout changes, thus not producing an endless loop.
and if now keyboard hides, call 3 will relayout and call 4 will again just quit.
Thanks for the code!!!
ReplyDeleteIs there a possibility to toggle all grid elements with an extra Button?