翻译动画是其他布局的背后

时间:2014-03-18 08:51:11

标签: android layout

我的屏幕上有四个线性布局。

第一个布局包含textview。

我正在尝试使用翻译动画将textView移动到右边的第四个布局。

但是当我这样做时,文本视图会移动到其他布局后面,如果我将我的布局从右边的第四个布局移动到左边的第一个布局,那就没关系。

我的xml我放了:所有布局

android:clipChildren="false"

image

你能帮助我吗?

谢谢

6 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

Pre-Kitkat:

yourLayout.bringToFront();
((View)yourLayout.getParent()).requestLayout();
((View)yourLayout.getParent()).invalidate();

KitKat:

yourLayout.bringToFront();

答案 2 :(得分:0)

Android线性布局构建从头开始的第一个元素开始。因此,首先定义的任何元素都将被创建然后休息,因此无论您做什么,都无法实现线性布局。尝试相对布局

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <LinearLayout
            android:id="@+id/testAnimTranslate"
            android:layout_width="wrap_content"
            android:layout_height="80dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:gravity="center_vertical"
            android:orientation="horizontal" >

            <LinearLayout
                android:layout_width="30dp"
                android:layout_height="70dp"
                android:background="#0000dd"
                android:orientation="vertical" />

            <LinearLayout
                android:layout_width="30dp"
                android:layout_height="70dp"
                android:layout_alignParentBottom="true"
                android:background="#0dd0dd"
                android:orientation="vertical" />

            <LinearLayout
                android:layout_width="30dp"
                android:layout_height="70dp"
                android:layout_alignParentBottom="true"
                android:background="#ddd0dd"
                android:orientation="vertical" />

            <LinearLayout
                android:layout_width="30dp"
                android:layout_height="70dp"
                android:layout_alignParentBottom="true"
                android:background="#44d0dd"
                android:orientation="vertical" />
     </LinearLayout>

        <TextView
            android:id="@+id/textAnimate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@id/testAnimTranslate"
            android:layout_alignTop="@id/testAnimTranslate"
            android:layout_toLeftOf="@id/testAnimTranslate"
            android:gravity="center"
            android:background="#00000000"
            android:text="qweqwew" />

</RelativeLayout>

在动画文件夹中或以编程方式定义您的翻译动画。确保添加

    LinearInterpolator
    setFillAfter to true

并开始动画

答案 3 :(得分:0)

我认为您在代码中创建了视图,因此您应该添加setClipChildren(false) 在你的构造函数中。

答案 4 :(得分:0)

查看docs

  

ZORDER_TOP:请求动画内容强制在动画持续时间的所有其他内容之上。

请检查setFillAfter(true)是否与此用法不符。 这有帮助吗?

答案 5 :(得分:0)

您要尝试做的主要问题是,您希望在其父级之外绘制视图。它落后于其他LinearLayouts,因为它们是在View的LinearLayout父元素之后绘制的。即使它被带到前面,似乎只涉及单亲中的孩子?

如果您查看片段动画的工作原理,您需要重新创建片段以将一个帧转换为另一个帧。您还需要两个单独的动画。

BlackBeard的解决方案将起作用,因为它使TextView成为最外层父级的子级并最后声明它。这意味着TextView是在其他所有内容之后绘制的,因此将绘制在其他所有内容之上。

这并没有实现我认为你想要做的事情。如果您希望TextView在动画后属于其目标LinearLayout,则需要重新创建TextView并将其添加到层次结构中正确位置的LinearLayout。您还需要第二个动画才能将新TextView移动到其位置。

如果操作正确,动画应完美叠加,如果在LinearLayout中,动画视图中的一个或另一个将传递到其他所有内容。

activity_main.xml中

<LinearLayout
    android:id="@+id/frame"
    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:clipChildren="false"
    android:orientation="horizontal"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layout1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#FFAABBCC"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="24sp"
            android:text="I'm some text"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#FFBBCCAA"
        android:orientation="vertical">

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout3"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#FFCCAABB"
        android:orientation="vertical">

    </LinearLayout>

    <LinearLayout
        android:id="@+id/layout4"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#FFBBAACC"
        android:orientation="vertical">

    </LinearLayout>

