我应该如何为特定视图添加动画效果?

3

当我从Activity 1 切换到 Activity 2 时,我希望能够动画地将 Bloc A 向上滑动,并将 Bloc B 向下滑动

有人可以为我提供解决方案吗?非常感谢您的帮助。

以下是我想要的效果示意图:

enter image description here


尝试下面的代码。 - Brainnovo
1个回答

1
请尝试以下步骤:

1)MainActivity.class

public class MainActivity extends AppCompatActivity implements Listener {

private Drawer m_Drawer;
private Button b;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    m_Drawer = new Drawer(this, this);

    b = (Button) findViewById(R.id.b); // click on this button to open drawer.
    b.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            m_Drawer.openDrawer();
        }
    });


}

@Override
public void AnimationFinished(int state) {
    if (state == 1) {
        b.setVisibility(View.VISIBLE); // you can start a new activity or do whatever here.
    }else if(state == 0){
        b.setVisibility(View.GONE);
    }
}

}

2) Drawer.class:-------

public class Drawer {

private static final String TAG = "Drawer";
private RelativeLayout topDrawer;//2
private RelativeLayout bottomDrawer;//2
private Activity activity;
private static final int DRAWER_UP = 1;
private static final int DRAWER_DOWN = 0;
private int mainlayoutHeight;
private TextView drawerTxt1;
private TextView drawerTxt;
private int direct;
private ConstraintLayout mainLayout;//1

private float mDownMotionX = 0;
private float mDownMotionY = 0;

private final int SWIPE_SENSITIVITY = 10;

private final int SWIPE_X_SENSITIVITY = 20;

private final int SWIPE_Y_SENSITIVITY_MIN = 0;
private int SWIPE_Y_SENSITIVITY_MAX = 0;

private Listener callback;

Drawer(Activity mainActivity , Listener l) {
    activity = mainActivity;
    if(l != null){
        this.callback = l;
    }
    initialize();
    getLayoutHeight();

}

private void initialize() {

    topDrawer =  (RelativeLayout) activity.findViewById(R.id.top_drawer);//2
    drawerTxt1 = (TextView) topDrawer.findViewById(R.id.drawer_txt1);
    drawerTxt1.setText("BLOCK A");
    bottomDrawer =  (RelativeLayout) activity.findViewById(R.id.bottom_drawer);//2
    drawerTxt = (TextView) bottomDrawer.findViewById(R.id.drawer_txt);
    drawerTxt.setText("BLOCK B");

    topDrawer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {

            Log.e(TAG, "Touch View");
            final int action = ev.getAction();

            switch (action & MotionEvent.ACTION_MASK) {

                case MotionEvent.ACTION_DOWN:
                    // Remember where the motion event started
                    mDownMotionX = ev.getX();
                    mDownMotionY = ev.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    // Scroll to follow the motion event
                    final float x = ev.getX();
                    final float y = ev.getY();

                    SWIPE_Y_SENSITIVITY_MAX = getScreenHeight();

                    if (Math.abs(y - mDownMotionY) >= SWIPE_SENSITIVITY &&
                            (mDownMotionY > SWIPE_Y_SENSITIVITY_MIN &&
                                    mDownMotionY <= SWIPE_Y_SENSITIVITY_MAX) &&
                            Math.abs(x - mDownMotionX) <= SWIPE_X_SENSITIVITY) {

                        if ((y - mDownMotionY) > 0) {
                            Log.d(TAG, "Dragging Down");
                        }
                    } else if ((y - mDownMotionY) < 0) {
                        closeDrawer();
                        Log.d(TAG, "Dragging Up");
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                case MotionEvent.ACTION_CANCEL:
                    break;
            }
            return true;
        }
    });

    bottomDrawer.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent ev) {

            Log.e(TAG, "Touch View");
            final int action = ev.getAction();

            switch (action & MotionEvent.ACTION_MASK) {

                case MotionEvent.ACTION_DOWN:
                    // Remember where the motion event started
                    mDownMotionX = ev.getX();
                    mDownMotionY = ev.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    // Scroll to follow the motion event
                    final float x = ev.getX();
                    final float y = ev.getY();

                    SWIPE_Y_SENSITIVITY_MAX = getScreenHeight();

                    if (Math.abs(y - mDownMotionY) >= SWIPE_SENSITIVITY &&
                            (mDownMotionY > SWIPE_Y_SENSITIVITY_MIN &&
                                    mDownMotionY <= SWIPE_Y_SENSITIVITY_MAX) &&
                            Math.abs(x - mDownMotionX) <= SWIPE_X_SENSITIVITY) {

                        if ((y - mDownMotionY) > 0) {
                            Log.d(TAG, "Dragging Down");
                            closeDrawer();
                        }
                    } else if ((y - mDownMotionY) < 0) {
                        Log.d(TAG, "Dragging Up");
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                case MotionEvent.ACTION_CANCEL:
                    break;
            }
            return true;
        }
    });


}

