Android: GridLayout size and View.GONE behavior

I want to make GridLayout that if one of them child Visibility set to GONE , it is replaced by the next child. enter image description here

This is not a task that I myself drew to better explain.

I can make the layout work both in the number of columns and in width and all. Just the default behavior of GONE GridLayout makes the child just disappear instead of replacing it, as if it weren’t in the first place, like other layouts.

I tried a lot of things, I tried looking for SO and google, but I can't handle it. And this will be the most convenient layout for the application I'm working on. Anyway, to do this in a layout without doing this programmatically? Or maybe a combination of both?

+7
android android-gridlayout
source share
3 answers

The solution would be to use RecyclerView with the GridLayoutManager. The key is to notify the adapter of changes to deleted items using notifyItemRemoved. There are many options for customization in RecyclerViews, such as nice animation for disappearing elements, rearrangement of remaining elements on the screen, decoration of objects, etc. You can apply all these settings and additional logic around deleting items as needed for your specific problem.

Activities

 public class MainActivity extends AppCompatActivity { RecyclerView recyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); List<String> dataSet = getSampleDataSet(); recyclerView = (RecyclerView) findViewById(R.id.grid); recyclerView.setAdapter(new MyAdapter(dataSet)); recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 2)); } private List<String> getSampleDataSet() { List strings = new ArrayList(); strings.add("one"); strings.add("two"); strings.add("three"); strings.add("four"); strings.add("five"); strings.add("six"); return strings; } } 

Adapter

 public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { List<String> dataSet; public MyAdapter(List<String> dataSet) { this.dataSet = dataSet; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { TextView tileView = (TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false); MyViewHolder myViewHolder = new MyViewHolder(tileView); return myViewHolder; } @Override public void onBindViewHolder(MyViewHolder holder, final int position) { holder.view.setText(dataSet.get(position)); holder.view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { dataSet.remove(position); notifyItemRemoved(position); // this notifies the adapter about item being removed } }); } @Override public int getItemCount() { return dataSet.size(); } } class MyViewHolder extends RecyclerView.ViewHolder { TextView view; public MyViewHolder(TextView itemView) { super(itemView); view = itemView; } } 

Action layout

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/grid" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout> 

Mesh element

 <?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridItem" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/colorPrimary" android:textColor="@android:color/white" android:gravity="center" android:text="Tile"/> 

Results To: Before

After clicking on 4. On a real device, you can see a nice framework animation for this action.

After

+2
source share

Solve the same problem as:

 package ua.vsgroup.widgets; import android.content.Context; import android.support.v7.widget.GridLayout; import android.util.AttributeSet; import android.view.View; public class vsGridLayout extends GridLayout { View[] mChild = null; public vsGridLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public vsGridLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public vsGridLayout(Context context) { this(context, null); } private void arrangeElements() { mChild = new View[getChildCount()]; for (int i = 0; i < getChildCount(); i++) { mChild[i] = getChildAt(i); } removeAllViews(); for (int i = 0; i < mChild.length; i++) { if (mChild[i].getVisibility() != GONE) addView(mChild[i]); } for (int i = 0; i < mChild.length; i++) { if (mChild[i].getVisibility() == GONE) addView(mChild[i]); } } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { arrangeElements(); super.onLayout(changed, left, top, right, bottom); } } 
+3
source share

If you do not need to view the view again, you can decide to remove it from the 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; } } } 
0
source share

All Articles