Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: GridLayout size and View.GONE behaviour

I want to make a GridLayout that when one of it's children's Visibility is set to GONE, it is replaced by the next child. enter image description here

This is no assignment I drew that myself to better explain.

I can get the layout working as in number of columns and width and all. Just the default GONE behaviour of GridLayout makes the child just disappear instead of being replaced as if it wasn't there in the first place, like other layouts work.

I did try a lot of stuff, I tried searching SO and google, but I can't seem to work this out. And this would be the most convenient layout for the app I'm working on.Is there anyway to do this in layout without having to do this programmatically?Or maybe a combination of both?

like image 295
vlatkozelka Avatar asked Nov 24 '15 20:11

vlatkozelka


2 Answers

If you don't need turn the view visible again you can solve it removing the view from GridLayout.

private void hideView(View view) {
    GridLayout gridLayout = (GridLayout) view.getParent();
    for (int i = 0; i <  gridLayout.getChildCount(); i++) {
        if (view == gridLayout.getChildAt(i)) {
            gridLayout.removeViewAt(i);
            break;
        }
    }
}
like image 111
Carlos Aires Avatar answered Oct 06 '22 17:10

Carlos Aires


Based on this answer. Thanks man.

Create your custom GridLayout widget.

package com.isolpro.pricelist.custom;    

public class RearrangingGridLayout extends GridLayout {
  private final List<View> views = new ArrayList<>();

  public RearrangingGridLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  public RearrangingGridLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public RearrangingGridLayout(Context context) {
    this(context, null);
  }

  private void arrangeElements() {
    removeAllViews();

    for (int i = 0; i < views.size(); i++) {
      if (views.get(i).getVisibility() != GONE)
        addView(views.get(i));
    }
  }

  public void saveViews() {
    for (int i = 0; i < getChildCount(); i++) {
      views.add(getChildAt(i));
    }
  }

  public void hideViewAtIndex(int index) {
    if (index >= 0 && index < views.size()) {
      views.get(index).setVisibility(GONE);
      arrangeElements();
    }
  }

  public void showViewAtIndex(int index) {
    if (index >= 0 && index < views.size()) {
      views.get(index).setVisibility(VISIBLE);
      arrangeElements();
    }
  }
}

Here is how to use it:

Save all the children of the GridLayout after it is bound (rendered), use the following code

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    RearrangingGridLayout rglPrices = findViewById(R.id.rglPrices);

    rglPrices.saveViews();
  }

Now, to hide your view

rglPrices.hideViewAtIndex(indexOfView);

Similarly, to show your view

rglPrices.showViewAtIndex(indexOfView);

And you are done!

For my project, it was essential to preserve the children's position so I went with index. You can easily modify the code to work with something else like view id, by updating the show and hide functions.

like image 29
Utsav Barnwal Avatar answered Oct 06 '22 19:10

Utsav Barnwal