//********************************************************************************************** Open and Close the Drawer /Animation/
private void drawerMovement(int movement){
    switch (movement) {
        case DRAWER_UP: // --------------------------------------------------------------------- Drawer UP
            topDrawer.animate().translationY(-mainlayoutHeight/2); // you can add two animation listeners, but for now one is enough.
            bottomDrawer.animate().translationY(mainlayoutHeight)
                    .setListener(new animationListener());
            direct = DRAWER_UP;
            break;

        case DRAWER_DOWN: // ------------------------------------------------------------------- Drawer DOWN
            topDrawer.animate().translationY(0);
            bottomDrawer.animate().translationY(mainlayoutHeight/2)
                    .setListener(new animationListener());
            direct = DRAWER_DOWN;
            break;
    }
}

//**********************************************************************************************  Animation Listener
private class animationListener implements  Animator.AnimatorListener {

    @Override
    public void onAnimationStart(Animator animation) {
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        callback.AnimationFinished(direct);
    }

    @Override
    public void onAnimationCancel(Animator animation) {
    }

    @Override
    public void onAnimationRepeat(Animator animation) {}
}

private void closeDrawer(){
    drawerMovement(DRAWER_UP);
}

public void openDrawer(){
    drawerMovement(DRAWER_DOWN);
}

// ********************************************************************************************* Get the Layout Height
private void getLayoutHeight() {
    mainLayout = (ConstraintLayout) activity.findViewById(R.id.main_layout);//1
    ViewTreeObserver vto = mainLayout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mainlayoutHeight = mainLayout.getMeasuredHeight();
            topDrawer.setY(0);
            bottomDrawer.setY(mainlayoutHeight/2);
            ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_PARENT, mainlayoutHeight/2);//1
            topDrawer.setLayoutParams(params);
            bottomDrawer.setLayoutParams(params);
            Log.d("Test", "Layout Height: " + mainlayoutHeight );
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            } else {
                mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        }
    });
}

private int getScreenHeight(){

    DisplayMetrics displayMetrics = new DisplayMetrics();
    activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.heightPixels;
}

}

3) 监听器接口:

public interface Listener {

public void AnimationFinished(int state);

}

4) main_activity.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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:id="@+id/main_layout"
tools:context=".MainActivity">

<RelativeLayout
     android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:id="@+id/bottom_drawer"
    android:background="?attr/colorPrimary">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/drawer_txt"
        android:textSize="28sp"
        android:gravity="center_horizontal|center_vertical" />

</RelativeLayout>

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:id="@+id/top_drawer"
    android:background="?attr/colorAccent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/drawer_txt1"
        android:textSize="28sp"
        android:gravity="center_horizontal|center_vertical" />

</RelativeLayout>

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="100dp"
    android:layout_marginLeft="10dp"
    android:layout_marginRight="10dp"
    android:gravity="center_horizontal">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/b"
        android:text="Open Drawer"
        android:textAllCaps="false"
        android:layout_gravity="center"
        android:visibility="gone"
        android:textSize="28sp"
        android:textColor="@android:color/white">
    </Button>

</LinearLayout>

</android.support.constraint.ConstraintLayout>

1
将私有的LinearLayout topDrawer和私有的LinearLayout bottomDrawer变量类型更改为RelativeLayout。 - Brainnovo
1
不,最好让top_drawer和bottom_drawer保持分离。 - Brainnovo
1
你是指父布局还是所有布局(包括顶部和底部抽屉)? - Brainnovo
1
你想让我告诉你需要改变什么吗? - Brainnovo
1
我编辑了我的答案:用ConstraintLayout替换了RelativeLayout。我还用1标记了mainLayout及其相关内容。同时,我用2标记了top_drawer和bottom_drawer及其相关内容。因此,每次需要更新父级(主布局)或(顶部和底部抽屉),您需要根据上述标记(1或2)更改它们对应的代码。 - Brainnovo
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接