首先,说一下布局,是FrameLayout,这个布局设置一点点击方法,要设置id,之后会用到。这个布局还包括两个子布局,分别是Poke的正面和反面布局。上代码:
还需额外注意一点:这是刚刚才发现的问题,在主activity中,正反面那个xml文件放在后面就会优先默认显示那个xml文件,所以,如果我需要一打开app就看到正面的话,那么正面xml文件需要放到反面xml文件的下面,就是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:onClick="flipCard" android:id="@+id/main_fl_container" tools:context="com.example.chenxuanhe.poketest.MainActivity">
<include layout="@layout/cell_card_back" /> <include layout="@layout/cell_card_front" /> </FrameLayout> |
根据代码的逻辑线走,则是接下来的两个layout:
这两个FrameLayout也是需要写id的,之后会用到。
cell_card_back.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main_fl_card_back" >
<ImageView android:src="@drawable/rectangle_back" android:contentDescription="@null" android:padding="16dp" android:layout_width="match_parent" android:layout_height="match_parent" />
<TextView android:textColor="@color/colorAccent" android:text="反面" android:textSize="40dp" android:layout_gravity="center" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" />
</FrameLayout> |
cell_card_front.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main_fl_card_front">
<ImageView android:src="@drawable/rectangle_front" android:padding="16dp" android:contentDescription="@null" android:layout_width="match_parent" android:layout_height="match_parent" />
<TextView android:textSize="40dp" android:textColor="@color/colorPrimary" android:text="正面" android:gravity="center" android:layout_gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" />
</FrameLayout> |
继续顺着上面两个布局的逻辑线来走,就需要用到两个Drawable的文件作为背景图,所以接着看drawable文件:
rectangle_back.xml:
大概是一个黑边红底色带圆角的卡片界面
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="16dp"/> <solid android:color="@color/cardBack"/> <stroke android:width="2dp" android:color="@android:color/black"/>
</shape> |
rectangle_front.xml:
大概是一个黑边灰底色带圆角的卡片界面
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="16dp"/> <solid android:color="@color/cardFront"/> <stroke android:width="2dp" android:color="@android:color/black"/>
</shape> |
走完界面UI的逻辑线之后,就去看Java代码,发现需要两个Animator,于是在res文件下创建一个animator资源文件夹,在下创建两个动画文件:
anim-in.xml:
这是一个从左边进入的动画,一开始是隐藏的,逆向旋转,当旋转到一半时,显示卡片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?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="3000" android:propertyName="rotationY" android:valueFrom="-180" android:valueTo="0"/>
<!--出现--> <objectAnimator android:duration="0" android:propertyName="alpha" android:startOffset="1500" android:valueFrom="0.0" android:valueTo="1.0"/>
</set> |
anim_out.xml:
这是一个右边出去的动画,旋转180度,旋转到一半时,卡片就消失了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator android:duration="3000" android:propertyName="rotationY" android:valueFrom="0" android:valueTo="180"/>
<!--消失--> <objectAnimator android:duration="0" android:propertyName="alpha" android:startOffset="1500" android:valueFrom="1.0" android:valueTo="0.0"/> </set> |
接着看Java代码:
MainActivity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
public class MainActivity extends AppCompatActivity {
@Bind(R.id.main_fl_card_back) FrameLayout mFlCardBack; @Bind(R.id.main_fl_card_front) FrameLayout mFlCardFront; @Bind(R.id.main_fl_container) FrameLayout mFlContainer; private AnimatorSet mLeftInSet; private AnimatorSet mRightOutSet;
private boolean mIsShowBack;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this);
setAnimation();//设置动画 setCameraDistance();//设置镜头距离,在这里不是太懂 }
private void setAnimation() { //mLeftInSet是左边进入的动画 mLeftInSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.anim_in); //mRightOutSet是右边出去的动画 mRightOutSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.anim_out);
//点击事件 //通过ListenerAdapter就不需重写所有方法,只需写需要写的方法 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);//主布局中framelayouy的就允许你去点击了 } });
}
//一直不是很懂的设置镜头距离, //帖子上的注释写着:改变视角距离,贴近屏幕 private void setCameraDistance() { int distance = 16000; float scale = getResources().getDisplayMetrics().density*distance; mFlCardFront.setCameraDistance(scale);//设置距离 mFlCardBack.setCameraDistance(scale);//设置距离 }
//这是主Framelayout的点击方法 public void flipCard(View view){ //mIsShowBack可以理解为互斥,所以为boolean if(!mIsShowBack){ //右出动画设置在正面卡片界面 mRightOutSet.setTarget(mFlCardFront); //左入动画设置在反面卡片界面 mLeftInSet.setTarget(mFlCardBack); //开始动画 mRightOutSet.start(); mLeftInSet.start(); mIsShowBack = true; }else { //右出动画设置在卡片背面界面 mRightOutSet.setTarget(mFlCardBack); //左入动画设置在卡片正面界面 mLeftInSet.setTarget(mFlCardFront); mRightOutSet.start(); mLeftInSet.start(); mIsShowBack = false; } } //这一点我一直没想到,还可以在onDestroy方法中解绑ButterKnife protected void onDestroy(){ super.onDestroy(); ButterKnife.unbind(this); } } |
到这一步,基本就全部完成了。