Android实现Windows 8磁贴(Tile)样式按钮

2018-07-20    来源:open-open

容器云强势上线!快速搭建集群,上万Linux镜像随意使用

我在网上流传的代码基础上精简、整理出一个简单的类,我暂时把它命名为:Windows8TileImageView,即Windows 8磁贴(Tile)样式按钮,Windows8TileImageView其实就是继承于标准Android ImageView,单击该Windows8TileImageView有收缩、侧边收缩等比较有趣的效果。现在把 Windows8TileImageView这个类的全部代码贴出来:
    package windows8.tile;  
      
    import android.annotation.SuppressLint;  
    import android.content.Context;  
    import android.graphics.Camera;  
    import android.graphics.Canvas;  
    import android.graphics.Matrix;  
    import android.graphics.Paint;  
    import android.graphics.PaintFlagsDrawFilter;  
    import android.graphics.drawable.BitmapDrawable;  
    import android.graphics.drawable.Drawable;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.util.AttributeSet;  
    import android.view.MotionEvent;  
    import android.widget.ImageView;  
      
    public class Windows8TileImageView extends ImageView {  
        public static final int Rotate_Handler_Message_Start = 1;  
        public static final int Rotate_Handler_Message_Turning = 2;  
        public static final int Rotate_Handler_Message_Turned = 3;  
        public static final int Rotate_Handler_Message_Reverse = 6;  
      
        public static final int Scale_Handler_Message_Start = 1;  
        public static final int Scale_Handler_Message_Turning = 2;  
        public static final int Scale_Handler_Message_Turned = 3;  
        public static final int Scale_Handler_Message_Reverse = 6;  
      
        private boolean isAntiAlias = true;  
        private boolean scaleOnly = false;  
        private boolean isSizeChanged = false;  
        private boolean isShowAnimation = true;  
        private int rotateDegree = 10;  
        private boolean isFirst = true;  
        private float minScale = 0.95f;  
        private int vWidth;  
        private int vHeight;  
        private boolean isAnimationFinish = true, isActionMove = false,  
                isScale = false;  
        private Camera camera;  
        boolean XbigY = false;  
        float RolateX = 0;  
        float RolateY = 0;  
        OnViewClick onclick = null;  
      
        public Windows8TileImageView(Context context) {  
            super(context);  
            camera = new Camera();  
        }  
      
        public Windows8TileImageView(Context context, AttributeSet attrs) {  
            super(context, attrs);  
            camera = new Camera();  
        }  
      
        public void SetAnimationOnOff(boolean oo) {  
            isShowAnimation = oo;  
        }  
      
        public void setOnClickIntent(OnViewClick onclick) {  
            this.onclick = onclick;  
        }  
      
        @SuppressLint("DrawAllocation")  
        @Override  
        protected void onDraw(Canvas canvas) {  
            super.onDraw(canvas);  
            if (isFirst) {  
                isFirst = false;  
                init();  
            }  
            canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG  
                    | Paint.FILTER_BITMAP_FLAG));  
        }  
      
        public void init() {  
            vWidth = getWidth() - getPaddingLeft() - getPaddingRight();  
            vHeight = getHeight() - getPaddingTop() - getPaddingBottom();  
            Drawable drawable = getDrawable();  
            BitmapDrawable bd = (BitmapDrawable) drawable;  
            bd.setAntiAlias(isAntiAlias);  
        }  
      
        @Override  
        public boolean onTouchEvent(MotionEvent event) {  
            super.onTouchEvent(event);  
            if (!isShowAnimation)  
                return true;  
      
            switch (event.getAction() & MotionEvent.ACTION_MASK) {  
            case MotionEvent.ACTION_DOWN:  
                float X = event.getX();  
                float Y = event.getY();  
                RolateX = vWidth / 2 - X;  
                RolateY = vHeight / 2 - Y;  
                XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false;  
      
                isScale = X > vWidth / 3 && X < vWidth * 2 / 3 && Y > vHeight / 3  
                        && Y < vHeight * 2 / 3;  
                isActionMove = false;  
      
                if (isScale) {  
                    if (isAnimationFinish && !isSizeChanged) {  
                        isSizeChanged = true;  
                        scale_handler.sendEmptyMessage(Scale_Handler_Message_Start);  
                    }  
                } else {  
                    if (scaleOnly) {  
                        scale_handler.sendEmptyMessage(Scale_Handler_Message_Start);  
                    } else {  
                        rotate_Handler  
                                .sendEmptyMessage(Rotate_Handler_Message_Start);  
                    }  
                }  
                break;  
            case MotionEvent.ACTION_MOVE:  
                float x = event.getX();  
                float y = event.getY();  
                if (x > vWidth || y > vHeight || x < 0 || y < 0) {  
                    isActionMove = true;  
                } else {  
                    isActionMove = false;  
                }  
      
                break;  
            case MotionEvent.ACTION_UP:  
                if (isScale) {  
                    if (isSizeChanged)  
                        scale_handler  
                                .sendEmptyMessage(Scale_Handler_Message_Reverse);  
                } else {  
                    rotate_Handler.sendEmptyMessage(Rotate_Handler_Message_Reverse);  
                }  
                break;  
            }  
            return true;  
        }  
      
        public interface OnViewClick {  
            public void onClick();  
        }  
      
        @SuppressLint("HandlerLeak")  
        private Handler rotate_Handler = new Handler() {  
            private Matrix matrix = new Matrix();  
            private float count = 0;  
      
            // private boolean clickGuolv = false;  
            @Override  
            public void handleMessage(Message msg) {  
                super.handleMessage(msg);  
                matrix.set(getImageMatrix());  
                switch (msg.what) {  
                case Rotate_Handler_Message_Start:  
                    count = 0;  
                    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));  
                    rotate_Handler.sendEmptyMessage(Rotate_Handler_Message_Turning);  
                    break;  
                case Rotate_Handler_Message_Turning:  
                    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));  
                    count++;  
                    if (count < getDegree()) {  
                        rotate_Handler  
                                .sendEmptyMessage(Rotate_Handler_Message_Turning);  
                    } else {  
                        isAnimationFinish = true;  
                    }  
                    break;  
                case Rotate_Handler_Message_Turned:  
                    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));  
                    if (count > 0) {  
                        rotate_Handler  
                                .sendEmptyMessage(Rotate_Handler_Message_Turned);  
                    } else {  
                        isAnimationFinish = true;  
                        if (!isActionMove && onclick != null) {  
                            onclick.onClick();  
                        }  
                    }  
                    count--;  
                    count--;  
                    break;  
                case Rotate_Handler_Message_Reverse:  
                    count = getDegree();  
                    beginRotate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));  
                    rotate_Handler.sendEmptyMessage(Rotate_Handler_Message_Turned);  
                    break;  
                }  
            }  
        };  
      
        private synchronized void beginRotate(Matrix matrix, float rotateX,  
                float rotateY) {  
            // Bitmap bm = getImageBitmap();  
            int scaleX = (int) (vWidth * 0.5f);  
            int scaleY = (int) (vHeight * 0.5f);  
            camera.save();  
            camera.rotateX(RolateY > 0 ? rotateY : -rotateY);  
            camera.rotateY(RolateX < 0 ? rotateX : -rotateX);  
            camera.getMatrix(matrix);  
            camera.restore();  
            // 控制中心点  
            if (RolateX > 0 && rotateX != 0) {  
                matrix.preTranslate(-vWidth, -scaleY);  
                matrix.postTranslate(vWidth, scaleY);  
            } else if (RolateY > 0 && rotateY != 0) {  
                matrix.preTranslate(-scaleX, -vHeight);  
                matrix.postTranslate(scaleX, vHeight);  
            } else if (RolateX < 0 && rotateX != 0) {  
                matrix.preTranslate(-0, -scaleY);  
                matrix.postTranslate(0, scaleY);  
            } else if (RolateY < 0 && rotateY != 0) {  
                matrix.preTranslate(-scaleX, -0);  
                matrix.postTranslate(scaleX, 0);  
            }  
            setImageMatrix(matrix);  
        }  
      
        private Handler scale_handler = new Handler() {  
            private Matrix matrix = new Matrix();  
            private float s;  
            int count = 0;  
      
            @Override  
            public void handleMessage(Message msg) {  
                super.handleMessage(msg);  
                matrix.set(getImageMatrix());  
                switch (msg.what) {  
                case Scale_Handler_Message_Start:  
                    if (!isAnimationFinish) {  
                        return;  
                    } else {  
                        isAnimationFinish = false;  
                        isSizeChanged = true;  
                        count = 0;  
                        s = (float) Math.sqrt(Math.sqrt(minScale));  
                        beginScale(matrix, s);  
                        scale_handler  
                                .sendEmptyMessage(Scale_Handler_Message_Turning);  
                    }  
                    break;  
                case Scale_Handler_Message_Turning:  
                    beginScale(matrix, s);  
                    if (count < 4) {  
                        scale_handler  
                                .sendEmptyMessage(Scale_Handler_Message_Turning);  
                    } else {  
                        isAnimationFinish = true;  
                        if (!isSizeChanged && !isActionMove && onclick != null) {  
                            onclick.onClick();  
                        }  
                    }  
                    count++;  
                    break;  
                case Scale_Handler_Message_Reverse:  
                    if (!isAnimationFinish) {  
                        scale_handler  
                                .sendEmptyMessage(Scale_Handler_Message_Reverse);  
                    } else {  
                        isAnimationFinish = false;  
                        count = 0;  
                        s = (float) Math.sqrt(Math.sqrt(1.0f / minScale));  
                        beginScale(matrix, s);  
                        scale_handler  
                                .sendEmptyMessage(Scale_Handler_Message_Turning);  
                        isSizeChanged = false;  
                    }  
                    break;  
                }  
            }  
        };  
      
        private synchronized void beginScale(Matrix matrix, float scale) {  
            int scaleX = (int) (vWidth * 0.5f);  
            int scaleY = (int) (vHeight * 0.5f);  
            matrix.postScale(scale, scale, scaleX, scaleY);  
            setImageMatrix(matrix);  
        }  
      
        public int getDegree() {  
            return rotateDegree;  
        }  
      
        public void setDegree(int degree) {  
            rotateDegree = degree;  
        }  
      
        public float getScale() {  
            return minScale;  
        }  
      
        public void setScale(float scale) {  
            minScale = scale;  
        }  
    }  

