2

我正在尝试使用来自 der android 开发人员网站的以下示例缩放 FrameLayout:http: //developer.android.com/training/animation/zoom.html

我的具体问题,第一次动画是正确的,是从 thumbView 扩展,第二次动画来自“某处”(中间/顶部到中心)。

我几乎相同,不同之处在于,我有一个 Framelayout 而不是一个 ImageView 并且我提取了函数以在一个额外的方法中最小化视图。现在看起来像这样:

private void zoomImageFromThumb(final View thumbView) {

    if (mCurrentAnimator != null) {
        mCurrentAnimator.cancel();
    }

    // here i building my custome layout

    startBounds = new Rect();
    final Rect finalBounds = new Rect();
    final Point globalOffset = new Point();

    thumbView.getGlobalVisibleRect(startBounds);
    findViewById(R.id.container)
            .getGlobalVisibleRect(finalBounds, globalOffset);
    startBounds.offset(-globalOffset.x, -globalOffset.y);
    finalBounds.offset(-globalOffset.x + 15, -globalOffset.y + 60);

    float startScale;
    if ((float) finalBounds.width() / finalBounds.height()
            > (float) startBounds.width() / startBounds.height()) {

        startScale = (float) startBounds.height() / finalBounds.height();
        float startWidth = startScale * finalBounds.width();
        float deltaWidth = (startWidth - startBounds.width()) / 2;
        startBounds.left -= deltaWidth;
        startBounds.right += deltaWidth;
    } else {

        startScale = (float) startBounds.width() / finalBounds.width();
        float startHeight = startScale * finalBounds.height();
        float deltaHeight = (startHeight - startBounds.height()) / 2;
        startBounds.top -= deltaHeight;
        startBounds.bottom += deltaHeight;
    }

    thumbView.setAlpha(0f);
    expandedImageView.setVisibility(View.VISIBLE);

    expandedImageView.setPivotX(0f);
    expandedImageView.setPivotY(0f);

    AnimatorSet set = new AnimatorSet();
    set
            .play(ObjectAnimator.ofFloat(expandedImageView, View.X,
                    startBounds.left, finalBounds.left))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
                    startBounds.top, finalBounds.top))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
            startScale, 1f)).with(ObjectAnimator.ofFloat(expandedImageView,
                    View.SCALE_Y, startScale, 1f));
    set.setDuration(mShortAnimationDuration);
    set.setInterpolator(new DecelerateInterpolator());
    set.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mCurrentAnimator = null;
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            mCurrentAnimator = null;
        }
    });
    set.start();
    mCurrentAnimator = set;
}

startBounds 变量是全局的,因为我需要它来知道最小化过程的位置。这里是最小化方法:

    private void minimizeViewFromThumb(final View thumbView) {
    if (mCurrentAnimator != null) {
                    mCurrentAnimator.cancel();
                }

                AnimatorSet set = new AnimatorSet();
                set.play(ObjectAnimator
                            .ofFloat(expandedImageView, View.X, startBounds.left))
                            .with(ObjectAnimator
                                    .ofFloat(expandedImageView, 
                                            View.Y,startBounds.top))
                            .with(ObjectAnimator
                                    .ofFloat(expandedImageView, 
                                            View.SCALE_X, startScaleFinal))
                            .with(ObjectAnimator
                                    .ofFloat(expandedImageView, 
                                            View.SCALE_Y, startScaleFinal));
                set.setDuration(mShortAnimationDuration);
                set.setInterpolator(new DecelerateInterpolator());
                set.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {


                thumbView.setAlpha(1f);
                    expandedImageView.setVisibility(View.GONE);
                    mCurrentAnimator = null;
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    thumbView.setAlpha(1f);
                    expandedImageView.setVisibility(View.GONE);
                    mCurrentAnimator = null;
                }
            });
            set.start();
            mCurrentAnimator = set;
}

如果我调试整个过程,我可以看到方法 zoomViewFromThumb 中的 getGlobalVisibleRect 方法给了我另一个值。

如果我调试线路

finalBounds.offset(-globalOffset.x, -globalOffset.y);

