一个简单的可控的头像列表叠加控件
需求:评论/点赞头像横向排列,第N个叠加在第N+1个上面,并且N小于一个固定的数
分析:1、假设N=4;头像列表最多显示4个,不足4个,有几个显示几个;2、头像第N个叠加在第N+1个上面,无法使用margin负数实现(叠加顺序不对)
1、控件实现代码
要点:控件可以横向滑动,继承HorizontalScrollView;创建RelativeLayout存放头像集合;
public class SDAvatarListLayout extends HorizontalScrollView { private Context context; /** * 存放创建的最大的ImageView集合 */ private List<SDCircleImageView> imageViewList; /** * 默认图片大小 */ private int imageSize = Math.round(SDTransitionUtil.dp2px(50)); /** * 默认图片数量 */ private int imageMaxCount = 6; /** * 默认图片偏移百分比 0~1 */ private float imageOffset = 0.3f; public SDAvatarListLayout(Context context) { this(context, null); } public SDAvatarListLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SDAvatarListLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; TypedArray ta = getResources().obtainAttributes(attrs, R.styleable.SDAvatarListLayout); imageMaxCount = ta.getInt(R.styleable.SDAvatarListLayout_image_max_count, imageMaxCount); imageSize = (int) ta.getDimension(R.styleable.SDAvatarListLayout_image_size, imageSize); imageOffset = ta.getFloat(R.styleable.SDAvatarListLayout_image_offset, imageOffset); imageOffset = imageOffset > 1 ? 1 : imageOffset; init(); ta.recycle(); } private void init() { setHorizontalScrollBarEnabled(false); RelativeLayout relativeLayout = new RelativeLayout(context); int offset = imageSize - (int) (imageSize * imageOffset); imageViewList = new ArrayList<>(imageMaxCount); for (int i = 0; i < imageMaxCount; i++) { SDCircleImageView imageView = new SDCircleImageView(context); imageView.setId(imageView.hashCode() + i); imageView.setBorderColor(Color.WHITE); imageView.setBorderWidth(Math.round(SDTransitionUtil.dp2px(1))); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageSize, imageSize); params.addRule(ALIGN_PARENT_LEFT); params.setMargins((imageMaxCount - i - 1) * offset, 0, 0, 0); relativeLayout.addView(imageView, params); imageViewList.add(imageView); } relativeLayout.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); this.addView(relativeLayout); } public void setAvatarListListener(ShowAvatarListener listener) { hideAllImageView(); listener.showImageView(imageViewList); } public void setAvatarListListener(List<Integer> drawableList) { if (drawableList == null) { return; } hideAllImageView(); int i = imageMaxCount - 1; for (int url : drawableList) { imageViewList.get(i).setImageResource(url); imageViewList.get(i).setVisibility(VISIBLE); if (i == 0) { break; } --i; } } private void hideAllImageView() { for (SDCircleImageView head : imageViewList) { head.setVisibility(View.GONE); } } public interface ShowAvatarListener { void showImageView(List<SDCircleImageView> imageViewList); } }
2、自定义属性
<declare-styleable name="SDAvatarListLayout"> <!--创建的最大ImageView数量--> <attr name="image_max_count" format="integer" /> <!--创建的ImageView的大小--> <attr name="image_size" format="dimension" /> <!--要叠加的ImageView偏移量--> <attr name="image_offset" format="float" /> </declare-styleable>
3、使用
final List<Integer> imageDatas = new ArrayList<>(); imageDatas.add(R.drawable.ic_launcher_background); imageDatas.add(R.drawable.meinv); imageDatas.add(R.drawable.meinv); imageDatas.add(R.drawable.meinv); //加载本地资源 avatarLayout1.setAvatarListListener(imageDatas); //顺序加载图片使用任意框架加载 avatarLayout2.setAvatarListListener(new SDAvatarListLayout.ShowAvatarListener() { @Override public void showImageView(List<SDCircleImageView> imageViewList) { //创建的ImageView的数量 int imageSize = imageViewList.size(); //实际需要显示的图片的数量 int realDataSize = imageDatas.size(); int mul = imageSize - realDataSize; for (int i = 0; i < imageSize; i++) { if (i >= mul) {//6 //可以替换为网络图片处理 imageViewList.get(i).setImageResource(imageDatas.get(realDataSize - (i - mul) - 1)); imageViewList.get(i).setVisibility(View.VISIBLE); } else { imageViewList.get(i).setVisibility(View.GONE); } } } }); //逆序加载图片使用任意框架加载 avatarLayout3.setAvatarListListener(new SDAvatarListLayout.ShowAvatarListener() { @Override public void showImageView(List<SDCircleImageView> imageViewList) { //创建的ImageView的数量 int imageSize = imageViewList.size(); //实际需要显示的图片的数量 int realDataSize = imageDatas.size(); int mul = imageSize - realDataSize; for (int i = 0; i < imageSize; i++) { if (i >= mul) {//6 //可以替换为网络图片处理 imageViewList.get(i).setImageResource(imageDatas.get(i - mul)); imageViewList.get(i).setVisibility(View.VISIBLE); } else { imageViewList.get(i).setVisibility(View.GONE); } } } });
### [了解更多资源收集ResourceCollection](https://github.com/SiberiaDante/ResourceCollection)