可翻转移到的自定义卡片
先建立卡片 xml 。view_card_item.xml
<?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" android:orientation="vertical" > <FrameLayout android:id="@+id/frame_layout_zm" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:orientation="vertical" android:layout_gravity="top" android:paddingTop="5dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:textColor="@color/default_black" android:textSize="20dp" android:text="正面小标题"/> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/blue" /> </LinearLayout> <TextView android:gravity="center" android:id="@+id/data_zm_msg" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="left" android:textColor="@color/default_black" android:textSize="25dp" android:text="事件内容正面"/> </FrameLayout> <FrameLayout android:visibility="gone" android:id="@+id/frame_layout_bm" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:orientation="vertical" android:layout_gravity="top" android:paddingTop="5dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:textColor="@color/default_black" android:textSize="20dp" android:text="背面小标题"/> <TextView android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/blue" /> </LinearLayout> <TextView android:gravity="center" android:id="@+id/data_bm_msg" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="left" android:textColor="@color/default_black" android:textSize="25dp" android:text="背面内容"/> </FrameLayout> </LinearLayout>
创建 CardItem.java
import android.view.View; /** * @author Yzh315 */ public class CardItem { public View getView() { return view; } public View getZmView() { return zmView; } public View getBmView() { return bmView; } public boolean isZm() { return isZm; } public void setZm(boolean zm) { isZm = zm; } private boolean isZm = true;//目前为正面 private View zmView,bmView; public CardItem setView(View zv1,View zv2){ this.zmView = zv1; this.bmView = zv2; return this; } private View view ; public CardItem setView(View view){ this.view = view; return this; } private float lastX; public float getLastX() { return lastX; } public void setLastX(float lastX) { this.lastX = lastX; } public float getLastY() { return lastY; } public void setLastY(float lastY) { this.lastY = lastY; } private float lastY; }
最后创建主要的自定义 ViewGroup ,MyCardsView.java
import android.animation.Animator;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import org.json.JSONArray;import org.json.JSONObject;import java.util.HashMap;import java.util.List;import java.util.Map;public class MyCardsView extends ViewGroup { public MyCardsView(Context context, AttributeSet attrs) { super(context, attrs); } public MyCardsView(Context context) { super(context); } public void setArrayJson(JSONArray arrayJson) { this.arrayJson = arrayJson; } public JSONObject getJSON(int index){ try { return arrayJson.getJSONObject(index); }catch (Exception e){} return null; } private JSONArray arrayJson = null ; private ItemView itemView = null; public void setItemView(ItemView itemView) { this.itemView = itemView; } private int paddingLeft = 100 ,paddingTop = 5;//间隔 public void setPadding(int left,int top){ paddingLeft = left; paddingTop = top; } @Override protected void onLayout( boolean changed, int left, int top, int right, int bottom) { final int count = getChildCount(); int childMeasureHeight = 0; for(int i = 0; i<count; i++){ View child = getChildAt(i); right = this.getWidth() - paddingLeft; bottom = top + child.getMeasuredHeight(); //确定子控件的位置,四个参数分别代表(左上右下)点的坐标值 child.layout(paddingLeft , paddingTop , right, bottom); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 计算出所有的childView的宽和高 measureChildren(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension( getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec)); } private Map<Integer, CardItem> viewMap = new HashMap<>(); float lastX, lastY; private int nowIndex = 0 ;//初始化值 private void initLayout(){ for(int i=arrayJson.length()-1;i>=0;i--){ CardItem cardItem = new CardItem(); LinearLayout linearLayout = new LinearLayout(getContext()); View rootView = itemView.getItemView(linearLayout,cardItem,getJSON(i),i);//目前位置 if(rootView!=null){ LayoutParams layoutParams = new LayoutParams(this.getWidth() - 200,this.getHeight()-10); linearLayout.addView(rootView,layoutParams); } viewMap.put(i,cardItem.setView(linearLayout));//添加 addView(linearLayout); } } public void initialize() { this.post(new Runnable() { @Override public void run() { initLayout(); } }); } ///////////////////////////// private void initShow(int x,int y){ for(int i = nowIndex - 1 ; i >= 0 ; i--){ View view = viewMap.get(i).getView(); view.setX(x); view.setY(y); view.bringToFront(); } for(int i=viewMap.size()-1;i>=nowIndex;i--){ View view = viewMap.get(i).getView(); view.setX(x); view.setY(y); view.bringToFront(); } } private float downX ,downY;// private long lastUpTime = 0; @Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); lastX = event.getRawX(); lastY = event.getRawY(); return true; case MotionEvent.ACTION_UP: try{ CardItem cardItem = viewMap.get(nowIndex); View myView = cardItem.getView(); float jlX = event.getX()-downX;//设置目前值 float jlY = event.getY()-downY;//设置目前值 if(jlY<=1&&jlX<=1){ //点击// if(System.currentTimeMillis()-lastUpTime>500){// lastUpTime = System.currentTimeMillis(); if(cardItem.isZm()){ AnimUtil.FlipAnimatorXViewShow(cardItem.getZmView(),cardItem.getBmView(),500); }else { AnimUtil.FlipAnimatorXViewShow(cardItem.getBmView(),cardItem.getZmView(),500); } cardItem.setZm(!cardItem.isZm());// } }else if(Math.abs(jlX)>200||Math.abs(jlY)>100){// lastUpTime = System.currentTimeMillis(); AnimUtil.EndBackCallListener endBackCallListener = new AnimUtil.EndBackCallListener() { @Override public void callBack() { //翻转 if(!cardItem.isZm()){ //反正 AnimUtil.FlipAnimatorXViewShow(cardItem.getBmView(),cardItem.getZmView(),500); cardItem.setZm(!cardItem.isZm()); } nowIndex ++; if(nowIndex<0) nowIndex = 0 ; if(nowIndex>=viewMap.size()) nowIndex = 0;//从0开始 initShow(paddingLeft,paddingTop); } }; if(jlX>0){ AnimUtil.SetViewXyToXy(myView, this.getWidth(), myView.getY(), 500, endBackCallListener); }else{ //右到左 float toX = - this.getWidth(); AnimUtil.SetViewXyToXy(myView, toX, myView.getY(), 500, endBackCallListener); } }else{// lastUpTime = System.currentTimeMillis(); AnimUtil.SetViewXyToXy(myView,paddingLeft,paddingTop,500,null); } }catch (Exception e){} break; case MotionEvent.ACTION_MOVE: // 不要直接用getX和getY,这两个获取的数据已经是经过处理的,容易出现图片抖动的情况 try{// lastUpTime = System.currentTimeMillis(); float distanceX = lastX - event.getRawX(); float distanceY = lastY - event.getRawY(); ////////////////////////////////////////////////////// View myView = viewMap.get(nowIndex).getView(); float nextY = myView.getY() - distanceY; float nextX = myView.getX() - distanceX; AnimUtil.SetViewXyToXy(myView,nextX,nextY,0,null); lastX = event.getRawX(); lastY = event.getRawY();// myView.bringToFront(); }catch (Exception e){} } return false; } public interface ItemView{ public View getItemView(View parentView,CardItem cardItem,JSONObject dataJson,int index); }}
工具类
AnimUtil.java
import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.view.View; import android.view.animation.OvershootInterpolator; public class AnimUtil { public interface EndBackCallListener{ void callBack(); }; public static void SetViewXyToXy(final View view,float toX,float toY,long durationTime,EndBackCallListener endBackCallListener){ try{ // 属性动画移动 ObjectAnimator y = ObjectAnimator.ofFloat(view, "y", view.getY(), toY); ObjectAnimator x = ObjectAnimator.ofFloat(view, "x", view.getX(), toX); AnimatorSet animatorSet = new AnimatorSet(); if(endBackCallListener!=null){ animatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { endBackCallListener.callBack(); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); } animatorSet.playTogether(x, y); animatorSet.setDuration(durationTime); animatorSet.start(); }catch (Exception e){} } public static void FlipAnimatorXViewShow(final View oldView, final View newView, final long time) { try{ if(oldView==null) return; if(newView==null) return; ObjectAnimator animator1 = ObjectAnimator.ofFloat(oldView, "rotationY", 0, 90); final ObjectAnimator animator2 = ObjectAnimator.ofFloat(newView, "rotationY", -90, 0); animator2.setInterpolator(new OvershootInterpolator(2.0f)); animator1.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { oldView.setVisibility(View.GONE); animator2.setDuration(time).start(); newView.setVisibility(View.VISIBLE); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animator1.setDuration(time).start(); }catch (Exception e){} } }
调用
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyCardsView myCardsView = new MyCardsView(this); JSONArray array = new JSONArray(); for(int i=0;i<20;i++){ try{ JSONObject jsonObject = new JSONObject(); jsonObject.put("msg","正面信息 ............."+i); array.put(jsonObject); }catch (Exception e){} } myCardsView.setArrayJson(array); myCardsView.setItemView(new MyCardsView.ItemView() { @Override public View getItemView(View parentView, CardItem cardItem, JSONObject dataJson, int index) { try{ View rootView = LayoutInflater.from(parentView.getContext()).inflate(R.layout.view_learn_card_item,null);//获取数据 TextView textView = rootView.findViewById(R.id.data_zm_msg); if(textView!=null){ textView.setText(dataJson.getString("msg") ); textView.setTextSize(25); } FrameLayout frame_layout_zm = rootView.findViewById(R.id.frame_layout_zm); FrameLayout frame_layout_bm = rootView.findViewById(R.id.frame_layout_bm); cardItem.setView(frame_layout_zm,frame_layout_bm); return rootView; }catch (Exception e){ } return null; } }); myCardsView.initialize(); LinearLayout linearLayout = new LinearLayout(this); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,600); lp.gravity = Gravity.CENTER; linearLayout.addView(myCardsView,lp); setContentView(linearLayout); }
相关推荐
huha 2020-10-16
xfcyhades 2020-11-20
sgafdsg 2020-11-04
Michael 2020-11-03
fengyeezju 2020-10-14
ziyexiaoxiao 2020-10-14
业余架构师 2020-10-09
OuNuo0 2020-09-29
moses 2020-09-22
Angelia 2020-09-11
qinxu 2020-09-10
刘炳昭 2020-09-10
Nostalgiachild 2020-09-07
Nostalgiachild 2020-08-17
leavesC 2020-08-14
一青年 2020-08-13
AndroidAiStudy 2020-08-07
ydc0 2020-07-30
绿豆饼 2020-07-28