为了账号安全,请及时绑定邮箱和手机立即绑定

小淇哥基础教学(二)_3D旋转效果的View

标签:
Android

5b9a0b870001b51b03320523.jpg

小淇哥QQ:91630844(如果想要demo,可以加我QQ,下载地址:http://git.oschina.net/wsxqg/shijiandemo/attach_files) 

用到的知识点1viewpager的滚动

    2Camera和Matrix的的3D旋转效果的实现

            3OldNineAndroid包的旋转的实现

            4自定义FrameLayout实现通过自定义Interpolator改变颜色的变化效果

1MainActivity中

mJazzy.setTransitionEffect(effect);

mJazzy.setAdapter(new MainAdapter());

mJazzy.setPageMargin(30);

private class MainAdapter extends PagerAdapter {

@Override

public Object instantiateItem(ViewGroup container, final int position) {

TextView text = new TextView(MainActivity.this);

text.setGravity(Gravity.CENTER);

text.setTextSize(30);

text.setTextColor(Color.WHITE);

text.setText("Page " + position);

text.setPadding(30, 30, 30, 30);

int bg = Color.rgb((int) Math.floor(Math.random()*128)+64, 

(int) Math.floor(Math.random()*128)+64,

(int) Math.floor(Math.random()*128)+64);

text.setBackgroundColor(bg);

container.addView(text, LayoutParams.MATCH_PARENT, 

LayoutParams.MATCH_PARENT);

mJazzy.setObjectForPosition(text, position);

return text;

}

@Override

public void destroyItem(ViewGroup container, int position, Object obj) {

container.removeView((View) obj);

}

@Override

public int getCount() {

return 10;

}

@Override

public boolean isViewFromObject(View arg0, Object arg1) {

return arg0 == arg1;

}

这里是基本的viewpager设置adapter的设置

------------------------------------------------------------------

2接下来,看一下自定义Viewpager的设置

public JazzyViewPager(Context context, AttributeSet attrs) {

super(context, attrs);

setClipChildren(false);

// now style everything!

TypedArray ta = context.obtainStyledAttributes(attrs, 

R.styleable.JazzyViewPager);

int effect = ta.getInt(R.styleable.JazzyViewPager_style, 0);

String[] transitions = getResources().getStringArray(R.array.jazzy_effects);

setTransitionEffect(TransitionEffect.valueOf(transitions[effect]));

setFadeEnabled(ta.getBoolean(R.styleable.JazzyViewPager_fadeEnabled, 

false));

setOutlineEnabled(ta.getBoolean(R.styleable.JazzyViewPager_outlineEnabled, 

false));

setOutlineColor(ta.getColor(R.styleable.JazzyViewPager_outlineColor, 

Color.WHITE));

switch (mEffect) {

case Stack:

case ZoomOut:

setFadeEnabled(true);

}

ta.recycle();

}

上面这里主要获取一些资源的属性值;

(2)

viewPager父类的方法public void onPageScrolled(int position, float positionOffset, int 

positionOffsetPixels) {

position代表的是当前view的个数,positionOffset代表偏移完成了的百分比, positionOffsetPixels

代表了位移多少像素,左滑的时候,后面两个参数是不断增加的。右滑的时候,后面两个参数是不断减少

}

这个是viewpager最主要的方法,当viewpager滑动的时候调用这个方法

下面,我们看看这个方法的主要内容:

@Override

public void onPageScrolled(int position, float positionOffset, int 

positionOffsetPixels) {

if (mState == State.IDLE && positionOffset > 0) {

oldPage = getCurrentItem();

mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;

//向左滑的时候,的时候,页数会马上改变,向右滑的时候,页数不会马上改变。还是当前页

}

boolean goingRight = position == oldPage;

if (mState == State.GOING_RIGHT && !goingRight)

mState = State.GOING_LEFT;

else if (mState == State.GOING_LEFT && goingRight)

mState = State.GOING_RIGHT;

float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;

//获取真正的移动

mLeft = findViewFromObject(position);

mRight = findViewFromObject(position+1);

if (true)//mFadeEnabled

animateFade(mLeft, mRight, effectOffset);

if (mOutlineEnabled)//mOutlineEnabled

animateOutline(mLeft, mRight);

switch (mEffect) {

case Tablet:

animateTablet(mLeft, mRight, effectOffset);

break;

}

super.onPageScrolled(position, positionOffset, positionOffsetPixels);

if (effectOffset == 0) {

disableHardwareLayer();

mState = State.IDLE;

}

}

首先根据滑动的数值,获取到当前的状态,空闲状态,左滑状态,右滑状态;状态的变化,可以控制动画的效果。下面的代码可以实现

(3)实现3D效果的方法

protected void animateTablet(View left, View right, float positionOffset) {

if (mState != State.IDLE) {

if (left != null) {

// manageLayer(left, true);

mRot = 30.0f * positionOffset;

mTrans = getOffsetXForRotation(mRot, left.getMeasuredWidth(),

left.getMeasuredHeight());

ViewHelper.setPivotX(left, left.getMeasuredWidth()/2);//设置

中心点

ViewHelper.setPivotY(left,left.getMeasuredHeight()/2);

ViewHelper.setTranslationX(left, mTrans);

ViewHelper.setRotationY(left, mRot);//如果注释掉这个,就没有

旋转效果

logState(left, "Left");

}

if (right != null) {

manageLayer(right, true);

mRot = -30.0f * (1-positionOffset);

mTrans = getOffsetXForRotation(mRot, right.getMeasuredWidth

(), 

right.getMeasuredHeight());

ViewHelper.setPivotX(right, right.getMeasuredWidth()*0.5f);

ViewHelper.setPivotY(right, right.getMeasuredHeight()*0.5f);

ViewHelper.setTranslationX(right, mTrans);

ViewHelper.setRotationY(right, mRot);

logState(right, "Right");

}

}

}

protected float getOffsetXForRotation(float degrees, int width, int height) {

mMatrix.reset();

mCamera.save();

mCamera.rotateY(Math.abs(degrees+0));//如果注释掉这个,就中间的距离过大

mCamera.getMatrix(mMatrix);

mCamera.restore();

mMatrix.preTranslate(-width * 0.5f, -height * 0.5f);

mMatrix.postTranslate(width * 0.5f, height * 0.5f);

mTempFloat2[0] = width;

mTempFloat2[1] = height;

mMatrix.mapPoints(mTempFloat2);//计算变换后的宽高

return (width - mTempFloat2[0]) * (degrees > 0.0f ? 1.0f : -1.0f);

}

mCamera.save();

mCamera.restore();是成对出现的;之间的代码代表需要旋转的改变

mMatrix.preTranslate(-width * 0.5f, -height * 0.5f);

mMatrix.postTranslate(width * 0.5f, height * 0.5f);

前乘和后乘,这里可以理解为,前者先把中心点放在-width * 0.5f, -height * 0.5f,等动画执行完毕

后,再放回去,width * 0.5f, height * 0.5f。这里整个可以理解为围绕中心点旋转

mMatrix.mapPoints(mTempFloat2);//计算变换后的宽高这里获取矩阵变化后,X的宽度变化

最后返回要位移的距离

----------------------------

ViewHelper.setPivotX(left, left.getMeasuredWidth()/2);//设置中心点

ViewHelper.setPivotY(left,left.getMeasuredHeight()/2);

ViewHelper.setTranslationX(left, mTrans);

ViewHelper.setRotationY(left, mRot);//如果注释掉这个,就没有旋转效果

这里是实现位移效果和旋转效果,真正的位移和旋转是这里实现的。看来上面的只是获取到位移的值,

如果不懂,可以看demo

原文链接:http://www.apkbus.com/blog-880881-68336.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消