Android实现3D层叠式卡片图片展示

Android实现3D层叠式卡片图片展示,第1张

概述Android实现3D层叠卡片图片展示 本文实例为大家分享了Android实现3D层叠式卡片图片展示的具体代码,供大家参考,具体内容如下 先看效果 好了效果看了,感兴趣的往下看哦! 整体实现思路 1.重写RelativeLayout 实现 锁定宽高比例的 RelativeLayout 2.自定义一个支持滑动的面板 继承 ViewGroup 3.卡片View绘制 4.页面中使用布局 首先为了更好的展示图片我们重写一下 RelativeLayout 编写一个锁定宽高比例的 RelativeLayout AutoScaleRelativeL

本文实例为大家分享了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层叠式卡片图片展示所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1144334.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存