效果图:
gridview是Android中的重要组件之一,俗称“九宫格”。有时会遇到翻牌情况,第一张先翻开,剩下的延迟打开。
说下思路:
首先,需要翻牌动画。
其次,翻牌控制。点击当前牌,记录点击位置然后延迟刷新数据。重刷数据时,判断如果重新设置数据的子view位置与点击相同,重置数据。
上代码:
动画 res下新建animator文件夹
anim_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--消失-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0"/>
<!--旋转-->
<objectAnimator
android:duration="600"
android:propertyName="rotationY"
android:valueFrom="-180"
android:valueTo="0"/>
<!--出现-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="300"
android:valueFrom="0.0"
android:valueTo="1.0"/>
</set>
anim_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--旋转-->
<objectAnimator
android:duration="600"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="180"/>
<!--消失-->
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:startOffset="300"
android:valueFrom="1.0"
android:valueTo="0.0"/>
</set>
封装成一个view使用:
FlipCardsView.java:
package com.lcl.view;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Created by liuchunliang on 2017/2/28.
*/
public class FlipCardsView extends FrameLayout {
Context mContext;
LinearLayout mFlCardBack;
LinearLayout mFlCardFront;
FrameLayout mFlContainer;
TextView tv;
AnimatorSet mRightOutSet; // 右出动画
AnimatorSet mLeftInSet; // 左入动画
public FlipCardsView(Context context,AttributeSet attrs) {
super(context,attrs);
mContext = context;
//加载布局
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.layout_flipcardsview, this);
mFlContainer = (FrameLayout) findViewById(R.id.main_fl_container);
mFlCardBack = (LinearLayout) findViewById(R.id.main_fl_card_back);
mFlCardFront = (LinearLayout) findViewById(R.id.main_fl_card_front);
tv = (TextView) findViewById(R.id.tv);
setAnimators(); // 设置动画
setCameraDistance(); // 设置镜头距离
}
// 改变视角距离, 贴近屏幕
private void setCameraDistance() {
int distance = 16000;
float scale = getResources().getDisplayMetrics().density * distance;
mFlCardFront.setCameraDistance(scale);
mFlCardBack.setCameraDistance(scale);
}
// 设置动画
private void setAnimators() {
mRightOutSet = (AnimatorSet) AnimatorInflater.loadAnimator(mContext, R.animator.anim_out);
mLeftInSet = (AnimatorSet) AnimatorInflater.loadAnimator(mContext, R.animator.anim_in);
// 设置点击事件
mRightOutSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mFlContainer.setClickable(false);
}
});
mLeftInSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mFlContainer.setClickable(true);
}
});
}
/**
*可以自行设置需要修改的数据属性,外放就行
*/
//设置反面文字(金币)
public void setText(String context) {
tv.setText(context);
}
//设置反面背景
public void setCardBackground(int color) {
mFlCardBack.setBackgroundColor(color);
}
//启动动画
public void start() {
mRightOutSet.setTarget(mFlCardFront);
mLeftInSet.setTarget(mFlCardBack);
mRightOutSet.start();
mLeftInSet.start();
}
}
cell_card_back.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:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="#EE7600"
android:textSize="25dp" />
</LinearLayout>
cell_card_front.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:background="#CDBE70"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="翻翻试手气"
android:textColor="#5D478B"
android:textSize="25dp" />
</LinearLayout>
layout_flipcardsview.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_fl_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/main_fl_card_back"
layout="@layout/cell_card_back" />
<include
android:id="@+id/main_fl_card_front"
layout="@layout/cell_card_front" />
</FrameLayout>
MainActivity.java:
package com.lcl.view;
import android.graphics.Color;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private GridView gridview;
private GridViewAdapter gridViewAdapter;
private boolean mFlag = true;
List<String> jinbi = new ArrayList<>();
private int clickPosition = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
gridview = (GridView) findViewById(R.id.doubledealer_gv);
gridViewAdapter = new GridViewAdapter();
jinbi.clear();
jinbi.add("3");
jinbi.add("6");
jinbi.add("9");
jinbi.add("5");
jinbi.add("2");
jinbi.add("4");
jinbi.add("24");
jinbi.add("33");
jinbi.add("11");
gridViewAdapter.refreshData_Grid(jinbi);
gridview.setAdapter(gridViewAdapter);
}
public class GridViewAdapter extends BaseAdapter {
List<String> headGVList = new ArrayList<>();
public boolean refreshData_Grid(List<String> list) {
if (list != null && list.size() > 0) {
headGVList.clear();
headGVList.addAll(list);
notifyDataSetChanged();
return true;
} else {
return false;
}
}
@Override
public int getCount() {
return headGVList == null ? 0 : headGVList.size();
}
@Override
public Object getItem(int position) {
return headGVList == null ? null : headGVList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
GridViewAdapter.ViewHolder holder = null;
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
// 1、如果没有可利用item时,找出所有控件
if (convertView == null) {
holder = new GridViewAdapter.ViewHolder();
convertView = LayoutInflater.from(MainActivity.this)
.inflate(R.layout.doubledealer_gv_item, parent, false);
holder.textView = (TextView) convertView.findViewById(R.id.tv);
holder.myLayout = (LinearLayout) convertView
.findViewById(R.id.myLayout);
holder.fcv = (FlipCardsView) convertView.findViewById(R.id.fcv);
// 2、绑定
convertView.setTag(holder);
} else {// 3、有可利用的item时就获取赋值使用
holder = (GridViewAdapter.ViewHolder) convertView.getTag();
}
if (mFlag) {
// 监听点击事件
holder.myLayout.setClickable(true);
holder.myLayout.setOnClickListener(new MyClickListener(holder, headGVList, position));
} else {
// 监听点击事件
holder.myLayout.setClickable(false);
if(clickPosition == position){
}else{
holder.fcv.start();
holder.fcv.setCardBackground(Color.parseColor("#B0E2FF"));
holder.fcv.setText(headGVList.get(position) + "");
}
}
return convertView;
}
private class ViewHolder {
TextView textView;
LinearLayout myLayout;
FlipCardsView fcv;
}
}
class MyClickListener implements View.OnClickListener {
GridViewAdapter.ViewHolder holder;
int position;
List<String> headGVList;
private MyClickListener(GridViewAdapter.ViewHolder holder, List<String> headGVList, int position) {
this.holder = holder;
this.headGVList = headGVList;
this.position = position;
}
@Override
public void onClick(View v) {
if (mFlag) {
clickPosition = position;
holder.fcv.start();
holder.fcv.setCardBackground(Color.parseColor("#C1C1C1"));
holder.fcv.setText(headGVList.get(position) + "");
new Handler().postDelayed(new Runnable() {
public void run() {
gridViewAdapter.refreshData_Grid(jinbi);
gridViewAdapter.notifyDataSetChanged();
}
}, 1000);
mFlag = false;
}
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<!--设置gridview列数、点击时效果、间距-->
<GridView
android:id="@+id/doubledealer_gv"
android:layout_width="match_parent"
android:layout_height="300dp"
android:gravity="center"
android:listSelector="@android:color/transparent"
android:numColumns="3"
android:verticalSpacing="15dp"></GridView>
</LinearLayout>
doubledealer_gv_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myLayout"
android:layout_width="80dp"
android:layout_height="80dp">
<com.lcl.view.FlipCardsView
android:id="@+id/fcv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
附上完整代码下载地址:
demo下载链接->传送门