第一次这两个参数是 0 和 -60,第二次(最小化和重新创建后有 15 和 360。

我不知道为什么会这样。

我尝试从给定的 thumbView 设置 View.X 和 View.Y 参数追加,我尝试在 ObjectAnimator 中使用 View.X、View.Y 参数的常量值,但没有解决我的问题。

现在请帮助我。

问候马努

1. 编辑:失败出现在 Android 4.1.2 上

2.编辑:这里是xml文件,第一个是代表我的主要活动的xml文件(带有动画),第二个代表我在主要xml的FrameLayout中推送的TableLayout。(请注意,目前我正在工作,我无法访问原始文件,现在这些 xml 文件在我记忆中都很好)

首先

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relZoom"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/frameZoomOne"
        android:layout_width="160dp"
        android:layout_height="215dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="10dp" >
    </FrameLayout>

    <FrameLayout
        android:id="@+id/frameZoomTwo"
        android:layout_width="160dp"
        android:layout_height="215dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp" >
    </FrameLayout>

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="300dp"
        android:layout_height="408dp"
        android:visibility="invisible" >
    </FrameLayout>

    <FrameLayout
        android:id="@+id/containerTwo"
        android:layout_width="300dp"
        android:layout_height="408dp"
        android:visibility="invisible" >
    </FrameLayout>

</RelativeLayout>

第二

    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tableLayout1"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
        <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dip" >

        <TextView
            android:id="@+id/textView1"
            android:text="Column 1"
            android:textAppearance="?android:attr/textAppearanceLarge" />

         <TextView
            android:id="@+id/textView2"
            android:text="Column 2"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </TableRow>
    <TableRow
        android:id="@+id/tableRow2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dip" >

        <ImageView
            android:id="@+id/imgView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/android" />
    </TableRow>
    <TableRow
        android:id="@+id/tableRow3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dip" >

        <TextView
            android:id="@+id/textView3"
            android:text="Column 3"
            android:textAppearance="?android:attr/textAppearanceLarge" />

         <TextView
            android:id="@+id/textView4"
            android:text="Column 4"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </TableRow>
</TableLayout>

3.编辑:更正xml文件,现在添加活动:

public class SinglePlayerSp extends Activity implements OnClickListener
{
    private final Context mContext = this;
    private boolean mBackZoomOne = false;
    private FrameLayout frameZoomOne;
    private FrameLayout frameZoomTwo;
    private static Animator mCurrentAnimatorOne;
    private int mShortAnimationDuration;
    private float startScaleOne;
    private static Animator mCurrentAnimatorTwo;
    private float startScaleTwo;
    private Rect startBoundsOne;
    private Rect startBoundsTwo;
    private static View lastViewOne;
    private static View lastViewTwo;

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

        frameZoomOne = (FrameLayout) findViewById(R.id.frameZoomOne);
        frameZoomTwo = (FrameLayout) findViewById(R.id.frameZoomTwo);
        frameZoomOne.setOnClickListener(this);
        frameZoomTwo.setOnClickListener(this);

        mShortAnimationDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime);

        cardItems = getIntent().getParcelableArrayListExtra(CARD_ITEMS);

        java.util.Collections.shuffle(cardItems);

    }

private void flipCard(boolean playerOneDeck, final int selectionFromPlayer, final boolean result)
    {
        Card cardItemOne = null;

            if (oneCards.get(0) != null)
            {
                cardItemOne = oneCards.get(0);
            }

            if (!mBackZoomOne)
            {
                getFragmentManager().beginTransaction().setCustomAnimations(R.animator.card_flip_right_in,
                        R.animator.card_flip_right_out, R.animator.card_flip_left_in, R.animator.card_flip_left_out).replace(
                        R.id.frameZoomOne, new CardBackFragment()).commit();
                mBackZoomOne = true;
            }
            else
            {
                getFragmentManager().beginTransaction().setCustomAnimations(R.animator.card_flip_right_in,
                        R.animator.card_flip_right_out, R.animator.card_flip_left_in, R.animator.card_flip_left_out).replace(
                        R.id.frameZoomOne,
                        CardFrontFragment.newInstance(cardItemPlayerOne, selectionFromPlayer, playerOneDeck)).commit();
                mBackZoomOne = false;

                zoomViewOneFromThumb(frameZoomOne, cardItemOne);
            }
    }

