可翻转移到的自定义卡片



先建立卡片 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);
} 相关推荐
xfcyhades 2020-11-20
Michael 2020-11-03
业余架构师 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