我的应用程序中有一个带缩略图的ListView作为ImageViews,我希望用户单击缩略图并获得缩放的图像。
就像本教程一样:
Android Zoom View

我的适配器已更新并发布在下面,这是我的ActiviyList:

public class WarmupList extends ListActivity {
    private ListView listView;
    private ArrayList<Warmup> mWarmup = new ArrayList<Warmup>();

    private WarmupAdapter adapter;
    private Runnable viewParts;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_warmup);

        listView = getListView();

        // adapter
        adapter = new WarmupAdapter(this, R.layout.item_warmup, mWarmup);
        listView.setAdapter(adapter);

        // here we are defining our runnable thread.
        viewParts = new Runnable(){
            public void run(){
                handler.sendEmptyMessage(0);
            }
        };

        // here we call the thread we just defined - it is sent to the handler below.
        Thread thread =  new Thread(null, viewParts, "WorkoutThread");
        thread.start();
    }

    private Handler handler = new Handler()
     {
        public void handleMessage(Message msg)
        {
            // TODO entering warmups

            mWarmup.add(new Warmup("Warmup 1", new ArrayList<String>(), "Move left and right like a ho", R.drawable.ic_launcher));
            mWarmup.get(0).getTargetMuscles().add("Shoulders");
            mWarmup.get(0).getTargetMuscles().add("Butt");

            mWarmup.add(new Warmup("Warmup 2", new ArrayList<String>(), "Jump and jump and jump", R.drawable.ic_launcher));
            mWarmup.get(1).getTargetMuscles().add("All muscles");
            mWarmup.get(1).getTargetMuscles().add("Ass too");

            adapter = new WarmupAdapter(WarmupList.this, R.layout.item_warmup, mWarmup);
            setListAdapter(adapter);
        }
    };
}


这行得通吗?任何建议将被认真考虑!

[EDIT_1]即使不正确,我也设法使其正常运行。我将zoomImageFromThumb()添加到了适配器。

public class WarmupAdapter extends ArrayAdapter<Warmup> {

    private ArrayList<Warmup> warmups;
    private LayoutInflater inflater;

    private TextView warmupNameView;
    private TextView targetMuscles;
    private TextView warmupInfo;
    private View warmupImage;

    public WarmupAdapter(Context context, int textViewResourceId,
            ArrayList<Warmup> objects) {
        super(context, textViewResourceId, objects);

        warmups = objects;
        inflater = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);

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

    }

    public View getView(int position, final View convertView, ViewGroup parent) {
        View view = convertView;

        if (view == null)
            view = inflater.inflate(R.layout.item_warmup, null);

        warmupNameView = (TextView) view.findViewById(R.id.tv_warmup_name);
        targetMuscles = (TextView) view.findViewById(R.id.tv_warmup_muscle);
        warmupInfo = (TextView) view.findViewById(R.id.tv_warmup_info);
        warmupImage = (ImageView) view.findViewById(R.id.thumb_button_1);

        final Warmup warmup = warmups.get(position);

        if (warmup != null) {
            warmupNameView.setText(warmup.getName());
            targetMuscles.setText("Target Muscles: "
                    + warmup.getTargetMuscles().get(0));

            ((ImageView) warmupImage).setImageResource(warmup.getThumbResId());

            for (int i = 1; i < warmup.getTargetMuscles().size(); i++) {
                targetMuscles.setText(targetMuscles.getText() + ", "
                        + warmup.getTargetMuscles().get(i));
            }

            warmupInfo.setText(warmup.getInfo());

            warmupImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    zoomImageFromThumb(warmupImage, warmup.getImageResId());
                    Toast.makeText(getContext(), "on click works", Toast.LENGTH_SHORT).show();
                }
            });

        }

        return view;
    }

    private Animator mCurrentAnimator;

    private int mShortAnimationDuration;

    private void zoomImageFromThumb(final View thumbView,
            int imageResId) {
        // get container and image view from warmupList activity


        // 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.
        final ImageView expandedImageView = WarmupList.imageView;
        expandedImageView.setImageResource(imageResId);

        // Calculate the starting and ending bounds for the zoomed-in image.
        // This step
        // involves lots of math. Yay, math.
        final Rect startBounds = new Rect();
        final Rect finalBounds = new Rect();
        final Point globalOffset = new Point();

        // 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);
        WarmupList.containerView.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).
        float startScale;
        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.
        final float startScaleFinal = startScale;
        expandedImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                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;
            }
        });
    }


}


我使用以下方法从列表活动中获取containerView和imageView:

public static View containerView;
public static ImageView imageView;


并在listActivity的onCreate方法中:

containerView = findViewById(R.id.container);
imageView = (ImageView) findViewById(R.id.expanded_image);


现在,当我单击每个thumbView时,都会放大所需的图像,但是您可能已经注意到zoomImageFromThumb()方法隐藏了被单击的thumbView并为其投射了动画。问题是,无论我单击哪个thumbView,总是将ListView中的最后一个thumbView设置为动画并设置为不可见。

[Edit_2]没关系,我解决了问题,工作正常。如果有人偶然发现相同的问题,请告诉我,我会给出答案。

最佳答案

这就是我最终的WarmupAdapter.java的样子:

public class WarmupAdapter extends ArrayAdapter<Warmup> {

    private ArrayList<Warmup> warmups;  private LayoutInflater inflater;

    private TextView warmupNameView;    private TextView targetMuscles;

    public WarmupAdapter(Context context, int textViewResourceId,           ArrayList<Warmup> objects) {        super(context, textViewResourceId, objects);

        warmups = objects;      inflater = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
                // Retrieve and cache the system's default "short" animation time.      mShortAnimationDuration = getContext().getResources().getInteger(
                android.R.integer.config_shortAnimTime);

    }

    public View getView(int position, final View convertView, ViewGroup parent) {       View view = convertView;        View warmupImage;
                if (view == null)           view = inflater.inflate(R.layout.item_warmup, null);

        warmupNameView = (TextView) view.findViewById(R.id.tv_warmup_name);         targetMuscles = (TextView) view.findViewById(R.id.tv_warmup_muscle);
                warmupImage = (ImageView) view.findViewById(R.id.thumb_button_1);

        final Warmup warmup = warmups.get(position);

        if (warmup != null) {           warmupNameView.setText(warmup.getName());           targetMuscles.setText("Targets: "
                    + warmup.getTargetMuscles().get(0));

            ((ImageView) warmupImage).setImageResource(warmup.getThumbResId());

            for (int i = 1; i < warmup.getTargetMuscles().size(); i++) {
                targetMuscles.setText(targetMuscles.getText() + ", "
                        + warmup.getTargetMuscles().get(i));            }

            warmupImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    ImageView wmpImage = (ImageView) v.findViewById(R.id.thumb_button_1);

                    zoomImageFromThumb(wmpImage, warmup.getImageResId());
                }           });
                    }
                return view;    }

    private Animator mCurrentAnimator;

    private int mShortAnimationDuration;

    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.      final ImageView expandedImageView = WarmupList.imageView;       expandedImageView.setImageResource(imageResId);

        // Calculate the starting and ending bounds for the zoomed-in image.        // This step        // involves lots of math. Yay, math.        final Rect startBounds = new Rect();        final Rect finalBounds = new Rect();        final Point globalOffset = new Point();

        // 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);        WarmupList.containerView.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).         float startScale;       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.        final float startScaleFinal = startScale;       expandedImageView.setOnClickListener(new View.OnClickListener() {           @Override           public void onClick(View view) {
                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;             }       });     }

     }

09-05 17:49