博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自定义控件:(动画)(特效)AllAppList平面矩阵3D效果
阅读量:6834 次
发布时间:2019-06-26

本文共 34448 字,大约阅读时间需要 114 分钟。

 

main.xml

View Code

app_item.xml 

View Code

AllAppList.java   (主Activity)

package com.hhj.appListDemo;import java.util.List;import android.app.Activity;import android.content.ActivityNotFoundException;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.graphics.Color;import android.os.Bundle;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.Window;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.GridView;import android.widget.Toast;public class AllAppList extends Activity {    private static final String TAG = "ScrollLayoutTest";    private ScrollLayout mScrollLayout;    private static final float APP_PAGE_SIZE = 16.0f;    private Context mContext;    final private int[] color = { Color.BLUE, Color.GRAY, Color.CYAN,            Color.GREEN, Color.LTGRAY, Color.MAGENTA, Color.RED };    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        this.requestWindowFeature(Window.FEATURE_NO_TITLE);        mContext = this;        setContentView(R.layout.main);        mScrollLayout = (ScrollLayout) findViewById(R.id.ScrollLayoutTest);        initViews();    }    public void initViews() {        final PackageManager packageManager = getPackageManager();        final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);        // get all apps        final List
apps = packageManager.queryIntentActivities( mainIntent, 0); System.out.println("apps---->" + apps.size()); // the total pages final int PageCount = (int) Math.ceil(apps.size() / APP_PAGE_SIZE); System.out.println("PageCount--->" + PageCount); Log.e(TAG, "size:" + apps.size() + " page:" + PageCount); for (int i = 0; i < PageCount; i++) { GridView appPage = new GridView(this); // get the "i" page data appPage.setAdapter(new AppAdapter(this, apps, i)); appPage.setNumColumns(4); appPage.setOnItemClickListener(listener); // appPage.setBackgroundColor(color[i]); mScrollLayout.addView(appPage); } } public OnItemClickListener listener = new OnItemClickListener() { public void onItemClick(AdapterView
parent, View view, int position, long id) { // TODO Auto-generated method stub ResolveInfo appInfo = (ResolveInfo) parent .getItemAtPosition(position); Intent mainIntent = mContext .getPackageManager() .getLaunchIntentForPackage(appInfo.activityInfo.packageName); mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { // launcher the package mContext.startActivity(mainIntent); } catch (ActivityNotFoundException noFound) { Toast.makeText(mContext, "Package not found!", Toast.LENGTH_SHORT).show(); } } }; @Override protected void onDestroy() { // TODO Auto-generated method stub android.os.Process.killProcess(android.os.Process.myPid()); super.onDestroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if (keyCode == KeyEvent.KEYCODE_BACK) { finish(); return true; } return super.onKeyDown(keyCode, event); }}
View Code

AppAdapter.java  (列表适配器)

package com.hhj.appListDemo;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class AppAdapter extends BaseAdapter {    private List
mList; private Context mContext; public static final int APP_PAGE_SIZE = 16; private PackageManager pm; public AppAdapter(Context context, List
list, int page) { mContext = context; pm = context.getPackageManager(); mList = new ArrayList
(); int i = page * APP_PAGE_SIZE; int iEnd = i + APP_PAGE_SIZE; while ((i < list.size()) && (i < iEnd)) { mList.add(list.get(i)); i++; } } public int getCount() { // TODO Auto-generated method stub return mList.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return mList.get(position); } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ResolveInfo appInfo = mList.get(position); AppItem appItem; if (convertView == null) { // 初始化 与findViewById类型,只不过findViewById是对控件,而这是对这个布局 View v = LayoutInflater.from(mContext).inflate(R.layout.app_item, null); appItem = new AppItem(); // 分别用来存储app的图标和名字 appItem.mAppIcon = (ImageView) v.findViewById(R.id.ivAppIcon); appItem.mAppName = (TextView) v.findViewById(R.id.tvAppName); v.setTag(appItem); convertView = v; } else { appItem = (AppItem) convertView.getTag(); } // set the icon appItem.mAppIcon.setImageDrawable(appInfo.loadIcon(pm)); // set the app name appItem.mAppName.setText(appInfo.loadLabel(pm)); return convertView; } public static class AppItem { ImageView mAppIcon; TextView mAppName; }}
View Code

ScrollLayout.java  (自定义动画控件)

package com.hhj.appListDemo;import java.util.Random;import com.hhj.appListDemo.AppAdapter.AppItem;import android.content.Context;import android.content.pm.ResolveInfo;import android.graphics.Bitmap;import android.graphics.Camera;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PaintFlagsDrawFilter;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.view.animation.Transformation;import android.widget.GridView;import android.widget.ImageView;import android.widget.ListAdapter;import android.widget.Scroller;public class ScrollLayout extends ViewGroup {    private boolean type;        /** 沿Y轴正方向看,数值减1时动画逆时针旋转。 */    public static final boolean ROTATE_DECREASE = true;    /** 沿Y轴正方向看,数值减1时动画顺时针旋转。 */    public static final boolean ROTATE_INCREASE = false;        /** 值为true时可明确查看动画的旋转方向。 */    public static final boolean DEBUG = false;        private static final String TAG = "ScrollLayout";    // 用于滑动的类    private Scroller mScroller;    // 用来跟踪触摸速度的类    private VelocityTracker mVelocityTracker;    // 当前的屏幕视图    private int mCurScreen;    // 默认的显示视图    private int mDefaultScreen = 0;    // 无事件的状态    private static final int TOUCH_STATE_REST = 0;    // 处于拖动的状态    private static final int TOUCH_STATE_SCROLLING = 1;    // 滑动的速度    private static final int SNAP_VELOCITY = 600;    private static int mNum;        private int mTouchState = TOUCH_STATE_REST;    private int mTouchSlop;    private float mLastMotionX;    // 用来处理立体效果的类    private Camera mCamera;    private Matrix mMatrix;    /**旋转的角度*/    private float angle = 180;    public ScrollLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);        // TODO Auto-generated constructor stub    }    // 在构造器中初始化    public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        // TODO Auto-generated constructor stub        mScroller = new Scroller(context);        mCurScreen = mDefaultScreen;        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();        mCamera = new Camera();        mMatrix = new Matrix();    }    /*     *      * 为子View指定位置     */    protected void onLayout(boolean changed, int left, int top, int right,            int bottom) {        // TODO Auto-generated method stub        Log.e(TAG, "onLayout");        if (changed) {            int childLeft = 0;            final int childCount = getChildCount();            for (int i = 0; i < childCount; i++) {                final View childView = getChildAt(i);                if (childView.getVisibility() != View.GONE) {                    final int childWidth = childView.getMeasuredWidth();                    childView.layout(childLeft, 0, childLeft + childWidth,                            childView.getMeasuredHeight());                    childLeft += childWidth;                }            }        }    }    // 重写此方法用来计算高度和宽度    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        Log.e(TAG, "onMeasure");        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        final int width = MeasureSpec.getSize(widthMeasureSpec);        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);        // Exactly:width代表的是精确的尺寸        // AT_MOST:width代表的是最大可获得的空间        if (widthMode != MeasureSpec.EXACTLY) {            throw new IllegalStateException(                    "ScrollLayout only canmCurScreen run at EXACTLY mode!");        }        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if (heightMode != MeasureSpec.EXACTLY) {            throw new IllegalStateException(                    "ScrollLayout only can run at EXACTLY mode!");        }        // The children are given the same width and height as the scrollLayout        // 得到多少页(子View)并设置他们的宽和高        final int count = getChildCount();        for (int i = 0; i < count; i++) {            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);        }        // Log.e(TAG, "moving to screen "+mCurScreen);        scrollTo(mCurScreen * width, 0);    }                /**     * 当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制 调用drawScreen函数     */    protected void dispatchDraw(Canvas canvas) {        // TODO Auto-generated method stub        final long drawingTime = getDrawingTime();        final int count = getChildCount();        //Log.i("HHJ", "125"+"   drawingTime:"+drawingTime+"           count:"+count);        for (int i = 0; i < count; i++) {            drawScreenCube(canvas, i, drawingTime,mNum);//mNum        }    }        class BigStone {        //图片        Bitmap bitmap;        //角度        int angle;        //x坐标        float x;        //y坐标        float y;        //是否可见        String text;        boolean isVisible = true;    }        /**     * 计算每个点的坐标     */    private void computeCoordinates() {        BigStone stone;        for(int index=0; index
scrollX + width || scrollWidth + width < scrollX) { return; } final View child;// = getChildAt(screen); float scaleX = 1f;/*设置矩阵大小*/ float scaleY = 1f; float centerX= (scrollWidth < scrollX)?scrollWidth + width:scrollWidth; //中心位置 float centerY=getHeight()/2; if(screen==mCurScreen+1 && getChildAt(mCurScreen+1)!=null){ child = getChildAt(mCurScreen+1); Log.i("HHJ", "child:"+child.toString()); scaleX = (float) (((getScrollX()-(mCurScreen*getMeasuredWidth()))) * (1.0 / getMeasuredWidth())); scaleY = scaleX; centerX = (scrollWidth < scrollX)?scrollWidth + width:scrollWidth-getMeasuredWidth()/2; centerY = getHeight()/2; }else if(screen==mCurScreen-1 && getChildAt(mCurScreen-1)!=null){ child = getChildAt(mCurScreen-1); }else { child = getChildAt(mCurScreen); if(scrollX
< scrollX)?scrollWidth + width:scrollWidth-getMeasuredWidth()/2; centerY = getHeight()/2; } } final Camera camera = mCamera; final Matrix matrix = mMatrix; canvas.save(); camera.save(); camera.rotateY(-0); camera.getMatrix(matrix); camera.restore(); matrix.preScale(Math.abs(scaleX),Math.abs(scaleY));//大小 //matrix.postScale(scaleX, scaleY); matrix.preTranslate(-centerX, -centerY); //中心位置 matrix.postTranslate(centerX, centerY); canvas.concat(matrix); drawChild(canvas, child, drawingTime); canvas.restore(); }else if(select==3){
//波浪情况 final int width = getWidth(); final int scrollWidth = screen * width; final int scrollX = this.getScrollX(); if(scrollWidth > scrollX + width || scrollWidth + width < scrollX) { return; } final View child;// = getChildAt(screen); float scaleX = 1f; float scaleY = 1f; if(screen==mCurScreen+1 && getChildAt(mCurScreen+1)!=null){ child = getChildAt(mCurScreen+1); scaleX = (float) ((float) ((getScrollX()-(mCurScreen*getMeasuredWidth()))) * (1.0 / getMeasuredWidth())); scaleY = scaleX; }else if(screen==mCurScreen-1 && getChildAt(mCurScreen-1)!=null){ child = getChildAt(mCurScreen-1); scaleX = (float) ((float) ((getScrollX()-(mCurScreen*getMeasuredWidth()))) * (1.0 / getMeasuredWidth())); scaleY = scaleX; }else { child = getChildAt(mCurScreen); } final float centerX = (scrollWidth < scrollX)?scrollWidth + width:scrollWidth; final float centerY = getHeight()/2; final Camera camera = mCamera; final Matrix matrix = mMatrix; canvas.save(); camera.save(); camera.rotateY(-0); camera.getMatrix(matrix); camera.restore(); matrix.preScale(Math.abs(scaleX), Math.abs(scaleY)); //matrix.postScale(scaleX, scaleY); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); canvas.concat(matrix); drawChild(canvas, child, drawingTime); canvas.restore(); }else if(select==4){
//立体翻转 final int width = getWidth(); final int scrollWidth = screen * width; final int scrollX = this.getScrollX(); if(scrollWidth > scrollX + width || scrollWidth + width < scrollX) { return; } final View child = getChildAt(screen); final int faceIndex = screen; final float faceDegree = (this.getScrollX() - faceIndex *480f)*0.1875f; final float currentDegree = getScrollX() * (angle / getMeasuredWidth()); if(faceDegree > 90 || faceDegree < -90) { return; } final float centerX = (scrollWidth < scrollX)?scrollWidth + width:scrollWidth; final float centerY = getHeight()/2; final Camera camera = mCamera; final Matrix matrix = mMatrix; canvas.save(); camera.save(); camera.rotateY(-faceDegree); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); canvas.concat(matrix); drawChild(canvas, child, drawingTime); canvas.restore(); }else if (select==5){ // 得到当前子View的宽度 final int width = getWidth(); /**当前滑动到view视图在viewgroup里面到位置 scrollWidth = 屏数*该view到宽度 */ final int scrollWidth = screen * width; /**View水平方向的偏移量(像素)*/ final int scrollX = this.getScrollX(); if (scrollWidth > scrollX + width || scrollWidth + width < scrollX) { return; } final View child = getChildAt(screen); final int faceIndex = screen; /** * 1.解锁下这里到意思 由于当前一屏所充满屏幕宽度(假如所480*800)480 * 2. 180/getMeasuredWidth() 当前屏总共分为180度 比上 当前屏总宽度 意思说屏每一个像素到滑动占多少角度 意思所说180/480=0.375 每移动一个像素就所要转动0.375个角度 * 3. getScrollX() 由于这个所一个viewgroup 上滑动到偏移量 ,所有等有所将viewgroup翻转了很多个180 * 等于说所第一屏所0~180度 第二屏所 180 ~ 360 度 第三屏所 360~540度 依次将viewgroup翻转到角度而已 * */ final float currentDegree = getScrollX() * (angle / getMeasuredWidth()); /** * 1.当前翻转到角度 currentDegree-当前屏数*180 * 2.这里这样一减当前到滑屏度数就控制在-180~0度之间了 * 3.让后在加上下面一个if判断,是将当前一屏与屏成九十度到时候以后的滑动就注销掉老 * **/ final float faceDegree = currentDegree - faceIndex * angle; if (faceDegree > 90 || faceDegree < -90) { return; } //旋转的x轴中心位置 final float centerX = (scrollWidth < scrollX) ? scrollWidth + width: scrollWidth; Log.i("HHJ", "centerX:"+centerX+" scrollWidth:"+scrollWidth+" scrollX:"+scrollX); //旋转的y轴中心位置 final float centerY = getHeight() / 2; final Camera camera = mCamera; final Matrix matrixX = mMatrix; canvas.save(); camera.save(); camera.rotateY(-faceDegree); camera.getMatrix(matrixX); camera.restore(); matrixX.preTranslate(-centerX, -centerY);//特效处理的中心 matrixX.postTranslate(centerX, centerY); canvas.concat(matrixX); drawChild(canvas, child, drawingTime); canvas.restore(); }else { super.dispatchDraw(canvas); } } /** * 把中心点放到中心处 * @param canvas * @param bitmap * @param left * @param top */ void drawInCenter(Canvas canvas, Bitmap bitmap, float left, float top,String text) { canvas.drawPoint(left, top, mPaint); Log.i("HHJ","bitmap==null:"+(bitmap==null)); canvas.drawBitmap(bitmap, left-bitmap.getWidth()/2, top-bitmap.getHeight()/2, null); canvas.drawText(text,left-bitmap.getWidth()/2+2, top+bitmap.getHeight()/2+8, mPaint); canvas.restore(); } /** * 根据目前的位置滚动到下一个视图位置. */ public void snapToDestination() { final int screenWidth = getWidth(); // 根据View的宽度以及滑动的值来判断是哪个View final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth; snapToScreen(destScreen); } public void snapToScreen(int whichScreen) { // get the valid layout page whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); if (getScrollX() != (whichScreen * getWidth())) { final int delta = whichScreen * getWidth() - getScrollX(); mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2); mCurScreen = whichScreen; invalidate(); // 重新布局 } } public void setToScreen(int whichScreen) { whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); mCurScreen = whichScreen; scrollTo(whichScreen * getWidth(), 0); } public int getCurScreen() { return mCurScreen; } @Override public void computeScroll() { // TODO Auto-generated method stub if (mScroller.computeScrollOffset()) { //Log.i("HHJ", "209"+mScroller.computeScrollOffset()); scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (mVelocityTracker == null) { // 使用obtain方法得到VelocityTracker的一个对象 mVelocityTracker = VelocityTracker.obtain(); } // 将当前的触摸事件传递给VelocityTracker对象 mVelocityTracker.addMovement(event); // 得到触摸事件的类型 final int action = event.getAction(); final float x = event.getX(); switch (action) { case MotionEvent.ACTION_DOWN: Log.e(TAG, "event down!"); if (!mScroller.isFinished()) { mScroller.abortAnimation(); } mLastMotionX = x; break; case MotionEvent.ACTION_MOVE: int deltaX = (int) (mLastMotionX - x); mLastMotionX = x; scrollBy(deltaX, 0); break; case MotionEvent.ACTION_UP: Log.e(TAG, "event : up"); // if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker; // 计算当前的速度 velocityTracker.computeCurrentVelocity(1000); // 获得当前的速度 int velocityX = (int) velocityTracker.getXVelocity(); if (velocityX > SNAP_VELOCITY && mCurScreen > 0) { // Fling enough to move left snapToScreen(mCurScreen - 1); } else if (velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1) { // Fling enough to move right snapToScreen(mCurScreen + 1); } else { snapToDestination(); } if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } // } mTouchState = TOUCH_STATE_REST; break; case MotionEvent.ACTION_CANCEL: mTouchState = TOUCH_STATE_REST; break; } return true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub Log.e(TAG, "onInterceptTouchEvent-slop:" + mTouchSlop); final int action = ev.getAction(); if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) { return true; } final float x = ev.getX(); switch (action) { case MotionEvent.ACTION_MOVE: final int xDiff = (int) Math.abs(mLastMotionX - x); if (xDiff > mTouchSlop) { mTouchState = TOUCH_STATE_SCROLLING; } break; case MotionEvent.ACTION_DOWN: mNum = new Random().nextInt(10); mLastMotionX = x; mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: mTouchState = TOUCH_STATE_REST; break; } return mTouchState != TOUCH_STATE_REST; }}
View Code

 

 DEMO完整路径下载:

 

 【滑动的时候九宫格图标变成原形】

 

