先求一个windows版本的gif制作工具!!!

这个代码只是做了简单的选择功能,图片的压缩与展示没做。可以自己在接口的方法中去实现。

写这个自定义view的初衷是为了学习LayoutParams,参考博客:http://www.jianshu.com/p/138b...

自定义一些属性

 <declare-styleable name="PhotoSelector">
        <attr name="columns" format="integer"/>//列
        <attr name="horizontal_space" format="dimension"/>//水平分割宽度
        <attr name="vertical_space" format="dimension"/>//竖直分割宽度
    </declare-styleable>

在布局中使用

 <com.idealcn.define.view.view.PhotoSelector
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         ideal:columns="3"
         ideal:horizontal_space="3dp"
         ideal:vertical_space="3dp"
         >
         <!-- 默认添加一个添加按钮的图片 -->
        <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_suggestions_add"/>
     </com.idealcn.define.view.view.PhotoSelector>

自定义这个ViewGroup

public class PhotoSelector extends ViewGroup {
 public PhotoSelector(Context context) {
        this(context,null);
    }

    public PhotoSelector(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

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

获取默认的添加按钮

  @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //获取默认的添加按钮
        addView = getChildAt(0);
        viewList.add(addView);
    }

为添加按钮添加点击事件

 @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        addView.setOnClickListener(new View.OnClickListener(){
             @Override
            public void onClick(View v) {
                  //这里添加选择图片的代码  
            }
        });
    }

子View的测量和布局

这里要重写onMeasure和onLayout。定义ViewGroup.LayoutParams的子类来保存view的left和top的属性。

public static class PhotoParams extends LayoutParams{

        public int left,top;

        public PhotoParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public PhotoParams(int width, int height) {
            super(width, height);
        }

        public PhotoParams(LayoutParams source) {
            super(source);
        }
    }

测量时,view的宽高一致,屏幕宽度减去水平分割线的宽度,然后平分给每个view。

     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        
        int width = MeasureSpec.getSize(widthMeasureSpec);

        int childWidth = (int) ((width - horizontalSpace * columns)/columns + .5f);
        int childHeight = childWidth;

        int childCount = viewList.size();
        for (int x = 0; x < childCount; x++) {
            //这里要从保存view的集合中取出view
            View child = viewList.get(x);
           PhotoParams lp = (PhotoParams) child.getLayoutParams();
           if (lp==null) {
               lp = new PhotoParams(childWidth, childHeight);
           }

            lp.width = childWidth;
            lp.height = childHeight;
            //这里确定了view的left和top属性值,在onLayout中只需取出即可
           lp.left = x%columns * childWidth + (x%columns+1) * horizontalSpace;
           lp.top = x/columns * (childHeight + verticalSpace) + verticalSpace;
            child.setLayoutParams(lp);
        }

        if (childCount<=columns)
            setMeasuredDimension(childWidth*childCount,childHeight);
        else {
            int heightCount = childCount%columns!=0?(childCount/columns+1):childCount/columns;
            setMeasuredDimension(childWidth*columns,childHeight*heightCount);
        }
        //测量并确定子view的大小
        measureChildren(widthMeasureSpec,heightMeasureSpec);
    }

放置子view

 @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = viewList.size();
        for (int x = 0; x < childCount; x++) {
            View child = viewList.get(x);
            PhotoParams lp = (PhotoParams) child.getLayoutParams();
            child.layout(lp.left,lp.top,lp.left + child.getMeasuredWidth() + horizontalSpace,lp.top + child.getMeasuredHeight() + verticalSpace);
        }
    }

添加图片

定义一个List集合,添加的图片存放于集合中。然后调用requestLayout()。定义一个接口,将添加图片的操作交给所在的Activity处理。

定义接口

public interface OnAddPhotoListener {
    Bitmap addByCamera();//拍照
    Bitmap addByGallery();//相册
}

所在的Activity实现接口

public class TableActivity extends AppCompatActivity implements OnAddPhotoListener {
    ...//省略一部分代码
    //只要把获取图片的操作在这里做处理即可
 @Override
    public Bitmap addByCamera() {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_round);
        return bitmap;
    }

    @Override
    public Bitmap addByGallery() {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_round);
        return bitmap;
    }
}

源码参考:https://github.com/idealcn/De...


idealcn
27 声望4 粉丝