横竖屏切换时如何在自定义Adapter中调整ListView图片列数
处理横竖屏切换时Gallery样式列表的列数适配方案
嘿,这个场景我之前做过类似的需求,给你梳理几个实用的步骤,确保Adapter能完美适配横竖屏的列数变化:
一、用资源文件自动适配不同方向的列数
首先,我们利用Android的资源限定符,让系统自动根据屏幕方向加载对应的列数配置,这是最优雅的方式:
- 在
res/values/目录下创建integers.xml,定义竖屏列数:<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="gallery_column_count">2</integer> </resources> - 在
res/values-land/目录下创建同名的integers.xml,定义横屏列数:<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="gallery_column_count">3</integer> </resources>
这样横竖屏切换时,系统会自动切换对应的列数值,不用我们手动判断方向。
二、在自定义Adapter中动态计算Item尺寸
接下来,在Adapter里根据当前的列数,计算每个图片Item的宽度,保证每行刚好放下指定数量的图片:
在Adapter构造方法中初始化必要参数
public class GalleryAdapter extends BaseAdapter { private Context mContext; private List<Bitmap> mImageList; private int mColumnCount; private int mItemWidth; private int mItemSpacing; // Item之间的间距,比如16dp转成px public GalleryAdapter(Context context, List<Bitmap> imageList) { mContext = context; mImageList = imageList; // 初始化间距:把dp转成px mItemSpacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, context.getResources().getDisplayMetrics()); // 初始化列数和Item宽度 updateColumnAndItemWidth(); } // 专门的方法更新列数和Item宽度,方便横竖屏切换时调用 private void updateColumnAndItemWidth() { // 获取当前方向的列数 mColumnCount = mContext.getResources().getInteger(R.integer.gallery_column_count); // 获取屏幕宽度 DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); int screenWidth = metrics.widthPixels; // 计算每个Item的宽度:屏幕宽度减去所有间距,再平分给列数 mItemWidth = (screenWidth - (mColumnCount - 1) * mItemSpacing) / mColumnCount; } }在getView中设置Item的尺寸
在getView方法里,给图片控件设置计算好的宽度和高度(比如保持宽高比1:1):@Override public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null) { imageView = new ImageView(mContext); // 设置间距和缩放模式 imageView.setPadding(mItemSpacing/2, mItemSpacing/2, mItemSpacing/2, mItemSpacing/2); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); } else { imageView = (ImageView) convertView; } // 设置图片的LayoutParams ViewGroup.LayoutParams params = imageView.getLayoutParams(); if (params == null) { params = new ViewGroup.LayoutParams(mItemWidth, mItemWidth); } else { params.width = mItemWidth; params.height = mItemWidth; } imageView.setLayoutParams(params); // 加载图片到ImageView imageView.setImageBitmap(mImageList.get(position)); return imageView; }
三、横竖屏切换时通知Adapter更新
因为你的Fragment是保留状态的(设置了setRetainInstance(true)),横竖屏切换时Fragment不会被重建,但我们需要让Adapter重新计算列数和Item宽度:
在你的Fragment中重写onConfigurationChanged方法:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // 通知Adapter更新列数和尺寸,然后刷新列表 if (mGalleryAdapter != null) { mGalleryAdapter.updateColumnAndItemWidth(); mGalleryAdapter.notifyDataSetChanged(); } }
这样切换横竖屏时,Adapter会重新计算Item尺寸,列表也会刷新显示新的列数。
额外注意点
- 如果你的列表用的是
GridView,其实可以更简单:直接在布局文件中给GridView设置numColumns="@integer/gallery_column_count",系统会自动处理列数,不需要手动计算宽度,但如果是自定义的Gallery样式ListView,上面的方法更通用。 - 图片加载建议用Glide/Picasso等库,避免OOM,这些库也能自动根据ImageView尺寸加载合适大小的图片,提升性能。
内容的提问来源于stack exchange,提问作者giozh
相关产品推荐
相关产品推荐

