ImageMovieAnimator - Image sliding Animator

This class is used to display a slide-moving image.

Usage

    ImageMovieAnimator imageAnimator = new ImageMovieAnimator(activity,(ImageView)findViewById(R.id.image),
                new int[]{R.drawable.image1,R.drawable.image2,...});
    imageAnimator.start();
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.LinearInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import me.lvxingshe.android.MyApplication;
import me.lvxingshe.android.R;

/**
 * Created by Luncrzs on 2015/10/18.
 */
public class ImageMovieAnimator {
    private Context mContext;
    private ImageView iv;
    private int[] images;
    private int thisImageId = 0;
    private int screenWidth = 0;
    private int screenHeight = 0;
    Bitmap bitmap;
    ValueAnimator animator;

    public ImageMovieAnimator(Context context, ImageView imageView, int[] imageResources){
        mContext = context;
        iv = imageView;
        images = imageResources;
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(displayMetrics);
        screenHeight = displayMetrics.heightPixels + getNavigationBarHeight();
        Log.d("ImageAnimator","height="+displayMetrics.heightPixels+" screenHeight="+screenHeight);
        screenWidth = displayMetrics.widthPixels;
    }

    public void start(){
        bitmap = BitmapFactory.decodeResource(mContext.getResources(),images[thisImageId]);
        iv.setImageBitmap(bitmap);
        double screenRatio = (double)screenWidth/screenHeight;
        double bitmapRatio = (double)bitmap.getWidth()/bitmap.getHeight();
        final int imageHeight = screenRatio<bitmapRatio?screenHeight:(int)(((double)screenWidth/bitmap.getWidth())*bitmap.getHeight());
        final int imageWidth = screenRatio<bitmapRatio?(int)(((double)screenHeight/bitmap.getHeight())*bitmap.getWidth()):screenWidth;
        final int paddingValue = (imageWidth-screenWidth)/2;
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(imageWidth,imageHeight);
        iv.setLayoutParams(params);
        iv.setPadding(paddingValue, 0, 0, 0);
        animator = ValueAnimator.ofFloat(1, -1);
        animator.setDuration(screenRatio < bitmapRatio ? paddingValue * 50 : 5000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();

                iv.setPadding((int) (value * paddingValue), 0, 0, 0);
                if (value > 0.9) {
                    iv.setAlpha((float) (0.3 + 7 * (1 - value)));
                } else if (value < -0.9) {
                    iv.setAlpha((float) (0.3 + 7 * (value + 1)));
                }
                iv.invalidate();
            }
        });
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                thisImageId = (thisImageId + 1) < images.length ? thisImageId + 1 : 0;
                start();
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

    public int getNavigationBarHeight(){
        Resources resources = mContext.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        if (resourceId > 0) {
            return resources.getDimensionPixelSize(resourceId);
        }
        return 0;
    }

    public void setHeight(int height){
        screenHeight = height;
    }

    public void stop(){
        if(animator!=null && animator.isRunning()){
            animator.end();
        }
    }
}

Shuffle Utility

This class is used to shuffle a list

import java.util.List;
import java.util.Random;

/**
 * Created by luncrzs on 16/1/27.
 */
public class Shuffle {

    public static List shuffle(List list){
        Random random = new Random(System.currentTimeMillis());
        for(int i=0; i<list.size(); i++){
            int a = random.nextInt(list.size());
            int b = random.nextInt(list.size());
            if(a == b){
                continue;
            }
            Object aObject = list.get(a);
            Object bObject = list.get(b);
            list.remove(a);
            list.add(a,bObject);
            list.remove(b);
            list.add(b,aObject);
        }
        return list;
    }

    public static int[][] shuffle(int[][] arr){
        Random random = new Random(System.currentTimeMillis());
        for(int i=0; i<arr.length; i++){
            int a = random.nextInt(arr.length);
            int b = random.nextInt(arr.length);
            if(a == b){
                continue;
            }
            int[] tmp = new int[arr[0].length];
            for(int j=0; j<arr[0].length; j++){
                tmp[j] = arr[a][j];
            }
            for(int j=0; j<arr[0].length; j++){
                arr[a][j] = arr[b][j];
            }
            for(int j=0; j<arr[0].length; j++){
                arr[b][j] = tmp[j];
            }
        }
        return arr;
    }
}

Statistic Utility

This class is used to generate A(m,n) and C(m,n) series

/**
 * Created by luncrzs on 16/1/27.
 */

/**
* Stats is a class that generate sequence of statistical function A(m,n) and C(m,n) where
* A(m,n) takes n objects from m objects in an order-sensitive case and C(m,n) takes n 
* objects from m objects in an order-insensitive case.
*/
public class Stats {