private void zoomViewOneFromThumb(final View thumbView, final Card cardItem)
    {
        if (mCurrentAnimatorOne != null)
        {
            mCurrentAnimatorOne.cancel();
        }

        lastViewOne = thumbView;
        View.getDefaultSize(0, 0);
        final FrameLayout expandFrameLayout = (FrameLayout) findViewById(R.id.container);

        LayoutInflater inflater =
                (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layout = inflater.inflate(R.layout.fragment_card_front_clickable, null);

        TableRow rowOne = (TableRow) layout.findViewById(R.id.tableRow1);
        rowOne.setOnClickListener(this);

        TextView cardone = (TextView) layout.findViewById(R.id.textView1);
        TextView cardtwo = (TextView) layout.findViewById(R.id.textView2);
        TextView cardthree = (TextView) layout.findViewById(R.id.textView3);
        TextView cardfour = (TextView) layout.findViewById(R.id.textView4);

        Locale locale = getApplicationContext().getResources().getConfiguration().locale;

        cardone.setText(cardItem.TextOne());
        cardtwo.setText(cardItem.getTextTwo());
        cardthree.setText(cardItem.getTextThree());
        cardfour.setText(cardItem.TextFour());

        expandFrameLayout.addView(layout);

        startBoundsOne = new Rect();
        final Rect finalBounds = new Rect();
        final Point globalOffset = new Point();

        thumbView.getGlobalVisibleRect(startBoundsOne);
        findViewById(R.id.containerSp).getGlobalVisibleRect(finalBounds, globalOffset);
        startBoundsOne.offset(-globalOffset.x, -globalOffset.y);
        finalBounds.offset(-globalOffset.x + 15, -globalOffset.y + 50);

        if ((float) finalBounds.width() / finalBounds.height() > (float) startBoundsOne.width()
                / startBoundsOne.height())
        {
            startScaleOne = (float) startBoundsOne.height() / finalBounds.height();
            float startWidth = startScaleOne * finalBounds.width();
            float deltaWidth = (startWidth - startBoundsOne.width()) / 2;
            startBoundsOne.left -= deltaWidth;
            startBoundsOne.right += deltaWidth;
        }
        else
        {
            startScaleOne = (float) startBoundsOne.width() / finalBounds.width();
            float startHeight = startScaleOne * finalBounds.height();
            float deltaHeight = (startHeight - startBoundsOne.height()) / 2;
            startBoundsOne.top -= deltaHeight;
            startBoundsOne.bottom += deltaHeight;
        }

        thumbView.setAlpha(0f);
        expandFrameLayout.setVisibility(View.VISIBLE);

        expandFrameLayout.setPivotX(0f);
        expandFrameLayout.setPivotY(0f);

        AnimatorSet set = new AnimatorSet();
        set.play(ObjectAnimator.ofFloat(expandFrameLayout, View.X, startBoundsOne.left, finalBounds.left)).with(
                ObjectAnimator.ofFloat(expandFrameLayout, View.Y, startBoundsOne.top, finalBounds.top)).with(
                ObjectAnimator.ofFloat(expandFrameLayout, View.SCALE_X, startScaleOne, 1f)).with(
                ObjectAnimator.ofFloat(expandFrameLayout, View.SCALE_Y, startScaleOne, 1f));
        set.setDuration(mShortAnimationDuration);
        set.setInterpolator(new DecelerateInterpolator());
        set.addListener(new AnimatorListenerAdapter()
        {
            @Override
            public void onAnimationEnd(Animator animation)
            {
                mCurrentAnimatorOne = null;
            }

            @Override
            public void onAnimationCancel(Animator animation)
            {
                mCurrentAnimatorOne = null;
            }
        });
        set.start();
        mCurrentAnimatorOne = set;
        startScaleFinal = startScaleOne; // with this or without this, i have the same problem
    }

private void minimizeViewOne(final View expandFrameLayout)
    {
        AnimatorSet set = new AnimatorSet();
        set.play(ObjectAnimator.ofFloat(expandFrameLayout, View.X, startBoundsOne.left)).with(
                ObjectAnimator.ofFloat(expandFrameLayout, View.Y, startBoundsOne.top)).with(
                ObjectAnimator.ofFloat(expandFrameLayout, View.SCALE_X, startScaleFinal)).with(
                ObjectAnimator.ofFloat(expandFrameLayout, View.SCALE_Y, startScaleFinal));
        set.setDuration(mShortAnimationDuration);
        set.setInterpolator(new DecelerateInterpolator());
        set.addListener(new AnimatorListenerAdapter()
        {
            @Override
            public void onAnimationEnd(Animator animation)
            {
                lastViewOne.setAlpha(1f);
                expandFrameLayout.setVisibility(View.GONE);
                mCurrentAnimatorOne = null;
            }

            @Override
            public void onAnimationCancel(Animator animation)
            {
                lastViewOne.setAlpha(1f);
                expandFrameLayout.setVisibility(View.GONE);
                mCurrentAnimatorOne = null;
            }
        });
        set.start();
        mCurrentAnimatorOne = set;
    }
}

