Android: GridLayout size and View.GONE behaviour
The solution would be to use RecyclerView along with GridLayoutManager. The key is to notify adapter about the changes to deleted items by using notifyItemRemoved. There is lots of room for customization in RecyclerViews, such as nice animations for disappearing items, rearrangement of remaining items on the screen, item decorations and etc. You can apply all these customization and additional logic around deletion of the items as needed for your particular problem.
Activity
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;
}
}
Activity 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>
Grid Item
<?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 Before:
After click on 4. On an actual device, you will be able to see a nice framework animation for this action.
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;
}
}
}