可翻转移到的自定义卡片
Posted yzh315
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可翻转移到的自定义卡片相关的知识,希望对你有一定的参考价值。
先建立卡片 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); }
以上是关于可翻转移到的自定义卡片的主要内容,如果未能解决你的问题,请参考以下文章