    /**
     * Example method to illustrate the usage of this class
     *
     * @param args
     */
    public static void main(String[] args){
        Stats stats = new Stats();
        int[][] results = stats.A(8,2);
        for(int i=0; i<results.length; i++){
            for(int j=0; j<results[i].length;j++){
                System.out.print(results[i][j]+" ");
            }
            System.out.print("\n");
        }
    }

    /**
     * A method used to calculate factorial of positive integer n
     *
     * @param n
     * @return facorial of n, aka n!
     */
    public static long factorial(int n){
        int result = 1;
        for(int i=1; i<=n; i++){
            result *= i;
        }
        return result;
    }

    /**
     * A method used to calculate how many possible arrangement are there
     * for C(m,n). Should be m!/(n!*(m-n)!)
     *
     * @param m how many objects are taken from
     * @param n how many objects are taken
     * @return how many possible arrangement are there
     */
    public static int cCount(int m, int n){
        // m should be larger than n
        if(m<n){
            return 0;
        }

        // When calculate C(200,198), factorial of 198 can be very large so transform
        // C(200,198) to C(200,2) which have the same number of arrangments
        if(n>m-n){
            return cCount(m,m-n);
        }

        long count = 1;

        // m!/(n!*(m-n)!) can be simplified to continuous multiplication from m-n+1 to m
        for(int i=m-n+1; i<=m; i++){
            count *= i;
        }
        return (int)(count/factorial(n));
    }

    /**
     * A method used to calculate how many possible arrangement are there
     * for A(m,n). Should be m!/(m-n)!
     *
     * @param m how many objects are taken from
     * @param n how many objects are taken
     * @return how many possible arrangement are there
     */
    public static int aCount(int m, int n){
        if(m<n){
            return 0;
        }
        int result = 1;
        for(int i=m; i>m-n; i--){
            result *= i;
        }
        return result;
    }

    int now = 0; // indicate which array index the calculation is in currently
    int[][] result; // result array used to storage possible sequence

    /**
     * This method is used to calculate statistical function C(m,n)
     *
     * @param m how many objects are taken from
     * @param n how many objects are taken
     * @return sequence of possible arrangements
     */
    public int[][] C(int m, int n){
        int count = cCount(m,n);
        result = new int[count][n];
        now = 0;

        proceedC(m,n,0,0); // recur to calculate the results

        return result;
    }

    /**
     * This method is recursion method that is used to calculate all
     * possible arrangments of function C(m,n)
     * @param m how many objects are taken from
     * @param n how many objects are taken
     * @param start the smallest object index that we are calculating
     * @param level at which index we are calculating in a possible arrangement
     */
    private void proceedC(int m, int n, int start, int level){
        if(n-level==1){ // Calculating last element in an arrangement,
            for(int i=start; i<m; i++){
                if(now+1<result.length){
                    for(int j=0; j<level; j++){
                        result[now+1][j] = result[now][j];
                    }
                }
                result[now++][level] = i; // Move to next possible arrangement
            }
        }else{ //Calculating middle element in an arrangement
            for(int i=start; i<m-n+level+1; i++){
                result[now][level] = i;
                proceedC(m,n,i+1,level+1);
            }
        }
    }

    /**
     * This method is used to calculate statistical function A(m,n)
     *
     * @param m how many objects are taken from
     * @param n how many objects are taken
     * @return sequence of possible arrangements
     */
    public int[][] A(int m, int n){
        int count = aCount(m,n);
        result = new int[count][n];
        now = 0;

        proceedA(m,n,0); // recur to calculate the results

        return result;
    }

    /**
     * This method is recursion method that is used to calculate all
     * possible arrangments of function A(m,n)
     * @param m how many objects are taken from
     * @param n how many objects are taken
     * @param level at which index we are calculating in a possible arrangement
     */
    private void proceedA(int m, int n, int level){
        if(n-level==1){ // Calculating last element in an arrangement,
            for(int i=0; i<m; i++){
                if(now==result.length){
                    break;
                }
                boolean skip = false;
                for(int k=0; k<level; k++){
                    if(i==result[now][k]){
                        skip = true; // we cannot take repeating object
                    }
                }
                if(skip){
                    continue;
                }
                if(now+1<result.length){
                    for(int j=0; j<level; j++){
                        result[now+1][j] = result[now][j];
                    }
                }
                result[now++][level] = i; // Move to next possible arrangement
            }
        }else{ //Calculating middle element in an arrangement
            for(int i=0; i<m; i++){
                if(now==result.length){
                    break;
                }
                boolean skip = false;
                for(int k=0; k<level; k++){
                    if(i==result[now][k]){
                        skip = true;
                    }
                }
                if(skip){
                    continue;
                }
                result[now][level] = i;
                proceedA(m,n,level+1);
            }
        }
    }
}

啦啦啦,试用typecho

Typecho

传说中的轻博客

今天心血来潮建了一个离线博客,以后技术各方面的东西都往这里面写吧,当然也免不了吐槽。主要typecho支持markdown,比较方便,又没有workpress那么笨重

2016年3月23日