web-dev-qa-db-fra.com

GridView avec deux colonnes, le premier élément s'étend sur les deux colonnes

J'ai une Imageview et une gridview ..

Ma mise en page ici ..

enter image description here

Je veux combiner ces deux vues en une seule vue de grille

ma question:

Comment définir les portées du premier élément gridview dans les deux colonnes?

26
AndroidDev

En recherchant votre question, j'ai appris quelque chose de nouveau: il m'est arrivé de regarder GridLayoutManager pour RecyclerView et j'ai remarqué que vous pouvez définir un SpanSizeLookup personnalisé. Un "span" n'est plus qu'une colonne si vous faites défiler verticalement et une ligne si vous faites défiler horizontalement. Ainsi, le SpanSizeLookup vous permet de spécifier par exemple, l'élément 0 prend 2 colonnes, l'élément 1 prend 1 colonne, etc.

Il s'avère que si vous utilisez RecyclerView avec un GridLayoutManager la solution est simple:

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

        // Create a grid layout with two columns
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2);

        // Create a custom SpanSizeLookup where the first item spans both columns
        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return position == 0 ? 2 : 1;
            }
        });

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(new MyGridAdapter());
    }

J'ai créé un projet de test juste pour l'essayer et m'assurer qu'il a fait ce que j'attendais, et cela a fonctionné comme un charme.


Remarque sur l'adaptateur: RecyclerView.Adapter N'est pas compatible avec ListAdapter. Vous devez étendre votre adaptateur à partir de RecyclerView.Adapter Et apporter les modifications appropriées.

Voici l'adaptateur que j'ai créé pour mon projet de test:

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        ImageView mImageView;
        TextView mTextView;

        public MyViewHolder(View itemView) {
            super(itemView);
            mImageView = (ImageView) itemView.findViewById(R.id.imageView);
            mTextView = (TextView) itemView.findViewById(R.id.textView);
        }
    }

    public static class MyGridAdapter extends RecyclerView.Adapter<MyViewHolder> {

        private int[] mDrawables;

        public MyGridAdapter() {
            this.mDrawables = new int[] {
                    R.drawable.images_01,
                    R.drawable.images_02,
                    .
                    .
                    .
            };
        }

        @Override
        public int getItemCount() {
            return mDrawables.length;
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View view = inflater.inflate(R.layout.layout_grid_item, parent, false);
            MyViewHolder holder = new MyViewHolder(view);
            // set up any onClickListener you need on the view here
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {

            holder.mImageView.setImageResource(mDrawables[position]);
            holder.mTextView.setText("Image " + position);
        }
    }

Créez d'abord une sous-classe RecyclerView.ViewHolder. Le modèle de support de vue fait désormais partie intégrante de cette nouvelle façon de faire des vues d'adaptateur. Votre ViewHolder configurera toutes les vues enfant pour votre vue.

Ensuite, dans votre sous-classe RecyclerView.Adapter, Remplacez onCreateViewHolder() et onBindViewHolder(). Dans onCreateViewHolder() vous gonflez votre vue et construisez le ViewHolder. Dans onBindViewHolder(), vous utilisez position pour obtenir les données de l'adaptateur et configurer les vues enfants à l'aide de ViewHolder. Donc RecyclerView recycle techniquement ViewHolders qui contiennent Views.

Une fois que vous avez apporté ces modifications à votre adaptateur, vous devriez être prêt.

55
kris larson