GridView 同行item高度不一致问题

发布时间 2023-04-27 16:09:25作者: 安妍

GridView 同行item高度不一致问题

//bug 场景:item高度不一致,存在留白间隙

 

解决办法:

将GridView 添加到它本身的适配器当中,新增ViewHolder(目的是在GridView 初始化完成后,适配器方便操作GridView,直接在适配器getView方法中对converView进行操作),计算GridView高度,并设置GridView同一行的item高度保持一致。完整代码如下:

public class GridAdapter extends SimpleAdapter {
   Context mContext;
   LayoutInflater inflater;
   GridView gv;

   private ArrayList<HashMap<String, Object>> listData = new ArrayList();
/*构造方法中新增gridview,并初始化*/
   public GridAdapter(Context context, GridView gv,List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
       super(context, data, resource, from, to);
       this.mContext = context;
       inflater = LayoutInflater.from(context);
       listData = (ArrayList)data;
       this.gv = gv;
  }
   //GridView适配时调用getView方法
     @Override
   public View getView(int position, View convertView, ViewGroup parent) {
       Log.d("oy", "getViewOne");
       Holder holder;
       if (convertView==null){
           convertView = inflater.inflate(R.layout.grid_cell, null);
           holder = new Holder(convertView);
           holder.cellLabel = convertView.findViewById(R.id.cellLabel);
           holder.cellImage = convertView.findViewById(R.id.cellImage);
           convertView.setTag(holder);
           //绑定监听器,检测convertView的高度
           holder.update(); //view初始化完成后更新修改
      }else {
           holder = (Holder) convertView.getTag();
      }
       HashMap<String, Object> map = (HashMap)listData.get(position);
       holder.cellImage.setImageResource(((Integer)map.get("cellImage")).intValue());
       holder.cellLabel.setText(String.valueOf(map.get("cellLabel")));
       holder.cellLabel.setTag(convertView);
       holder.cellImage.setTag(position);

       return convertView;
  }
   
   
   //自定义View Holder内部类,解决view尚未初始化完成,无法操控的问题
       public class  Holder {
       public ImageView cellImage;
       public TextView cellLabel;

       public Holder(@NonNull View itemView) {
           cellImage = itemView.findViewById(R.id.cellImage);
           cellLabel = itemView.findViewById(R.id.cellLabel);
      }
           //main 计算GridView 对应item的高度,解决GridView 同行item不一致的问题
       public void update() {
           // 精确计算GridView的item高度
           cellImage.getViewTreeObserver().addOnGlobalLayoutListener(
                   new ViewTreeObserver.OnGlobalLayoutListener() {
                       public void onGlobalLayout() {
                           int position = (Integer) cellImage.getTag();
                           cellImage.getTag();
                           // 这里是保证同一行的item高度是相同的!!也就是同一行是齐整的 height相等
                           if (position > 0 && position % 2 == 1) {
                               View v = (View) cellLabel.getTag();
                               int height = v.getHeight();
                               Log.d("oy", "height==" + height);
                               View view = gv.getChildAt(position - 1);
                               int lastheight = view.getHeight();
                               Log.d("oy", "lastHeight==" + lastheight);
                               // 得到同一行的最后一个item和前一个item想比较,把谁的height大,就把两者中
                               // height小的item的高度设定为height较大的item的高度一致,也就是保证同一
                               // 行高度相等即可
                               if (height > lastheight) {
                                   view.setLayoutParams(new GridView.LayoutParams(
                                           GridView.LayoutParams.FILL_PARENT,
                                           height));
                              } else if (height < lastheight) {
                                   v.setLayoutParams(new GridView.LayoutParams(
                                           GridView.LayoutParams.FILL_PARENT,
                                           lastheight));
                              }
                          }
                      }
                  });
      }
  }
}