NineGridView icon indicating copy to clipboard operation
NineGridView copied to clipboard

测量有问题,不能添加 padding,修改 onMeasure 和onLayout如下

Open w4lle opened this issue 10 years ago • 2 comments

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
    int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
    totalWidth = sizeWidth - getPaddingLeft() - getPaddingRight();
    if (listData != null && listData.size() > 0) {
        int measureWidth, measureHeight;
        int childrenCount = listData.size();
        if (childrenCount == 1) {
            if (!isSmallScreen) {
                singleWidth = ((Photo) listData.get(0)).preview_width;
                singleHeight = ((Photo) listData.get(0)).preview_height;
            } else {
                singleWidth = defaultWidth;
                singleHeight = defaultHeight;
            }
        } else {
            singleWidth = (totalWidth - gap * (3 - 1)) / 3;
            singleHeight = singleWidth;
        }
        measureChildren(MeasureSpec.makeMeasureSpec(singleWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(singleHeight, MeasureSpec.EXACTLY));
        measureWidth = singleWidth * columns + gap * (columns - 1);
        measureHeight = singleHeight * rows + gap * (rows - 1);
        setMeasuredDimension(sizeWidth, measureHeight);
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    layoutChildrenView();
}

private void layoutChildrenView() {
    int childrenCount = listData.size();
    for (int i = 0; i < childrenCount; i++) {
        int[] position = findPosition(i);
        int left = (singleWidth + gap) * position[1] + getPaddingLeft();
        int top = (singleHeight + gap) * position[0] + getPaddingTop();
        int right = left + singleWidth;
        int bottom = top + singleHeight;
        NineGridImageView childrenView = (NineGridImageView) getChildAt(i);
        if (childrenCount == 1) {
            //只有一张图片
            childrenView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        } else {
            childrenView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        }
        Photo photo = (Photo) listData.get(i);
        if (photo != null) {
            String imageUrl = isSmallScreen ? photo.small_url : photo.middle_url;
            childrenView.setImageUrl(imageUrl);
        }

        final int itemPosition = i;
        childrenView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListerner != null) {
                    onItemClickListerner.onItemClick(v, itemPosition);
                }
            }
        });
        childrenView.layout(left, top, right, bottom);
    }
}

w4lle avatar Jun 29 '15 06:06 w4lle

您好,能不能分享一下您修改后的代码,这个不太全,看不太明白!

weinierfei avatar Jul 01 '15 15:07 weinierfei

public class NineGridLayout extends ViewGroup { private final int ITEM_GAP = 3; /** * 图片之间的间隔 / private int gap; private int columns;// private int rows;// private List listData; private int totalWidth; int singleWidth = 0, singleHeight = 0; private int defaultWidth, defaultHeight; /* * 该布局如果左边有控件,该值为左边控件的宽度 */ private Context context; private boolean isSmallScreen = false; private OnItemClickListerner onItemClickListerner;

public NineGridLayout(Context context) {
    this(context, null);
}

public NineGridLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    gap = ViewUtils.dip2px(context, ITEM_GAP);
    isSmallScreen = DensityUtil.getDensity(context) < 2;
    defaultWidth = defaultHeight = ViewUtils.dip2px(context, 140);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
    int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
    totalWidth = sizeWidth - getPaddingLeft() - getPaddingRight();
    if (listData != null && listData.size() > 0) {
        int measureWidth, measureHeight;
        int childrenCount = listData.size();
        if (childrenCount == 1) {
            if (!isSmallScreen) {
                singleWidth = ((Photo) listData.get(0)).preview_width;
                singleHeight = ((Photo) listData.get(0)).preview_height;
            } else {
                singleWidth = defaultWidth;
                singleHeight = defaultHeight;
            }
        } else {
            singleWidth = (totalWidth - gap * (3 - 1)) / 3;
            singleHeight = singleWidth;
        }
        measureChildren(MeasureSpec.makeMeasureSpec(singleWidth, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(singleHeight, MeasureSpec.EXACTLY));
        measureWidth = singleWidth * columns + gap * (columns - 1);
        measureHeight = singleHeight * rows + gap * (rows - 1);
        setMeasuredDimension(sizeWidth, measureHeight);
    }
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    layoutChildrenView();
}

private void layoutChildrenView() {
    int childrenCount = listData.size();
    for (int i = 0; i < childrenCount; i++) {
        int[] position = findPosition(i);
        int left = (singleWidth + gap) * position[1] + getPaddingLeft();
        int top = (singleHeight + gap) * position[0] + getPaddingTop();
        int right = left + singleWidth;
        int bottom = top + singleHeight;
        NineGridImageView childrenView = (NineGridImageView) getChildAt(i);
        if (childrenCount == 1) {
            //只有一张图片
            childrenView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        } else {
            childrenView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        }
        Photo photo = (Photo) listData.get(i);
        if (photo != null) {
            String imageUrl = isSmallScreen ? photo.small_url : photo.middle_url;
            childrenView.setImageUrl(imageUrl);
        }

        final int itemPosition = i;
        childrenView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onItemClickListerner != null) {
                    onItemClickListerner.onItemClick(v, itemPosition);
                }
            }
        });
        childrenView.layout(left, top, right, bottom);
    }
}


private int[] findPosition(int childNum) {
    int[] position = new int[2];
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            if ((i * columns + j) == childNum) {
                position[0] = i;//行
                position[1] = j;//列
                break;
            }
        }
    }
    return position;
}

public int getGap() {
    return gap;
}

public void setGap(int gap) {
    this.gap = gap;
}


public void setImagesData(List<Photo> lists) {
    if (lists == null || lists.isEmpty()) {
        return;
    }
    //初始化布局形状
    generateChildrenLayout(lists.size());
    //这里做一个重用view的处理
    if (listData == null) {
        for (int i = 0; i < lists.size(); i++) {
            View itemView = generateImageView(i);
            addView(itemView, generateDefaultLayoutParams());
        }
    } else {
        //以前添加过view
        int oldViewCount = listData.size();
        int newViewCount = lists.size();
        if (oldViewCount > newViewCount) {
            removeViews(newViewCount - 1, oldViewCount - newViewCount);
        } else if (oldViewCount < newViewCount) {
            for (int i = 0; i < newViewCount - oldViewCount; i++) {
                View itemView = generateImageView(i);
                addView(itemView, generateDefaultLayoutParams());
            }
        }
    }
    listData = lists;

// layoutChildrenView(); requestLayout(); }

/**
 * 根据图片个数确定行列数量
 * 对应关系如下
 * num  row column
 * 1       1    1
 * 2       1    2
 * 3       1    3
 * 4       2    2
 * 5       2    3
 * 6       2    3
 * 7       3    3
 * 8       3    3
 * 9       3    3
 *
 * @param length
 */
private void generateChildrenLayout(int length) {
    if (length <= 3) {
        rows = 1;
        columns = length;
    } else if (length <= 6) {
        rows = 2;
        columns = 3;
        if (length == 4) {
            columns = 2;
        }
    } else {
        rows = 3;
        columns = 3;
    }
}

private View generateImageView(final int position) {
    NineGridImageView iv = new NineGridImageView(getContext());
    iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
    return iv;
}

public void setOnItemClickListerner(OnItemClickListerner onItemClickListerner) {
    this.onItemClickListerner = onItemClickListerner;
}

public interface OnItemClickListerner {
    public void onItemClick(View view, int position);
}

}

w4lle avatar Jul 02 '15 02:07 w4lle