</LinearLayout>

MainActivity.java

private LinearLayout mLayout1;
private LinearLayout mLayout2;
private LinearLayout mLayout3;
private LinearLayout mLayout4;
private TextView mTextView;
private View.OnTouchListener mOnTouchListener;

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

    mLayout1 = (LinearLayout) findViewById(R.id.layout1);
    mLayout2 = (LinearLayout) findViewById(R.id.layout2);
    mLayout3 = (LinearLayout) findViewById(R.id.layout3);
    mLayout4 = (LinearLayout) findViewById(R.id.layout4);
    mTextView = (TextView) findViewById(R.id.textView);
    mOnTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // simple trigger to start the animation.
            startAnimation();
            mTextView.setOnTouchListener(null);
            return true;
        }
    };
    mTextView.setOnTouchListener(mOnTouchListener);
}

private void startAnimation() {

    final LinearLayout origin = (LinearLayout) mTextView.getParent();
    LinearLayout destination = null;
    // I'm not sure what kind of behaviour you want. This just randomises the destination.
    do {
        switch (new Random().nextInt(4)) {
            case 0:
                destination = mLayout1;
                break;
            case 1:
                destination = mLayout2;
                break;
            case 2:
                destination = mLayout3;
                break;
            case 3:
                destination = mLayout4;
                break;
            default:
        }
        // if destination == origin or is null, try again.
    } while (destination == origin || destination == null);

    // Create another TextView and initialise it to match mTextView
    final TextView textViewNew = new TextView(this);
    textViewNew.setText(mTextView.getText());
    textViewNew.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextView.getTextSize());
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    textViewNew.setLayoutParams(params);
    textViewNew.setOnTouchListener(mOnTouchListener);

    // Add the new TextView to the destination LinearLayout
    destination.addView(textViewNew);

    // Create animations based on origin and destination LinearLayouts
    ObjectAnimator outAnimator = getOutAnimator(origin, destination);
    // The in animator also requires a reference to the new TextView
    ObjectAnimator inAnimator = getInAnimator(textViewNew, origin, destination);
    // All animators must be created before any are started because they are calculated
    // using values that are modified by the animation itself.
    outAnimator.start();
    inAnimator.start();
    // Add a listener to update mTextView reference to the new TextView when complete.
    inAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }

        @Override
        public void onAnimationEnd(Animator animation) {

            origin.removeView(mTextView);
            mTextView = textViewNew;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }

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

/**
 * This method creates an ObjectAnimator to move the existing TextView out of its parent
 * towards its destination
 */
private ObjectAnimator getOutAnimator(View origin, View destination) {

    // Calculate the difference between x of destination and of origin
    float layoutDifferenceX = destination.getX() - origin.getX();
    // initialX is simply mTextView.getX()
    // the distance moved == layoutDifferenceX
    float finalX = mTextView.getX() + layoutDifferenceX;

    ObjectAnimator animator = ObjectAnimator.ofFloat(mTextView, "x",
            mTextView.getX(), finalX);
    animator.setInterpolator(new AccelerateDecelerateInterpolator());
    animator.setDuration(500);

    return animator;
}

/**
 * This method creates an ObjectAnimator to move the new TextView from the initial position
 * of mTextView, relative to the new TextView's parent, to its destination.
 */
private ObjectAnimator getInAnimator(View newView, View origin, View destination) {

    // Calculate the difference between x of destination and of origin
    float layoutDifferenceX = destination.getX() - origin.getX();
    // initialX relative to destination
    float initialX = mTextView.getX() - layoutDifferenceX;

    // finalX relative to destination == initialX relative to origin
    float finalX = mTextView.getX();

    ObjectAnimator animator = ObjectAnimator.ofFloat(newView, "x",
            initialX, finalX);
    animator.setInterpolator(new AccelerateDecelerateInterpolator());
    animator.setDuration(500);

    return animator;
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

编辑:您也可以在xml中声明TextView并对其进行充气以摆脱所有初始化它的代码。