how to convert listview to gridview

前端 未结 5 685
梦毁少年i
梦毁少年i 2021-01-02 20:04

below is my code which works fine for showing listview horizontally. how can I change it to gridvew. What changes should I make to change it to gridview? help me please

5条回答
  •  庸人自扰
    2021-01-02 20:28

    I'd suggest that you use RecyclerView intead.

    You might want to refer to the documentation and learn more about it. I'm sharing my piece of code in which I'm changing my gridview to listview using RecyclerView

    If you're using Android Studio then you might need to add dependencies in gradle build. In my case I added as follows:

    dependencies {
        .
        .
        .
        compile 'com.android.support:recyclerview-v7:24.0.0'
    }
    

    First I'm defining a grid cell which is to be used in grid layout

    recycler_cell.xml

    
    
    
    
    
    
    

    Now I'm defining a list row which is to be used in list layout

    recycler_row.xml

    
    
    
    
    
    
    

    recycler_view_test.xml And of course define a layout which would contain RecyclerView

    
    
    
    
    
    

    I'm sharing my piece of code but I'd strongly recommend that you go through the documentation and tutorials to understand RecyclerView to its full extent.

    public class RecyclerViewTest extends AppCompatActivity
    {
        final int GRID = 0;
        final int LIST = 1;
        int type;
    
        RecyclerView recyclerView;
        RecyclerView.LayoutManager gridLayoutManager, linearLayoutManager;
        MyAdapter adapter;
    
        Button btnChange;
    
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.recycler_view_test);
    
            // Display contents in views
            final List list = new ArrayList<>();
            list.add(new Person("Ariq Row 1"));
            list.add(new Person("Ariq Row 2"));
            list.add(new Person("Ariq Row 3"));
    
            // Finding views by id
            recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
            btnChange = (Button) findViewById(R.id.btnChange);
    
            // Defining Linear Layout Manager
            linearLayoutManager = new LinearLayoutManager(getApplicationContext());
            // Defining Linear Layout Manager (here, 3 column span count)
            gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);
    
            //Setting gird view as default view
            type = GRID;
            adapter = new MyAdapter(list, GRID);
            recyclerView.setLayoutManager(gridLayoutManager);
            recyclerView.setAdapter(adapter);
    
            //Setting click listener
            btnChange.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view)
                {
                    if (type == LIST)
                    {
                        // Change to grid view
                        adapter = new MyAdapter(list, GRID);
                        recyclerView.setLayoutManager(gridLayoutManager);
                        recyclerView.setAdapter(adapter);
                        type = GRID;
                    }
    
                    else
                    {
                        // Change to list view
                        adapter = new MyAdapter(list, LIST);
                        recyclerView.setLayoutManager(linearLayoutManager);
                        recyclerView.setAdapter(adapter);
                        type = LIST;
                    }
                }
            });
    
        }
    }
    
    //Defining Adapter
    class MyAdapter extends RecyclerView.Adapter
    {
        List list;
        int type;
        final int GRID = 0;
        final int LIST = 1;
    
        MyAdapter(List list, int type)
        {
            this.list = list;
            this.type = type;
        }
    
        // Inflating views if the existing layout items are not being recycled
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            View itemView;
    
            if (viewType == GRID)
            {
                // Inflate the grid cell as a view item
                itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_cell, parent, false);
            }
    
            else
            {
                // Inflate the list row as a view item
                itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_row, parent, false);
            }
    
            return new ViewHolder(itemView, viewType);
        }
    
        // Add data to your layout items
        @Override
        public void onBindViewHolder(ViewHolder holder, int position)
        {
            Person person = list.get(position);
            holder.textView.setText(person.name);
        }
    
        // Number of items
        @Override
        public int getItemCount()
        {
            return list.size();
        }
    
        // Using the variable "type" to check which layout is to be displayed
        @Override
        public int getItemViewType(int position)
        {
            if (type == GRID)
            {
                return GRID;
            }
    
            else
            {
                return LIST;
            }
        }
    
        // Defining ViewHolder inner class
        public class ViewHolder extends RecyclerView.ViewHolder
        {
            TextView textView;
            final int GRID = 0;
            final int LIST = 1;
    
            public ViewHolder(View itemView, int type)
            {
                super(itemView);
                if (type == GRID)
                {
                    textView = (TextView) itemView.findViewById(R.id.textView2);
                }
    
                else
                {
                    textView = (TextView) itemView.findViewById(R.id.textView);
                }
            }
        }
    }
    
    // Data Source Class
    class Person
    {
        String name;
    
        Person(String name)
        {
            this.name = name;
        }
    }
    

    If you end up with the issue to auto fit the number of columns in case of grid layout then you might want to check @s-marks's answer in which he extended the GridLayoutManager class and added his own patch of code, and also my fix if you start having weird column width.


    In my case, using his solution I made a class as follows:

    class GridAutofitLayoutManager extends GridLayoutManager
    {
        private int mColumnWidth;
        private boolean mColumnWidthChanged = true;
    
        public GridAutofitLayoutManager(Context context, int columnWidth)
        {
            /* Initially set spanCount to 1, will be changed automatically later. */
            super(context, 1);
            setColumnWidth(checkedColumnWidth(context, columnWidth));
        }
    
        public GridAutofitLayoutManager(Context context, int columnWidth, int orientation, boolean reverseLayout)
        {
            /* Initially set spanCount to 1, will be changed automatically later. */
            super(context, 1, orientation, reverseLayout);
            setColumnWidth(checkedColumnWidth(context, columnWidth));
        }
    
        private int checkedColumnWidth(Context context, int columnWidth)
        {
            if (columnWidth <= 0)
            {
                /* Set default columnWidth value (48dp here). It is better to move this constant
                to static constant on top, but we need context to convert it to dp, so can't really
                do so. */
                columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48,
                        context.getResources().getDisplayMetrics());
            }
    
            else
            {
                columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, columnWidth,
                        context.getResources().getDisplayMetrics());
            }
            return columnWidth;
        }
    
        public void setColumnWidth(int newColumnWidth)
        {
            if (newColumnWidth > 0 && newColumnWidth != mColumnWidth)
            {
                mColumnWidth = newColumnWidth;
                mColumnWidthChanged = true;
            }
        }
    
        @Override
        public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state)
        {
            int width = getWidth();
            int height = getHeight();
            if (mColumnWidthChanged && mColumnWidth > 0 && width > 0 && height > 0)
            {
                int totalSpace;
                if (getOrientation() == VERTICAL)
                {
                    totalSpace = width - getPaddingRight() - getPaddingLeft();
                }
                else
                {
                    totalSpace = height - getPaddingTop() - getPaddingBottom();
                }
                int spanCount = Math.max(1, totalSpace / mColumnWidth);
                setSpanCount(spanCount);
                mColumnWidthChanged = false;
            }
            super.onLayoutChildren(recycler, state);
        }
    }
    

    Then you simply have to change:

    gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);
    

    and use your custom grid layout object, here 100 is the width of columns in dp

    gridLayoutManager = new GridAutofitLayoutManager(getApplicationContext(), 100);
    

提交回复
热议问题