好的,这就是完整的代码。最后是一个 onClick 方法,在那里我收到用户操作。从那里我调用minimizeView 方法,然后进行一些检查,然后我调用flipCard。就这样。

4

2 回答 2

4

根据谷歌开发者:

getGlobalVisibleRect(Rect r, Point globalOffset);

如果该视图的某些部分没有被它的任何父项裁剪,则在全局(根)坐标中返回 r 中的该区域。

例如: thumbView.getGlobalVisibleRect(startBounds);

这里假设 thumbview 的宽度为 100,高度为 75,marging 分别从左侧和顶部 16 和 51 此方法将值存储在 startBound(Rect) 中为 left 16 , top 51 , right 16+100 = 116 , bottom 51+75 = 126 . 即 (16 , 51 , 116 , 126)

于 2013-12-10T09:17:58.557 回答
0

我不确定您在哪里分配事件以关闭视图。但我会说导致错误的点是您读取一些变量的地方,例如 startScaleFinal = startScale;必须在放大动画开始之前完成, 并且可能还有其他变量。

我用不同的功能和框架视图发布我的完整工作示例:它运行良好。

活动:

/*
 * Copyright 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.android.animationsdemo;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;

/**
 * A sample showing how to zoom an image thumbnail to full-screen, by animating the bounds of the
 * zoomed image from the thumbnail bounds to the screen bounds.
 *
 * <p>In this sample, the user can touch one of two images. Touching an image zooms it in, covering
 * the entire activity content area. Touching the zoomed-in image hides it.</p>
 */
public class ZoomActivity extends FragmentActivity {
    /**
     * Hold a reference to the current animator, so that it can be canceled mid-way.
     */
    private Animator mCurrentAnimator;

    /**
     * The system "short" animation time duration, in milliseconds. This duration is ideal for
     * subtle animations or animations that occur very frequently.
     */
    private int mShortAnimationDuration;
    final Rect finalBounds = new Rect();
    final Point globalOffset = new Point();
    final Rect startBounds = new Rect();
    float startScale;
    FrameLayout expandedImageView;

    float startScaleFinal  ;


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

        // Hook up clicks on the thumbnail views.