Windows8TileImageView使用方法很简单,和Android的ImageView类似,直接把它作为一个View使用。比如可以在布局文件中这样使用:

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:gravity="center"  
        android:orientation="vertical" >  
      
        <LinearLayout  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
            android:orientation="vertical" >  
      
            <LinearLayout  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:orientation="horizontal" >  
      
                <LinearLayout  
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"  
                    android:orientation="vertical" >  
      
                    <windows8.tile.Windows8TileImageView  
                        android:id="@+id/c_joke"  
                        android:layout_width="wrap_content"  
                        android:layout_height="wrap_content"  
                        android:layout_margin="2dp"  
                        android:scaleType="matrix"  
                        android:src="@drawable/left_top" />  
      
                    <windows8.tile.Windows8TileImageView  
                        android:id="@+id/c_idea"  
                        android:layout_width="wrap_content"  
                        android:layout_height="wrap_content"  
                        android:layout_margin="2dp"  
                        android:scaleType="matrix"  
                        android:src="@drawable/left_bottom" />  
                </LinearLayout>  
      
                <windows8.tile.Windows8TileImageView  
                    android:id="@+id/c_constellation"  
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"  
                    android:layout_margin="2dp"  
                    android:scaleType="matrix"  
                    android:src="@drawable/right" />  
            </LinearLayout>  
      
            <windows8.tile.Windows8TileImageView  
                android:id="@+id/c_recommend"  
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"  
                android:layout_margin="2dp"  
                android:scaleType="matrix"  
                android:src="@drawable/bottom" />  
        </LinearLayout>  
      
    </LinearLayout>  

说明:此布局文件中的 android:src加载的drawable资源图片是自己选取的,具体使用时候可以根据自身情况设置。

可以为控件Windows8TileImageView增加单击事件,比如这样添加:

    package windows8.tile;  
      
    import android.support.v7.app.ActionBarActivity;  
    import android.widget.Toast;  
    import android.os.Bundle;  
      
    public class MainActivity extends ActionBarActivity {  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
      
            Windows8TileImageView joke = (Windows8TileImageView) findViewById(R.id.c_joke);  
      
            // 为某一个磁贴添加点击事件的方式。  
            joke.setOnClickIntent(new Windows8TileImageView.OnViewClick() {  
      
                @Override  
                public void onClick() {  
                    Toast.makeText(getApplicationContext(), "磁贴的点击事件",  
                            Toast.LENGTH_LONG).show();  
                }  
            });  
        }  
    }  
来自:http://blog.csdn.net/zhangphil/article/details/44957091

标签: ssl 代码

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

上一篇:Android用代码实现全屏

下一篇:Android自动获取短信验证码