Search code examples
androidandroid-gridlayout

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

Using GridLayout, setting any child's visibility to View.Gone simply hides the view. How can I make it so it behaves like the image above?


Solution

  • 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: Before

    After click on 4. On an actual device, you will be able to see a nice framework animation for this action.

    After