        final View thumb1View = findViewById(R.id.thumb_button_1);
        thumb1View.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                zoomImageFromThumb(thumb1View, R.drawable.image1);
            }
        });

        final View thumb2View = findViewById(R.id.thumb_button_2);
        thumb2View.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                zoomImageFromThumb(thumb2View, R.drawable.image2);
            }
        });

        // Retrieve and cache the system's default "short" animation time.
        mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
    }


    private void zoomImageFromThumb(final View thumbView, int imageResId) {
        // If there's an animation in progress, cancel it immediately and proceed with this one.
        if (mCurrentAnimator != null) {
            mCurrentAnimator.cancel();
        }

        // Load the high-resolution "zoomed-in" image.
     expandedImageView = (FrameLayout) findViewById(R.id.expanded_image);


        // The start bounds are the global visible rectangle of the thumbnail, and the
        // final bounds are the global visible rectangle of the container view. Also
        // set the container view's offset as the origin for the bounds, since that's
        // the origin for the positioning animation properties (X, Y).
        thumbView.getGlobalVisibleRect(startBounds);
        findViewById(R.id.container).getGlobalVisibleRect(finalBounds, globalOffset);
        startBounds.offset(-globalOffset.x, -globalOffset.y);
        finalBounds.offset(-globalOffset.x, -globalOffset.y);

        // Adjust the start bounds to be the same aspect ratio as the final bounds using the
        // "center crop" technique. This prevents undesirable stretching during the animation.
        // Also calculate the start scaling factor (the end scaling factor is always 1.0).

        if ((float) finalBounds.width() / finalBounds.height()
                > (float) startBounds.width() / startBounds.height()) {
            // Extend start bounds horizontally
            startScale = (float) startBounds.height() / finalBounds.height();
            float startWidth = startScale * finalBounds.width();
            float deltaWidth = (startWidth - startBounds.width()) / 2;
            startBounds.left -= deltaWidth;
            startBounds.right += deltaWidth;
        } else {
            // Extend start bounds vertically
            startScale = (float) startBounds.width() / finalBounds.width();
            float startHeight = startScale * finalBounds.height();
            float deltaHeight = (startHeight - startBounds.height()) / 2;
            startBounds.top -= deltaHeight;
            startBounds.bottom += deltaHeight;
        }

        // Hide the thumbnail and show the zoomed-in view. When the animation begins,
        // it will position the zoomed-in view in the place of the thumbnail.
        thumbView.setAlpha(0f);
        expandedImageView.setVisibility(View.VISIBLE);

        // Set the pivot point for SCALE_X and SCALE_Y transformations to the top-left corner of
        // the zoomed-in view (the default is the center of the view).
        expandedImageView.setPivotX(0f);
        expandedImageView.setPivotY(0f);

        // Construct and run the parallel animation of the four translation and scale properties
        // (X, Y, SCALE_X, and SCALE_Y).
        AnimatorSet set = new AnimatorSet();
        set
                .play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left,
                        finalBounds.left))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top,
                        finalBounds.top))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1f));
        set.setDuration(mShortAnimationDuration);
        set.setInterpolator(new DecelerateInterpolator());
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mCurrentAnimator = null;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mCurrentAnimator = null;
            }
        });
        set.start();
        mCurrentAnimator = set;

        // Upon clicking the zoomed-in image, it should zoom back down to the original bounds
        // and show the thumbnail instead of the expanded image.
        startScaleFinal = startScale;
   expandedImageView.setOnClickListener(new View.OnClickListener() {


            @Override
            public void onClick(View view) {
                minimizeViewFromThumb(thumbView);
              }
        });
    }
    private void minimizeViewFromThumb(final View thumbView) {  

        // Upon clicking the zoomed-in image, it should zoom back down to the original bounds
        // and show the thumbnail instead of the expanded image.


                if (mCurrentAnimator != null) {
                    mCurrentAnimator.cancel();
                }

                // Animate the four positioning/sizing properties in parallel, back to their
                // original values.
                AnimatorSet set = new AnimatorSet();
                set
                        .play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left))
                        .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView, View.SCALE_X, startScaleFinal))
                        .with(ObjectAnimator
                                .ofFloat(expandedImageView, View.SCALE_Y, startScaleFinal));
                set.setDuration(mShortAnimationDuration);
                set.setInterpolator(new DecelerateInterpolator());
                set.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        thumbView.setAlpha(1f);
                        expandedImageView.setVisibility(View.GONE);
                        mCurrentAnimator = null;
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                        thumbView.setAlpha(1f);
                        expandedImageView.setVisibility(View.GONE);
                        mCurrentAnimator = null;
                    }
                });
                set.start();
                mCurrentAnimator = set;


    }
}

布局:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView style="?android:textAppearanceSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/message_zoom_touch_expand" />

        <!-- This is an example layout containing thumbnail image buttons that, when pressed,
             zoom in to show more detail. All of the zooming and animation logic is in
             the ZoomActivity class. -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:orientation="horizontal">

            <!-- These buttons don't have any decorations (3D bevel, etc.), but it's still
                 important to show feedback on touch or focus. The custom
                 "ToughHighlightImageButton" ImageButton subclass helps achieve this by drawing
                 the standard system "pressed" and "focused" overlay upon user interaction. -->

                  <FrameLayout
                android:id="@+id/thumb_button_1"
                android:layout_width="100dp"
                android:layout_height="75dp"
 android:background="@android:color/holo_orange_light"
                android:contentDescription="@string/description_image_2" />
            <FrameLayout
                android:id="@+id/thumb_button_2"
                android:layout_width="100dp"
                android:layout_height="75dp"
 android:background="@android:color/darker_gray"
                android:contentDescription="@string/description_image_2" />

        </LinearLayout>

    </LinearLayout>

    <!-- This initially-hidden ImageView will hold the expanded/zoomed version of the
         images above. Without transformations applied, it takes up the entire screen.
         To achieve the "zoom" animation, this view's bounds are animated from the
         bounds of the thumbnail buttons above, to its final laid-out bounds. The implementation
         of this animation is in the ZoomActivity class. -->
    <FrameLayout
        android:id="@+id/expanded_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible"
         android:background="@android:color/holo_blue_light" />

</FrameLayout>
于 2013-12-10T09:37:29.433 回答