本文实例为大家分享了AndroID实现3D层叠式卡片图片展示的具体代码,供大家参考,具体内容如下
先看效果
好了效果看了,感兴趣的往下看哦!
整体实现思路
1、重写relativeLayout 实现 锁定宽高比例的 relativeLayout
2、自定义一个支持滑动的面板 继承 VIEwGroup
3、卡片VIEw绘制
4、页面中使用布局
首先为了更好的展示图片我们重写一下 relativeLayout 编写一个锁定宽高比例的 relativeLayout
autoScalerelativeLayout
public class autoScalerelativeLayout extends relativeLayout { //宽高比例 private float wIDthHeightRate = 0.35f; public autoScalerelativeLayout(Context context) { this(context,null); } public autoScalerelativeLayout(Context context,AttributeSet attrs) { this(context,attrs,0); } public autoScalerelativeLayout(Context context,AttributeSet attrs,int defStyleAttr) { super(context,defStyleAttr); //通过布局获取宽高比例 TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.card,0); wIDthHeightRate = a.getfloat(R.styleable.card_wIDthHeightRate,wIDthHeightRate); a.recycle(); } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); // 调整高度 int wIDth = getMeasureDWIDth(); int height = (int) (wIDth * wIDthHeightRate); VIEwGroup.LayoutParams lp = getLayoutParams(); lp.height = height; setLayoutParams(lp); }}
这样我们就编写好了我们想要的父布局
使用方法
<com.petterp.toos.ImageCard.autoScalerelativeLayout androID:ID="@+ID/card_top_layout" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" card:wIDthHeightRate="0.6588"><!-- wIDthHeightRate:就是设置宽高的百分比--> <ImageVIEw androID:ID="@+ID/card_image_vIEw" androID:layout_wIDth="fill_parent" androID:layout_height="match_parent" androID:scaleType="fitXY" /><!-- 这是我们展示的图片--> <VIEw androID:ID="@+ID/maskVIEw" androID:layout_wIDth="fill_parent" androID:layout_height="match_parent" androID:background="?androID:attr/selectableItemBackground" androID:clickable="true" /><!-- 这个是为了让我们图片上有波纹--></com.petterp.toos.ImageCard.autoScalerelativeLayout>
接下来就是主要布局,也就是展示图片的布局了
为了实现滑动我们编写一个支持滑动的画板
//事件处理 @OverrIDe public boolean dispatchtouchEvent(MotionEvent ev) { int action = ev.getActionMasked(); // 按下时保存坐标信息 if (action == MotionEvent.ACTION_DOWN) { this.downPoint.x = (int) ev.getX(); this.downPoint.y = (int) ev.getY(); } return super.dispatchtouchEvent(ev); } /* touch事件的拦截与处理都交给mDraghelper来处理 */ @OverrIDe public boolean onIntercepttouchEvent(MotionEvent ev) { boolean shouldIntercept = mDragHelper.shouldIntercepttouchEvent(ev); boolean moveFlag = moveDetector.ontouchEvent(ev); int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { // ACTION_DOWN的时候就对vIEw重新排序 if (mDragHelper.getVIEwDragState() == VIEwDragHelper.STATE_SETTliNG) { mDragHelper.abort(); } orderVIEwStack(); // 保存初次按下时arrowFlagVIEw的Y坐标 // action_down时就让mDragHelper开始工作,否则有时候导致异常 mDragHelper.processtouchEvent(ev); } return shouldIntercept && moveFlag; } @OverrIDe public boolean ontouchEvent(MotionEvent e) { try { // 统一交给mDragHelper处理,由DragHelperCallback实现拖动效果 // 该行代码可能会抛异常,正式发布时请将这行代码加上try catch mDragHelper.processtouchEvent(e); } catch (Exception ex) { ex.printstacktrace(); } return true; } //计算 @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { measureChildren(wIDthMeasureSpec,heightmeasureSpec); int maxWIDth = MeasureSpec.getSize(wIDthMeasureSpec); int maxHeight = MeasureSpec.getSize(heightmeasureSpec); setMeasuredDimension( resolveSizeAndState(maxWIDth,wIDthMeasureSpec,0),resolveSizeAndState(maxHeight,heightmeasureSpec,0)); allWIDth = getMeasureDWIDth(); allHeight = getMeasuredHeight(); } //定位 @OverrIDe protected voID onLayout(boolean changed,int left,int top,int right,int bottom) { // 布局卡片vIEw int size = vIEwList.size(); for (int i = 0; i < size; i++) { VIEw vIEwItem = vIEwList.get(i); int childHeight = vIEwItem.getMeasuredHeight(); int vIEwleft = (getWIDth() - vIEwItem.getMeasureDWIDth()) / 2; vIEwItem.layout(vIEwleft,itemmargintop,vIEwleft + vIEwItem.getMeasureDWIDth(),itemmargintop + childHeight); int offset = yOffsetStep * i; float scale = 1 - SCALE_STEP * i; if (i > 2) { // 备用的vIEw offset = yOffsetStep * 2; scale = 1 - SCALE_STEP * 2; } vIEwItem.offsettopAndBottom(offset); vIEwItem.setScaleX(scale); vIEwItem.setScaleY(scale); } // 布局底部按钮的VIEw if (null != bottomLayout) { int layouttop = vIEwList.get(0).getBottom() + bottommargintop; bottomLayout.layout(left,layouttop,right,layouttop + bottomLayout.getMeasuredHeight()); } // 初始化一些中间参数 initCenterVIEwX = vIEwList.get(0).getleft(); initCenterVIEwY = vIEwList.get(0).gettop(); chilDWith = vIEwList.get(0).getMeasureDWIDth(); } //onFinishInflate 当VIEw中所有的子控件均被映射成xml后触发 @OverrIDe protected voID onFinishInflate() { super.onFinishInflate(); // 渲染完成,初始化卡片vIEw列表 vIEwList.clear(); int num = getChildCount(); for (int i = num - 1; i >= 0; i--) { VIEw childVIEw = getChildAt(i); if (childVIEw.getID() == R.ID.card_bottom_layout) { bottomLayout = childVIEw; initBottomLayout(); } else { // for循环取vIEw的时候,是从外层往里取 CardItemVIEw vIEwItem = (CardItemVIEw) childVIEw; vIEwItem.setParentVIEw(this); vIEwItem.setTag(i + 1); vIEwItem.maskVIEw.setonClickListener(btnListener); vIEwList.add(vIEwItem); } } CardItemVIEw bottomCardVIEw = vIEwList.get(vIEwList.size() - 1); bottomCardVIEw.setAlpha(0); }
卡片VIEw绘制
private voID initSpring() { SpringConfig springConfig = SpringConfig.fromBouncinessAndSpeed(15,20); SpringSystem mSpringSystem = SpringSystem.create(); springX = mSpringSystem.createSpring().setSpringConfig(springConfig); springY = mSpringSystem.createSpring().setSpringConfig(springConfig); springX.addListener(new SimpleSpringListener() { @OverrIDe public voID onspringUpdate(Spring spring) { int xPos = (int) spring.getCurrentValue(); setScreenX(xPos); parentVIEw.onVIEwPosChanged(CardItemVIEw.this); } }); springY.addListener(new SimpleSpringListener() { @OverrIDe public voID onspringUpdate(Spring spring) { int yPos = (int) spring.getCurrentValue(); setScreenY(yPos); parentVIEw.onVIEwPosChanged(CardItemVIEw.this); } }); } //装载数据 public voID fillData(CardDataItem itemData) { GlIDe.with(getContext()).load(itemData.imagePath).into(imageVIEw); } /** * 动画移动到某个位置 */ public voID animTo(int xPos,int yPos) { setCurrentSpringPos(getleft(),gettop()); springX.setEndValue(xPos); springY.setEndValue(yPos); } /** * 设置当前spring位置 */ private voID setCurrentSpringPos(int xPos,int yPos) { springX.setCurrentValue(xPos); springY.setCurrentValue(yPos); }
接下来我们需要使用它 编写Fragment布局
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" xmlns:card="http://schemas.androID.com/apk/res-auto" androID:background="#fff" androID:orIEntation="vertical"> <com.petterp.toos.ImageCard.CardSlIDePanel androID:ID="@+ID/image_slIDe_panel" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" card:bottommargintop="38dp" card:itemmargintop="10dp" card:yOffsetStep="26dp"> <linearLayout androID:ID="@+ID/card_bottom_layout" androID:layout_wIDth="fill_parent" androID:layout_height="wrap_content" androID:gravity="center" androID:orIEntation="horizontal"> <button androID:background="#03A9F4" androID:text="右侧移除" androID:ID="@+ID/card_left_btn" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" /> <button androID:background="#03A9F4" androID:text="右侧移除" androID:ID="@+ID/card_right_btn" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_marginleft="10dp" /> </linearLayout> <com.petterp.toos.ImageCard.CardItemVIEw androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" /> <com.petterp.toos.ImageCard.CardItemVIEw androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" /> <com.petterp.toos.ImageCard.CardItemVIEw androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" /> <com.petterp.toos.ImageCard.CardItemVIEw androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" /> </com.petterp.toos.ImageCard.CardSlIDePanel></linearLayout>
代码中的使用
private voID initVIEw(VIEw rootVIEw) { CardSlIDePanel slIDePanel = (CardSlIDePanel) rootVIEw .findVIEwByID(R.ID.image_slIDe_panel); cardSwitchListener = new CardSlIDePanel.CardSwitchListener() { @OverrIDe public voID onShow(int index) { Toast.makeText(getContext(),"CardFragment"+"正在显示=" +index,Toast.LENGTH_SHORT).show(); } //type 0=右边 ,-1=左边 @OverrIDe public voID onCardVanish(int index,int type) { Toast.makeText(getContext(),"CardFragment"+ "正在消失=" + index + " 消失type=" + type,Toast.LENGTH_SHORT).show(); } @OverrIDe public voID onItemClick(VIEw cardVIEw,int index) { Toast.makeText(getContext(),"CardFragment"+"卡片点击=" + index,Toast.LENGTH_SHORT).show(); } }; slIDePanel.setCardSwitchListener(cardSwitchListener); prepareDataList(); slIDePanel.fillData(dataList); } //封装数据 private voID prepareDataList() { int num = imagePaths.length; //重复添加数据10次(测试数据太少) for (int j = 0; j < 10; j++) { for (int i = 0; i < num; i++) { CardDataItem dataItem = new CardDataItem(); dataItem.imagePath = imagePaths[i]; dataList.add(dataItem); } } }
到此主要逻辑代码就编写完了
详细说明代码中已经注释 ,全部代码请看源码
源码:github源码
源码中的TestCardFragment 为使用模板
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
总结以上是内存溢出为你收集整理的Android实现3D层叠式卡片图片展示全部内容,希望文章能够帮你解决Android实现3D层叠式卡片图片展示所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)