问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

android中如何实现翻页特效,3D的那种,不要2D的

发布网友 发布时间:2022-04-22 06:07

我来回答

2个回答

热心网友 时间:2023-06-29 20:27

package com.example.rotation3dview;  
import android.content.Context;  
import android.graphics.Camera;  
import android.graphics.Canvas;  
import android.graphics.Matrix;  
import android.util.AttributeSet;  
import android.view.MotionEvent;  
import android.view.VelocityTracker;  
import android.view.View;  
import android.view.ViewDebug.HierarchyTraceType;  
import android.view.ViewGroup;  
import android.widget.ImageView;  
import android.widget.Scroller;  
  
public class Rote3DView extends ViewGroup{  
    private int mCurScreen = 1;  
    // 滑动的速度  
    private static final int SNAP_VELOCITY = 500;  
    private VelocityTracker mVelocityTracker;  
    private int mWidth;  
    private Scroller mScroller;  
    private Camera mCamera;  
    private Matrix mMatrix;  
    // 旋转的角度,可以进行修改来观察效果  
    private float angle = 90;  
    public Rote3DView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        mScroller = new Scroller(context);  
        mCamera = new Camera();  
        mMatrix = new Matrix();  
        initScreens();  
    }  
      
    public void initScreens(){  
        ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(  
                ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);     
         for (int i = 0; i < 3; i++) {   
             this.addView(new ImageView(this.getContext()), i, p);   
         }   
         ((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);   
         ((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);   
         ((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);   
    }  
  
    @Override  
    protected void onLayout(boolean changed, int l, int t, int r, int b) {  
        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) {  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
        final int width = MeasureSpec.getSize(widthMeasureSpec);  
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);  
        if(widthMode != MeasureSpec.EXACTLY){  
            throw new IllegalStateException("仅支持精确尺寸");  
        }  
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);  
        if(heightMode != MeasureSpec.EXACTLY){  
            throw new IllegalStateException("仅支持精确尺寸");  
        }  
        final int count = getChildCount();  
        for(int i = 0; i < count; i++){  
            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);  
        }  
        scrollTo(mCurScreen * width, 0);  
    }  
      
    private float mDownX;  
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        if(mVelocityTracker == null){  
            mVelocityTracker = VelocityTracker.obtain();  
        }  
        //将当前的触摸事件传递给VelocityTracker对象  
        mVelocityTracker.addMovement(event);  
        float x = event.getX();  
        switch (event.getAction()) {  
        case MotionEvent.ACTION_DOWN:  
            if(!mScroller.isFinished()){  
                mScroller.abortAnimation();  
            }  
            mDownX = x;  
            break;  
        case MotionEvent.ACTION_MOVE:  
            int disX = (int)(mDownX - x);  
            mDownX = x;  
            scrollBy(disX, 0);  
            break;  
        case MotionEvent.ACTION_UP:  
            final VelocityTracker velocityTracker = mVelocityTracker;  
            velocityTracker.computeCurrentVelocity(1000);  
            int velocityX = (int) velocityTracker.getXVelocity();  
            if(velocityX > SNAP_VELOCITY && mCurScreen > 0){  
                snapToScreen(mCurScreen - 1);  
            }else if(velocityX < -SNAP_VELOCITY && mCurScreen < getChildCount() - 1){  
                snapToScreen(mCurScreen + 1);  
            }else{  
                snapToDestination();  
            }  
            if(mVelocityTracker != null){  
                mVelocityTracker.recycle();  
                mVelocityTracker = null;  
            }  
            break;  
        }  
        return true;  
    }  
      
    @Override  
    public void computeScroll() {  
        if (mScroller.computeScrollOffset()) {  
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  
            postInvalidate();  
        }  
    }  
      
    public void snapToDestination(){  
        setMWidth();  
        final int destScreen = (getScrollX() + mWidth / 2) / mWidth;  
        snapToScreen(destScreen);  
    }  
      
    public void snapToScreen(int whichScreen){  
        whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1));  
        setMWidth();  
        int scrollX = getScrollX();  
        int startWidth = whichScreen * mWidth;  
        if(scrollX != startWidth){  
            int delta = 0;  
            int startX = 0;  
            if(whichScreen > mCurScreen){  
                setPre();  
                delta = startWidth - scrollX;  
                startX = mWidth - startWidth + scrollX;  
            }else if(whichScreen < mCurScreen){  
                setNext();  
                delta = -scrollX;  
                startX = scrollX + mWidth;  
            }else{  
                startX = scrollX;  
                delta = startWidth - scrollX;  
            }  
            mScroller.startScroll(startX, 0, delta, 0, Math.abs(delta) * 2);  
            invalidate();  
        }  
    }  
      
    private void setNext(){  
        int count = this.getChildCount();  
        View view = getChildAt(count - 1);  
        removeViewAt(count - 1);  
        addView(view, 0);  
    }  
      
    private void setPre(){  
        int count = this.getChildCount();  
        View view = getChildAt(0);  
        removeViewAt(0);  
        addView(view, count - 1);  
    }  
      
    private void setMWidth(){  
        if(mWidth == 0){  
            mWidth = getWidth();  
        }  
    }  
}

