1 Explanation
Here is the important application class AutoTextView, which is a custom class that inherits to TextSwitcher. Here is a brief description of the AutoTextView class:
1. The focus of this type of application is to set two animations, setInAnimation(...) and setOutAnimation(...), which separates the animation of text entry and text exit;
2. An external class - Rotate3dAnimation is defined in the class. This class is important to realize the entry and exit animation of text, and the external class inherits to Animation. To be said, this happened to be seen in apiDemo. This is my first time applying custom Animation. The animation logic is implemented in void applyTransformation(float interpolatedTime, Transformation t). The code is quite sharp. I changed it based on the original to achieve the above effect.
Two Code Part:
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class AutoTextView extends TextSwitcher implements
{
private float mHeight;
private Context mContext;
//mInUp, mOutUp separate to form an in-out animation for turning pages down
private Rotate3dAnimation mInUp;
private Rotate3dAnimation mOutUp;
//mInDown, mOutDown separates to form an in and out animation that turns downward pages
private Rotate3dAnimation mInDown;
private Rotate3dAnimation mOutDown;
public AutoTextView(Context context) {
this(context, null);
// TODO Auto-generated constructor stub
}
public AutoTextView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray a = (attrs, .auto3d);
mHeight = (.auto3d_textSize, 36);
();
mContext = context;
init();
}
private void init() {
// TODO Auto-generated method stub
setFactory(this);
mInUp = createAnim(-90, 0 , true, true);
mOutUp = createAnim(0, 90, false, true);
mInDown = createAnim(90, 0 , true , false);
mOutDown = createAnim(0, -90, false, false);
//TextSwitcher is important for file switching, such as switching from text A to text B.
//After setInAnimation(), A will execute inAnimation,
//After setOutAnimation(), B will execute OutAnimation
setInAnimation(mInUp);
setOutAnimation(mOutUp);
}
private Rotate3dAnimation createAnim(float start, float end, boolean turnIn, boolean turnUp){
final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, turnIn, turnUp);
(800);
(false);
(new AccelerateInterpolator());
return rotation;
}
//The TextView returned here is the View we see
@Override
public View makeView() {
// TODO Auto-generated method stub
TextView t = new TextView(mContext);
();
(mHeight);
(2);
return t;
}
//Define the action and scroll down the page
public void previous(){
if(getInAnimation() != mInDown){
setInAnimation(mInDown);
}
if(getOutAnimation() != mOutDown){
setOutAnimation(mOutDown);
}
}
//Define the action, scroll upward to turn the page
public void next(){
if(getInAnimation() != mInUp){
setInAnimation(mInUp);
}
if(getOutAnimation() != mOutUp){
setOutAnimation(mOutUp);
}
}
class Rotate3dAnimation extends Animation {
private final float mFromDegrees;
private final float mToDegrees;
private float mCenterX;
private float mCenterY;
private final boolean mTurnIn;
private final boolean mTurnUp;
private Camera mCamera;
public Rotate3dAnimation(float fromDegrees, float toDegrees, boolean turnIn, boolean turnUp) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mTurnIn = turnIn;
mTurnUp = turnUp;
}
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
(width, height, parentWidth, parentHeight);
mCamera = new Camera();
mCenterY = getHeight() / 2;
mCenterX = getWidth() / 2;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX ;
final float centerY = mCenterY ;
final Camera camera = mCamera;
final int derection = mTurnUp ? 1: -1;
final Matrix matrix = ();
();
if (mTurnIn) {
(0.0f, derection *mCenterY * (interpolatedTime - 1.0f), 0.0f);
} else {
(0.0f, derection *mCenterY * (interpolatedTime), 0.0f);
}
(degrees);
(matrix);
();
(-centerX, -centerY);
(centerX, centerY);
}
}
}
2.
package ;
import ;
import ;
import ;
import ;
import ;
public class MainActivity extends Activity implements OnClickListener {
private Button mBtnNext;
private Button mBtnPrev;
private AutoTextView mTextView02;
private static int sCount = 10;
@Override
protected void onCreate(Bundle savedInstanceState) {
(savedInstanceState);
setContentView(.activity_main);
init();
}
private void init() {
// TODO Auto-generated method stub
mBtnNext = (Button) findViewById();
mBtnPrev = (Button) findViewById();
mTextView02 = (AutoTextView) findViewById(.switcher02);
("Hello world!");
(this);
(this);
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (()) {
case :
();
sCount++;
break;
case :
();
sCount--;
break;
}
(sCount%2==0 ?
sCount+"AAFirstAA" :
sCount+"BBBBBBB");
("getH: ["+()+"]");
}
}
3. activity_main.xml
<LinearLayout xmlns:andro
xmlns:auto3d="/apk/res/"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="@string/next" />
<Button
android:
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="@string/prev" />
</RelativeLayout>
<
android:
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_green_dark"
auto3d:textSize="30sp" />
</LinearLayout>
There are not many comments written in the code, but the structure is quite clear and should not be difficult to understand!
Three Summary
I think the difficulty of implementing this control lies in the writing of animation files, that is, the implementation of the applyTransformation(...) method in Rotate3dAnimation. By controlling the movement of camara in the Y direction and the rotation in the X direction, it creates a visual sense of up and down rolling, and then converts the value to matrix, thus changing the parameters (.., Transformation t). Friends who are interested can directly rewrite this method, which can lose the TextSwitcher with different animation effects.