【android】第一个简单的轮子(多图展示控件--ImageViewGroup)

做android开发已经有一段时间了,看了很多别人写的控件,也用了很多别人的东西,总是希望自己也能写出一些好用的东西,终于开始了自己的第一次尝试。

多图展示控件是很常见的控件,像微信朋友圈、qq空间说说等。大家可能有会觉得这个东西很简单,用一个不可滑动gridVIew就可以实现了,没必要重新写一个。

之前也用不可滑动gridView实现过类似的效果,但是使用过程中存在一些问题:

1、item之间的间距在不同手机上,适配可能出现问题。

2、gridView的点击事件把没有图片的地方的点击事件拦截了,导致点击空白处跳转无反应

3、我懒得去写gridView的adapter。


废话不多说了,贴上代码。

public class ImageViewGroup extends LinearLayout implements View.OnClickListener {
    //存图片得数组
    private String[] imageArray;
    //每行的item个数,默认为3
    private int columnSize = 3;
    //默认间距,默认为2dp
    private int SPACING = 2;
    //默认宽度为270dp
    private int viewWith = 270;
    
    //使用了imageloader来加载图片
    private ImageLoader imageLoader = ImageLoader.getInstance();

    //    需要加载的最大图片数
    private int maxNum;
    private OnItemClickListener onItemClickListener;

    public ImageViewGroup(Context context) {
        super(context);
        initBase();
    }

    public ImageViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
        initBase();
    }

    public ImageViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initBase();
    }

//    设置每行图片的个数

    public void setColumnSize(int size) {
        this.columnSize = size;
    }

//    设置上下和左右的间距

    public void setSpacing(int spacing) {
        this.SPACING = DensityTool.px2dip(getContext(), spacing);
    }

//    设置view的宽度

    public void setWidth(int width) {
        this.viewWith = DensityTool.px2dip(getContext(), width);
    }

//    设置显示的最大图片数

    public void setMaxSize(int maxNum) {
        this.maxNum = maxNum;
    }

//    2种添加图片的方法,可以添加列表,数组类型

    public void setImages(List imageList) {
        if (imageList != null && imageList.size() > 0) {
            setVisibility(VISIBLE);
            imageArray = new String[imageList.size()];
            for (int i = 0; i < imageList.size(); i++) {
                imageArray[i] = imageList.get(i);
            }
            initImages(imageArray);
        } else {
            setVisibility(GONE);
        }
    }

    public void setImages(String[] imageArray) {
        if (imageArray != null && imageArray.length > 0) {
            setVisibility(VISIBLE);
            this.imageArray = imageArray;
            initImages(imageArray);
        } else {
            setVisibility(GONE);
        }
    }

//    加载view的大小

    private void initBase() {
        setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        setOrientation(VERTICAL);
        setBackgroundColor(getResources().getColor(R.color.white));
    }

//    加载Images

    private void initImages(String[] imageArray) {
//        检查是否设置了最大图片数量
        imageArray = dealPic(imageArray);
//        item的大小
        int itemSize = (viewWith - SPACING * (columnSize - 1)) / columnSize;
        List imageViews = new ArrayList<>();
        //在添加imageview之前需清除之前的view
        removeAllViews();
        for (int i = 0; i < imageArray.length / columnSize + 1; i++) {
            LinearLayout linearLayout = new LinearLayout(getContext());
            if (i > 0) {
                linearLayout.setPadding(0, DensityTool.dip2px(getContext(), SPACING), 0, 0);
            } else {
                linearLayout.setPadding(0, 0, 0, 0);
            }
            linearLayout.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            linearLayout.setOrientation(HORIZONTAL);
            addView(linearLayout);
            int length = columnSize > imageArray.length - i * columnSize ? imageArray.length - i * columnSize : columnSize;
            for (int j = 0; j < length; j++) {
                ImageView imageView = new ImageView(getContext());
                imageView.setId(j + i * columnSize);
                imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                imageView.setOnClickListener(this);
                imageViews.add(imageView);
                LayoutParams layoutParams = new LayoutParams(DensityTool.dip2px(getContext(), itemSize), DensityTool.dip2px(getContext(), itemSize));
                layoutParams.setMargins(0, 0, DensityTool.dip2px(getContext(), SPACING), 0);
                linearLayout.addView(imageView, layoutParams);
            }
        }
        loadImages(imageViews);
    }

    private void loadImages(List imageViews) {
        if (imageViews == null || imageViews.size() == 0) {
            return;
        }
        for (int i = 0; i < imageViews.size(); i++) {
            if (i >= imageArray.length) {
                break;
            }
            imageLoader.displayImage(imageArray[i], imageViews.get(i));
        }
    }

    //处理设置了最大显示图片的情况
    private String[] dealPic(String[] images) {
        if (maxNum != 0 && images.length > maxNum) {
            String[] pics = new String[maxNum];
            System.arraycopy(images, 0, pics, 0, maxNum);
            return pics;
        }
        return images;
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();
        if (onItemClickListener != null) {
            onItemClickListener.onItemListener(id);
        }
    }

//    item点击事件监听

    public interface OnItemClickListener {
        void onItemListener(int index);
    }

    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
}

 
  
思路很简单,一个纵向的LinearLayout中包含几个横向的LinearLayout,根据添加的图片数量,为每个横向的LinearLayout中添加若干个ImageView,将添加的imageView加入一个List中,最后通过ImageLoader加载出图片。可以设置 每行图片的个数、间距大小、view的宽度、最大显示图片张数

需要注意的几个问题:

1、在linearLayout中添加ImageView的时候注意不要超过图片张数,否则会出现数组越界,在loadImages方法中也进行了越界判断,防止崩溃。

2、在每次添加横向的linearLayout时记得remove所有的view,避免出现view的多次显示。

3、点击事件是通过图片位置作为图片id,再通过view.getId获取ImageView的位置,也可以通过tag进行获取。


补充:DensityTool工具类可以参考之前转得文章,简单的dp和px的转换方法。

第一次写博客,写的不太好,代码的质量也不高,希望大家能够提出意见、多多交流,谢谢。


你可能感兴趣的:(android)