/* 
 * 当进行View滑动时,会导致当前的View无效,该函数的作用是对View进行重新绘制 调用drawScreen函数 
 */  
@Override  
protected void dispatchDraw(Canvas canvas) {  
    final long drawingTime = getDrawingTime();  
    final int count = getChildCount();  
    for (int i = 0; i < count; i++) {  
        drawScreen(canvas, i, drawingTime);  
    }  
}  
  
public void drawScreen(Canvas canvas, int screen, long drawingTime) {  
    // 得到当前子View的宽度  
    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 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();  
}

热心网友 时间:2023-06-29 20:27

下面我们就开始一步步完成这个效果吧。

实现水平滑动
[java] view plaincopyprint?
01.package com.example.rotation3dview;
02.
03.import android.content.Context;
04.import android.util.AttributeSet;
05.import android.view.MotionEvent;
06.import android.view.View;
07.import android.view.ViewDebug.HierarchyTraceType;
08.import android.view.ViewGroup;
09.import android.widget.ImageView;
10.
11.public class Rote3DView extends ViewGroup{
12.
13. public Rote3DView(Context context, AttributeSet attrs) {
14. super(context, attrs);
15. initScreens();
16. }
17.
18. public void initScreens(){
19. ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(
20. ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
21. for (int i = 0; i < 3; i++) {
22. this.addView(new ImageView(this.getContext()), i, p);
23. }
24. ((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);
25. ((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);
26. ((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);
27. }
28.
29. @Override
30. protected void onLayout(boolean changed, int l, int t, int r, int b) {
31. int childLeft = 0;
32. final int childCount = getChildCount();
33. for(int i = 0; i< childCount; i++){
34. final View childView = getChildAt(i);
35. if(childView.getVisibility() != View.GONE){
36. final int childWidth = childView.getMeasuredWidth();
37. childView.layout(childLeft, 0, childLeft + childWidth, childView.getMeasuredHeight());
38. childLeft += childWidth;
39. }
40. }
41. }
42.
43. @Override
44. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
45. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
46. final int width = MeasureSpec.getSize(widthMeasureSpec);
47. final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
48. if(widthMode != MeasureSpec.EXACTLY){
49. throw new IllegalStateException("仅支持精确尺寸");
50. }
51. final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
52. if(heightMode != MeasureSpec.EXACTLY){
53. throw new IllegalStateException("仅支持精确尺寸");
54. }
55. final int count = getChildCount();
56. for(int i = 0; i < count; i++){
57. getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
58. }
59. }
60.
61. private float mDownX;
62. @Override
63. public boolean onTouchEvent(MotionEvent event) {
64. float x = event.getX();
65. switch (event.getAction()) {
66. case MotionEvent.ACTION_DOWN:
67. mDownX = x;
68. break;
69. case MotionEvent.ACTION_MOVE:
70. int disX = (int)(mDownX - x);
71. mDownX = x;
72. scrollBy(disX, 0);
73. break;
74. case MotionEvent.ACTION_UP:
75.
76. break;
77.
78. default:
79. break;
80. }
81.
82. return true;
83. }
84.
85.}
package com.example.rotation3dview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug.HierarchyTraceType;
import android.view.ViewGroup;
import android.widget.ImageView;

public class Rote3DView extends ViewGroup{

public Rote3DView(Context context, AttributeSet attrs) {
super(context, attrs);
initScreens();
}

public void initScreens(){
ViewGroup.LayoutParams p = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
for (int i = 0; i < 3; i++) {
this.addView(new ImageView(this.getContext()), i, p);
}
((ImageView)this.getChildAt(0)).setImageResource(R.drawable.page1);
((ImageView)this.getChildAt(1)).setImageResource(R.drawable.page2);
((ImageView)this.getChildAt(2)).setImageResource(R.drawable.page3);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
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) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if(widthMode != MeasureSpec.EXACTLY){
throw new IllegalStateException("仅支持精确尺寸");
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if(heightMode != MeasureSpec.EXACTLY){
throw new IllegalStateException("仅支持精确尺寸");
}
final int count = getChildCount();
for(int i = 0; i < count; i++){
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
}

private float mDownX;
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = x;
break;
case MotionEvent.ACTION_MOVE:
int disX = (int)(mDownX - x);
mDownX = x;
scrollBy(disX, 0);
break;
case MotionEvent.ACTION_UP:

break;

default:
break;
}

return true;
}

}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
信和财富p2p回款怎样?想做理财,有做过的吗?谢谢 想当飞行员高中学文理哪个好 用迅雷下载的电影中带有srt格式idx格式和sub格式的字幕怎么导入... 酸汤乌鱼的做法 四川的酸汤乌鱼的做法 酸汤乌鱼片的做法 用烤箱弄蛋白糖的做法 入口即化蛋白糖怎么做好吃 ...3000元的手机,我比较喜欢触屏机,有什么牌子介绍,最好是功能强大的... 蓝魔T11TE能播放超过4G的视频文件吗?(比如720P和1080P) 怎样把安卓手机的主菜单切换成左右翻页的? 安卓平板版wps软件怎设置左右翻页? Android activity切换时怎么实现类似ios的翻页效果 android怎么做类似网页的左右翻页 安卓的淘宝怎么设置左右滑动翻页?有这个功能吗? 手机屏幕翻页怎么设置 uc浏览器怎么设置自动翻页? 我oppo手机屏幕应用原先是平滑翻页,不知道怎么就... 手机屏幕翻页怎么设置? 11月份适合去哪里赏秋色? JTY-GD/LD 3000E点型光电感烟火灾探测器中JTY,GD... 上饶做消防维保的做烟感,火灾报警器的有哪家公司做 目前最先进的吸气式感烟火灾探测器是什么品牌? 哪种灭蚊灯效果最好 消防烟杆一套是什么价格 效果、质量最好的灭蚊灯? 烟感号码怎么编不进去,而模块号码能编进去 家用灭蚊器哪个牌子好 消防火灾自动报警系统中的点位数量是怎样计算的,... 吸入式灭蚊灯选哪个牌子好? 22年二驴不玩快手了吗 市监局回应二驴夫妇带货山寨机,市监局持怎样的态度? linux就该这么学的pdf版本下载地址?谁有?? 手机内存到底多大才够用,需要买256G内存的手机吗? 辛巴和二驴为什么翻脸? 手机内存多大合适 linux就该这么学的pdf版本下载地址?谁有??\ 直播飙脏话扇同伴脸被官方点名仍不悔改,二驴为何... 手机运行内存多大够用 Linux就该这么学这本书怎么样? 目前买手机内存多大合适? Linux下如何给PDF文件加注释 广东一男子在二驴直播间买到山寨机9倍索赔,快手官... 分享本不错的电子书《Linux就该这么学》,大家可以... 老人买手机多大内存合适? 咋回事 二驴今晚又在快手直播呢 不是封杀了吗? 有读过《Linux就该这么学》这本书的么?不知道跟鸟... 12月26日二驴在快手的用哪个号卖货? 鸟哥的linux私房菜第三版的PDF版本和实体书籍版有... 现在买手机,买多大内存的适合?