简体   繁体   中英

Flip Images in a viewpager

I have a viewpager for a fullscreen image slider with horizontal swipe. What I am trying to do is put an image behind every image on the slider. Meaning, a user can click on a 'flip' button to reveal another image.

Below is my code however I have two issues:

  1. The first time I click the flip button, it flips the image but only to reveal the same image. However, when I click it the second time it works :).
  2. The flip button only works on the first image. When I swipe right or left the flip button doesn't work anymore. Any help?

Note: I am using a fullscreenActivity theme which hides the UI control until the user clicks on the image.

FullscreenActivity.java

package me.zamaaan.wallpaper;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import me.zamaaan.wallpaper.util.SystemUiHider;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import static me.zamaaan.wallpaper.HeavyLifter.FAIL;
import static me.zamaaan.wallpaper.HeavyLifter.SUCCESS;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;


import java.util.ArrayList;
import java.util.List;

/** A helper class that will do the heavy work of decoding images and actually setting the wallpaper */


/**
 * An example full-screen activity that shows and hides the system UI (i.e.
 * status bar and navigation/system bar) with user interaction.
 * 
 * @see SystemUiHider
 */
public class FullscreenActivity extends Activity implements OnClickListener, AnimationListener{
    /**
     * Whether or not the system UI should be auto-hidden after
     * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
     */
    private static final boolean AUTO_HIDE = true;
    private HeavyLifter chuckNorris;
    private Animation animation1;
    private Animation animation2;
    private boolean isBackOfCardShowing = true;

    /*
    an array with the ids of the images for the viewpager

     */
    public Integer[] mImageIds = {
            R.drawable.background1, R.drawable.background2,
            R.drawable.background3, R.drawable.background4,
            R.drawable.background1, R.drawable.background2,
            R.drawable.background1, R.drawable.background2,
            R.drawable.background3, R.drawable.background4,
            R.drawable.background1, R.drawable.background2,
            R.drawable.background3
    };
    /*
    an array with the ids of the images for the back flip of each image in the viewpager
     */
    public Integer[] mBackIds = {
            R.drawable.splash, R.drawable.splash,
            R.drawable.splash, R.drawable.splash,
            R.drawable.splash, R.drawable.splash,
            R.drawable.splash, R.drawable.splash,
            R.drawable.splash, R.drawable.splash,
            R.drawable.splash, R.drawable.splash,
            R.drawable.splash
    };

    /**
     * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
     * user interaction before hiding the system UI.
     */
    private static final int AUTO_HIDE_DELAY_MILLIS = 3000;

    /**
     * If set, will toggle the system UI visibility upon interaction. Otherwise,
     * will show the system UI visibility upon interaction.
     */
    private static final boolean TOGGLE_ON_CLICK = true;

    /**
     * The flags to pass to {@link SystemUiHider#getInstance}.
     */
    private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;

    /**
     * The instance of the {@link SystemUiHider} for this activity.
     */
    private SystemUiHider mSystemUiHider;

    /**
     * The pager widget, which handles animation and allows swiping horizontally to access previous
     * and next wizard steps.
     */
    private ViewPager mPager;