package com.hhj.allApp;import java.util.Random;import com.hhj.allApp.AppAdapter.AppItem;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Camera;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.drawable.BitmapDrawable;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.VelocityTracker;import android.view.View;import android.view.ViewConfiguration;import android.view.ViewGroup;import android.widget.GridView;import android.widget.Scroller;public class ScrollLayout extends ViewGroup {    private static final String TAG = "HHJ";    // 用于滑动的类    private Scroller mScroller;    // 用来跟踪触摸速度的类    private VelocityTracker mVelocityTracker;    // 当前的屏幕视图    private int mCurScreen;    // 默认的显示视图    private int mDefaultScreen = 0;    // 无事件的状态    private static final int TOUCH_STATE_REST = 0;    // 处于拖动的状态    private static final int TOUCH_STATE_SCROLLING = 1;    // 滑动的速度    private static final int SNAP_VELOCITY = 600;    private int mTouchState = TOUCH_STATE_REST;    private int mTouchSlop;    private float mLastMotionX;    // 用来处理立体效果的类    private Camera mCamera;    private Matrix mMatrix;    // 旋转的角度    private float angle = 100;        private int mNum;        Paint mPaint = new Paint();        private Context mContext;    public ScrollLayout(Context context, AttributeSet attrs) {        this(context, attrs, 0);        mContext = context;        // TODO Auto-generated constructor stub    }    // 在构造器中初始化    public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        // TODO Auto-generated constructor stub        mScroller = new Scroller(context);        mCurScreen = mDefaultScreen;        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();        mCamera = new Camera();        mMatrix = new Matrix();    }    /*     *      * 为子View指定位置     */    protected void onLayout(boolean changed, int left, int top, int right,            int bottom) {        // TODO Auto-generated method stub        Log.e(TAG, "onLayout");        if (changed) {            int childLeft = 0;            final int childCount = getChildCount();            for (int i = 0; i < childCount; i++) {                final View childView = getChildAt(i);                if (childView.getVisibility() != View.GONE) {                    final int childWidth = childView.getMeasuredWidth();                    childView.layout(childLeft, 0, childLeft + childWidth,                            childView.getMeasuredHeight());                    childLeft += childWidth;                }            }        }    }    // 重写此方法用来计算高度和宽度    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        Log.e(TAG, "onMeasure");        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        final int width = MeasureSpec.getSize(widthMeasureSpec);        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);        // Exactly:width代表的是精确的尺寸        // AT_MOST:width代表的是最大可获得的空间        if (widthMode != MeasureSpec.EXACTLY) {            throw new IllegalStateException(                    "ScrollLayout only canmCurScreen run at EXACTLY mode!");        }        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);        if (heightMode != MeasureSpec.EXACTLY) {            throw new IllegalStateException(                    "ScrollLayout only can run at EXACTLY mode!");        }        // The children are given the same width and height as the scrollLayout        // 得到多少页(子View)并设置他们的宽和高        final int count = getChildCount();        for (int i = 0; i < count; i++) {            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);        }        // Log.e(TAG, "moving to screen "+mCurScreen);        scrollTo(mCurScreen * width, 0);    }    /*     * 当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制 调用drawScreen函数     */    protected void dispatchDraw(Canvas canvas) {        //Log.i(TAG, "dispatchDraw");        final long drawingTime = getDrawingTime();        final int count = getChildCount();        for (int i = 0; i < count; i++) {            drawScreen(canvas, i, drawingTime,1);//mNum        }    }    BigStone[] mStones;    /**圆心坐标*/    int mPointX=0, mPointY=0;   /**定义一个圆的半径*/    int mRadius = 180;        /**定义一个陀螺的半径*/    int[] mmRadius = {30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180};    /**每两个点间隔的角度*/    int mDegreeDelta;    /**是否在拖动*/    boolean isDrag=false;    public void drawScreen(Canvas canvas, int screen, long drawingTime,int selsect) {        if(selsect == 1){ //圆            Log.i(TAG, "isDrag:"+isDrag+"    "+getScrollX());            if(isDrag){                GridView gridView = (GridView) getChildAt(screen);                int width = getWidth();                int height = getHeight();                int screenCount = gridView.getChildCount();                mStones = new BigStone[screenCount];;                                mPointX = screen*width+width/2;                mPointY =height/2;                                BigStone stone;                int angle = 0;                mDegreeDelta = 180/screenCount;                                for(int index=0; index
scrollX + width || scrollWidth + width < scrollX) { return; } final View child = getChildAt(screen); final int faceIndex = screen; final float currentDegree = getScrollX() * (angle / getMeasuredWidth()); final float faceDegree = currentDegree - faceIndex * angle; if (faceDegree > 90 || faceDegree < -90) { return; } final float centerX = (scrollWidth < scrollX) ? scrollWidth + width : scrollWidth; final float centerY = getHeight() / 2; final Camera camera = mCamera; final Matrix matrix = mMatrix; canvas.save(); camera.save(); camera.rotateY(-faceDegree); camera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); canvas.concat(matrix); drawChild(canvas, child, drawingTime); canvas.restore(); } } /** * 根据目前的位置滚动到下一个视图位置. */ public void snapToDestination() { final int screenWidth = getWidth(); // 根据View的宽度以及滑动的值来判断是哪个View final int destScreen = (getScrollX() + screenWidth / 2) / screenWidth; snapToScreen(destScreen); } public void snapToScreen(int whichScreen) { // get the valid layout page whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); if (getScrollX() != (whichScreen * getWidth())) { final int delta = whichScreen * getWidth() - getScrollX(); mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2); mCurScreen = whichScreen; invalidate(); // 重新布局 } } public void setToScreen(int whichScreen) { whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); mCurScreen = whichScreen; scrollTo(whichScreen * getWidth(), 0); } public int getCurScreen() { return mCurScreen; } @Override public void computeScroll() { // TODO Auto-generated method stub if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } } public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub //Log.i(TAG, "onTouchEvent"); if (mVelocityTracker == null) { // 使用obtain方法得到VelocityTracker的一个对象 mVelocityTracker = VelocityTracker.obtain(); } // 将当前的触摸事件传递给VelocityTracker对象 mVelocityTracker.addMovement(event); // 得到触摸事件的类型 final int action = event.getAction(); final float x = event.getX(); switch (action) { case MotionEvent.ACTION_DOWN: if (!mScroller.isFinished()) { mScroller.abortAnimation(); } mLastMotionX = x; break; case MotionEvent.ACTION_MOVE: isDrag = true; int deltaX = (int) (mLastMotionX - x); mLastMotionX = x; scrollBy(deltaX, 0); break; case MotionEvent.ACTION_UP: isDrag = false; //Log.e(TAG, "event : up"); // if (mTouchState == TOUCH_STATE_SCROLLING) {
final VelocityTracker velocityTracker = mVelocityTracker; // 计算当前的速度 velocityTracker.computeCurrentVelocity(1000); // 获得当前的速度 int velocityX = (int) velocityTracker.getXVelocity(); if (velocityX > SNAP_VELOCITY && mCurScreen > 0) { // Fling enough to move left snapToScreen(mCurScreen - 1); } else if (velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1) { // Fling enough to move right snapToScreen(mCurScreen + 1); } else { snapToDestination(); } if (mVelocityTracker != null) { mVelocityTracker.recycle(); mVelocityTracker = null; } // } mTouchState = TOUCH_STATE_REST; break; case MotionEvent.ACTION_CANCEL: mTouchState = TOUCH_STATE_REST; break; } return true; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub //Log.i(TAG, "onInterceptTouchEvent-slop:"); final int action = ev.getAction(); if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) { return true; } final float x = ev.getX(); switch (action) { case MotionEvent.ACTION_MOVE: final int xDiff = (int) Math.abs(mLastMotionX - x); if (xDiff > mTouchSlop) { mTouchState = TOUCH_STATE_SCROLLING; } break; case MotionEvent.ACTION_DOWN: mNum = new Random().nextInt(5); mLastMotionX = x; mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: mTouchState = TOUCH_STATE_REST; break; } return mTouchState != TOUCH_STATE_REST; } class BigStone { //图片 Bitmap bitmap; //角度 int angle; //x坐标 float x; //y坐标 float y; //是否可见 String text; boolean isVisible = true; }}
View Code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载地址:http://qtqkl.baihongyu.com/

你可能感兴趣的文章
Firefox 将导入 Windows 根证书,避免与杀毒软件的冲突
查看>>
Windows搭建golang开发平台
查看>>
多线程基础篇(3)——初试锁
查看>>
利用WSS搭建学生作业平台
查看>>
刚进入win7系统就提示检测到一个硬盘问题的解决方法
查看>>
Python之配置日志模块logging
查看>>
指定目录的所有 *.gif 文件都重命名为 *.jpg
查看>>
为11.2.0.2 Grid Infrastructure添加节点
查看>>
Linux运维课程 第一阶段 重难点摘要(六)CISCO
查看>>
inotify结合rsync监控目录的实时变化
查看>>
pfSense book之硬件配置指南
查看>>
存储过程总结 2
查看>>
js parsefloat
查看>>
快速启动神器 Wox
查看>>
第 34 章 Gnuplot
查看>>
WCF NetTcpBinding Transport安全模式(6) ClientCredentialType证书验证模式---- PeerTrust验证模式...
查看>>
选择HttpHandler还是HttpModule?
查看>>
HTC Desire 金卡制作方法
查看>>
C#高性能大容量SOCKET并发(十):SocketAsyncEventArgs线程模型
查看>>
phpcurl 请求Chunked-Encoded data 遇到的一个问题
查看>>