2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 安卓自定义View(四)重叠View(灵感来自头像重叠)

安卓自定义View(四)重叠View(灵感来自头像重叠)

时间:2022-11-28 07:45:53

相关推荐

安卓自定义View(四)重叠View(灵感来自头像重叠)

最近同事需要实现如下效果的一个功能,我闲来无事就试着实现了一下,以下是具体功能的实现步骤:

功能要求:
可以水平滚动动态添加个数不定可点击 点击后变为选中色
功能实现:
自定义View

package com.light.mytext.mycustomview;import android.animation.ValueAnimator;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Color;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.bumptech.glide.Glide;import com.light.mytext.R;import com.light.mytext.utiles.DensityUtil;import java.util.ArrayList;/*** Created by HARRY on /1/18 0018.*/public class DiscussionAvatarView extends ViewGroup implements View.OnClickListener {/*** 图片的宽高*/private int mItemViewWidth;private int mItemViewHeight;/*** 头像间的距离*/private float mSpace;private Context mContext;private LayoutInflater mInflater;/*** 是否最后一个显示完全*/private boolean mIsLastComplete;/*** 最大头像数目*/private int mMaxCount;/*** 当前移动的偏移量*/private int mCurrentOffset;/*** 移动的属性动画*/private ValueAnimator animator;/*** 是否显示动画效果*/private boolean mIsShowAnimation;/*** 监听*/private boolean mIsShowFrame;private int mFrameColor;//重写点击事件private OnItemViewClickListener mOnItemClickListener = null;//点击事件//选中图片R.mipmap.anniu115private Integer[] pic = {R.mipmap.anniu5, R.mipmap.anniu511};//选中的indexprivate int ChooseIndex = 0;private ArrayList<String> listData = new ArrayList();public DiscussionAvatarView(Context context) {this(context, null);}public DiscussionAvatarView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DiscussionAvatarView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initView(context, attrs);}private void initView(Context context, AttributeSet attrs) {this.mContext = context;this.mInflater = LayoutInflater.from(mContext);TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DiscussionAvatarView);if (array != null) {mSpace = array.getFloat(R.styleable.DiscussionAvatarView_space, (float) 0.8);mMaxCount = array.getInteger(R.styleable.DiscussionAvatarView_maxCount, 6);mIsLastComplete = array.getBoolean(R.styleable.DiscussionAvatarView_isLastComplete, true);mIsShowAnimation = array.getBoolean(R.styleable.DiscussionAvatarView_isShowAnimation, true);mIsShowFrame = array.getBoolean(R.styleable.DiscussionAvatarView_isShowFrame, true);mFrameColor = array.getColor(R.styleable.DiscussionAvatarView_frameColor, Color.RED);mItemViewWidth = array.getInteger(R.styleable.DiscussionAvatarView_iviewWidth, 150);//item的宽mItemViewHeight = array.getInteger(R.styleable.DiscussionAvatarView_iviewHeight, 60);//item的高array.recycle();}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int heiMeasure = MeasureSpec.getSize(heightMeasureSpec);int heiMode = MeasureSpec.getMode(heightMeasureSpec);int widMode = MeasureSpec.getMode(widthMeasureSpec);int widMeasure = MeasureSpec.getSize(widthMeasureSpec);int wid = 0;int hei = 0;int count = getChildCount();for (int i = 0; i < count; i++) {View child = getChildAt(i);LayoutParams lp = child.getLayoutParams();lp.width = DensityUtil.dip2px(mContext, mItemViewWidth);lp.height = DensityUtil.dip2px(mContext, mItemViewHeight);child.setLayoutParams(lp);// 测量子View的宽和高,系统提供的measureChildmeasureChild(child, widthMeasureSpec, heightMeasureSpec);// 子View占据的宽度int childWidth = child.getMeasuredWidth();// 子View占据的高度int childHeight = child.getMeasuredHeight();if (i < mMaxCount) {if (i == 0) {wid = wid + childWidth;} else {wid = (int) (wid + childWidth * mSpace);}}hei = Math.max(hei, childHeight);child.setOnClickListener(this);}//如果是exactly使用测量宽和高,否则使用自己设置的宽和高setMeasuredDimension((widMode == MeasureSpec.EXACTLY) ? widMeasure : wid,(heiMode == MeasureSpec.EXACTLY) ? heiMeasure : hei);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int count = getChildCount();int left = -mCurrentOffset;int top = 0;int right = -mCurrentOffset;for (int i = count - 1; i > -1; i--) {//配合第一个元素置顶效果 数据反着放 间距也反着计算 左边叠加右边View child;child = getChildAt(i);int childWidth = child.getMeasuredWidth();int childHeight = child.getMeasuredHeight();if (i == count - 1) {right = right + childWidth;} else {right = (int) (right + childWidth * mSpace);}child.layout(left, top, right, childHeight);left = (int) (left + childWidth * mSpace);}}/*** 初始化数据** @param list*/public void initDatasList(ArrayList<String> list) {if (list == null) {return;}listData = list;initDatas();}/*** 初始化数据*/public void initDatas() {if (listData == null) {return;}removeAllViews();int size = listData.size();mMaxCount = size;for (int i = size - 1; i > -1; i--) {//反向添加 设置最左边置顶的效果View view2 = mInflater.inflate(R.layout.avatar, null);ImageView iv = (ImageView) view2.findViewById(R.id.imv_pic);TextView tv = (TextView) view2.findViewById(R.id.tv_num);tv.setText("第" + (i) + "个");if (i % 2 == 0) {tv.setTextColor(getResources().getColor(R.color.white));} else {tv.setTextColor(getResources().getColor(R.color.black));}if (ChooseIndex == i) {Glide.with(mContext).load(R.mipmap.anniu115).into(iv);tv.setTextColor(getResources().getColor(R.color.white));} else {Glide.with(mContext).load(pic[i % 2]).into(iv);}this.addView(view2);}}@Overridepublic void onClick(View view) {int count = getChildCount();for (int i = 0; i < count; i++) {if (getChildAt(i).equals(view)) {Log.i("DiscussionAvatarView==", "点击的是第" + (count - i - 1) + "个");ChooseIndex = count - i - 1;mOnItemClickListener.onViewClick(ChooseIndex);}}initDatas();}/*** 点击事件*/public interface OnItemViewClickListener {/*** 重试按钮点击*/void onViewClick(int poi);}/*** 设置重试点击事件** @param l 重试的点击事件*/public void setOnItemViewClickListener(OnItemViewClickListener l) {mOnItemClickListener = l;}}

调用方法

由于要实现水平滚动,所以结合了HorizontalScrollView使用

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><HorizontalScrollViewandroid:id="@+id/scrollview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:scrollbars="none"android:layout_gravity="left"><com.light.mytext.mycustomview.DiscussionAvatarViewandroid:id="@+id/daview"android:layout_width="wrap_content"android:layout_height="wrap_content"app:isLastComplete="true"app:isShowAnimation="false"app:isShowFrame="false"app:iviewHeight="48"app:iviewWidth="120"app:maxCount="6"app:space="0.8"></com.light.mytext.mycustomview.DiscussionAvatarView></HorizontalScrollView></LinearLayout>

Java代码实现:

package com.light.mytext.mycustomviewimport android.os.Bundleimport androidx.appcompat.app.AppCompatActivityimport com.light.mytext.Rimport com.light.mytext.utiles.ToastUtilsimport kotlinx.android.synthetic.main.activity_my_pin_jie.*import java.util.*class MyPinJieActivity : AppCompatActivity() {private val mDatas = ArrayList<String>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_my_pin_jie)initTestDatas()daview.initDatasList(mDatas)//自动滚动到最后一个item/* Timer timer=new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {scrollview.fullScroll(HorizontalScrollView.FOCUS_RIGHT);}},1000);*/daview.setOnItemViewClickListener {poi ->ToastUtils.show(this@MyPinJieActivity,"点击的是第" + poi + "个")}}private fun initTestDatas() {for (i in 0..7) {mDatas.add("")}}}

资源文件

attrs.xml

<declare-styleable name="DiscussionAvatarView"><!--头像的半径,dp为单位--><attr name="iviewWidth" format="reference|integer" /><attr name="iviewHeight" format="reference|integer" /><!--头像间的距离,为头像直径的长度的百分比,dp为单位--><attr name="space" format="reference|float" /><!--最多显示多少个头像--><attr name="maxCount" format="reference|integer" /><!--是否最后一个显示完全,默认是true--><attr name="isLastComplete" format="reference|boolean" /><!--是否显示动画效果--><attr name="isShowAnimation" format="reference|boolean" /><!--是否显示边框--><attr name="isShowFrame" format="reference|boolean" /><!--边框颜色--><attr name="frameColor" format="reference|color" /></declare-styleable>

avatar.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"><ImageViewandroid:id="@+id/imv_pic"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@mipmap/anniu5"android:scaleType="fitXY"></ImageView><TextViewandroid:id="@+id/tv_num"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="1"android:textColor="#000000"android:layout_centerInParent="true"android:textSize="15sp" /></RelativeLayout>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。