    /**
     * The pager adapter, which provides the pages to the view pager widget.
     */
    private PagerAdapter mPagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_fullscreen);
        animation1 = AnimationUtils.loadAnimation(this, R.anim.to_middle);
        animation1.setAnimationListener(this);
        animation2 = AnimationUtils.loadAnimation(this, R.anim.from_middle);
        animation2.setAnimationListener(this);
        findViewById(R.id.flip).setOnClickListener(this);

        // Loop through the ids to create a list of full screen image views
        ImageAdapter imageAdapter = new ImageAdapter(this);
        List<ImageView> images = new ArrayList<ImageView>();

        for (int i = 0; i < imageAdapter.getCount(); i++) {
            ImageView imageView = new ImageView(this);
            imageView.setId(i);
            imageView.setImageResource(imageAdapter.mThumbIds[i]);
            imageView.setScaleType(ImageView.ScaleType.FIT_XY);
            images.add(imageView);
        }

        final View controlsView = findViewById(R.id.fullscreen_content_controls);
        final View contentView = findViewById(R.id.view_pager);

        // Set up an instance of SystemUiHider to control the system UI for
        // this activity.
        mSystemUiHider = SystemUiHider.getInstance(this, contentView, HIDER_FLAGS);
        mSystemUiHider.setup();
        mSystemUiHider.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() {
                    // Cached values.
                    int mControlsHeight;
                    int mShortAnimTime;

                    @Override
                    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
                    public void onVisibilityChange(boolean visible) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
                            // If the ViewPropertyAnimator API is available
                            // (Honeycomb MR2 and later), use it to animate the
                            // in-layout UI controls at the bottom of the
                            // screen.
                            if (mControlsHeight == 0) {
                                mControlsHeight = controlsView.getHeight();
                            }
                            if (mShortAnimTime == 0) {
                                mShortAnimTime = getResources().getInteger(
                                        android.R.integer.config_shortAnimTime);
                            }
                            controlsView
                                    .animate()
                                    .translationY(visible ? 0 : mControlsHeight)
                                    .setDuration(mShortAnimTime);
                        } else {
                            // If the ViewPropertyAnimator APIs aren't
                            // available, simply show or hide the in-layout UI
                            // controls.
                            controlsView.setVisibility(visible ? View.VISIBLE
                                    : View.GONE);
                        }

                        if (visible && AUTO_HIDE) {
                            // Schedule a hide().
                            delayedHide(AUTO_HIDE_DELAY_MILLIS);
                        }
                    }
                });

        // Set up the user interaction to manually show or hide the system UI.
        contentView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (TOGGLE_ON_CLICK) {
                    mSystemUiHider.toggle();
                } else {
                    mSystemUiHider.show();
                }
            }
        });

        // Upon interacting with UI controls, delay any scheduled hide()
        // operations to prevent the jarring behavior of controls going away
        // while interacting with the UI.
        findViewById(R.id.btnSetAsWallpaper).setOnTouchListener(
                mDelayHideTouchListener);
        findViewById(R.id.btnSaveWallpaper).setOnTouchListener(
                mDelayHideTouchListener);



        // Finally create the adapter
        ImagePagerAdapter imagePagerAdapter = new ImagePagerAdapter(images);
        ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
        viewPager.setAdapter(imagePagerAdapter);

        // Set the ViewPager to point to the selected image from the previous activity
        // Selected image id
        int position = getIntent().getExtras().getInt("id");
        viewPager.setCurrentItem(position);
        //set title of Image
        this.setTitle(imageAdapter.mThumbTitles[position]);
        // Load are heavy lifter (goes and does work on another thread), to get a response after the lifters thread
        // has finished we pass in a Handler that will be notified when it completes
        chuckNorris = new HeavyLifter(this, chuckFinishedHandler);

    }


    @Override
    public void onClick(View v) {
        v.setEnabled(false);
        ((ImageView)findViewById(getIntent().getExtras().getInt("id"))).clearAnimation();
        ((ImageView)findViewById(getIntent().getExtras().getInt("id"))).setAnimation(animation1);
        ((ImageView)findViewById(getIntent().getExtras().getInt("id"))).startAnimation(animation1);
    }
    @Override
    public void onAnimationEnd(Animation animation) {
        int i = getIntent().getExtras().getInt("id");
        if (animation==animation1) {
            if (isBackOfCardShowing) {
                ((ImageView)findViewById(i)).setImageResource(mImageIds[i]);
            } else {
                ((ImageView)findViewById(i)).setImageResource(mBackIds[i]);
            }
            ((ImageView)findViewById(getIntent().getExtras().getInt("id"))).clearAnimation();
            ((ImageView)findViewById(getIntent().getExtras().getInt("id"))).setAnimation(animation2);
            ((ImageView)findViewById(getIntent().getExtras().getInt("id"))).startAnimation(animation2);
        } else {
            isBackOfCardShowing=!isBackOfCardShowing;
            findViewById(R.id.flip).setEnabled(true);
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onAnimationStart(Animation animation) {
        // TODO Auto-generated method stub

    }
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        // Trigger the initial hide() shortly after the activity has been
        // created, to briefly hint to the user that UI controls
        // are available.
        delayedHide(100);
    }

    /**
     * Touch listener to use for in-layout UI controls to delay hiding the
     * system UI. This is to prevent the jarring behavior of controls going away
     * while interacting with activity UI.
     */
    View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (AUTO_HIDE) {
                delayedHide(AUTO_HIDE_DELAY_MILLIS);
            }
            return false;
        }
    };

    Handler mHideHandler = new Handler();
    Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            mSystemUiHider.hide();
        }
    };

    /**
     * Schedules a call to hide() in [delay] milliseconds, canceling any
     * previously scheduled calls.
     */
    private void delayedHide(int delayMillis) {
        mHideHandler.removeCallbacks(mHideRunnable);
        mHideHandler.postDelayed(mHideRunnable, delayMillis);
    }

    /**
     * Called from XML when the save wallpaper button is pressed
     * Thie retrieves the id of the current image from our list
     * It then asks chuck to save it as a wallpaper!
     * The chuckHandler will be called when this operation is complete
     * @param v
     */

    public void saveWallpaper(View v) {
         // get intent data
        Intent i = getIntent();

        // Selected image id
        int position = i.getExtras().getInt("id");
        ImageAdapter imageAdapter = new ImageAdapter(this);


     // Show a toast message on successful save
        if(chuckNorris.saveResourceAsWallpaper(imageAdapter.mThumbIds[position])){
            Toast.makeText(FullscreenActivity.this, "Image Saved to ZamaaanWallpaper folder", Toast.LENGTH_SHORT).show();
        }
        else{
            Toast.makeText(FullscreenActivity.this, "Image couldn't be saved, try again", Toast.LENGTH_SHORT).show();
        }

    }

    /**
     * Called from XML when the set wallpaper button is pressed
     * Thie retrieves the id of the current image from our list
     * It then asks chuck to set it as a wallpaper!
     * The chuckHandler will be called when this operation is complete
     * @param v
     */
    public void setAsWallpaper(View v) {
         // get intent data
        Intent i = getIntent();

        // Selected image id
        int position = i.getExtras().getInt("id");
        ImageAdapter imageAdapter = new ImageAdapter(this);

        chuckNorris.setResourceAsWallpaper(imageAdapter.mThumbIds[position]);
    }

    /**
     * This is the handler that is notified when are HeavyLifter is finished doing an operation
     */
    private Handler chuckFinishedHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
            case SUCCESS:
                Toast.makeText(FullscreenActivity.this, "Wallpaper set", Toast.LENGTH_SHORT).show();
                break;
            case FAIL:
                Toast.makeText(FullscreenActivity.this, "Wallper NOT set, try again", Toast.LENGTH_SHORT).show();
                break;
            default:
                super.handleMessage(msg);
            }
        }
    };



    }

I fixed my issues. I simply had to :

  1. Change the boolean isBackOfCardShowing to an array of boolean for each page and intialize it to false.
  2. Use viewpager.getCurrentItem() to get the position of the current page instead of what I was doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM