1.带有缩放效果的头部视差的实现:
--》自定义一个view继承listview,以便实现滑动
--》重写三个构造方法;
重写overScrollBy()方法--当各种能滑动的listview滑动到顶部或尾部之后继续滑动会调用该方法;
重写onTouchevent()方法,当手指抬起的时候实现将缩放的动画平滑的恢复原状
--》通过setImageview(Imageview imageview)方法,让外界传入用于头部展示的图片--》接着通过给imageview设置一个全局的布局监听器来获取imageview最初的宽高(并不一定是图片真实的宽高)
设置全局布局监听:
imageview.getViewTreeObserver().addOnGlobalLayoutListener
移除监听:
imageview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
--》在overScrollBy()方法中,让imageview调用layout方法对图片进行布局,上边界不变,左右和底部随手指的滑动同步向外拉伸,若想让缩放的效果不是那么明显可以将deltaY/2或 deltaY/3,最后请求重新布局
// LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imageView.getLayoutParams();
//ViewGroup.LayoutParams params = imageView.getLayoutParams();
//params.height = imageView.getBottom()-deltaY;
// imageView.setLayoutParams(params);
imageView.layout(imageView.getLeft()+deltaY,0,imageView.getRight()-deltaY,imageView.getBottom()-deltaY);
imageView.requestLayout(); //获将注释解开。将该句注释掉也可以
--》因为在overScrollBy()方法中已经实现了手指按下滑动的操作,所以在onTouchevent()方法中只需要处理手指抬起的动作就好,手指抬起的时候通过设置值动画来让图片平滑的恢复如初(值动画的值从图片当前的宽高,变化到图片最初的宽高),同时设置回弹差值器,让其有回弹的感觉
switch(ev.getAction()) {
case MotionEvent.ACTION_UP:
//通过值动画让imageview的高度一点点的回到最初的位置高度
animator = ValueAnimator.ofInt(imageView.getHeight(),originalHeight);
//监听动画值的改变实现自己的动画
animator.addUpdateListener(newValueAnimator.AnimatorUpdateListener() {
@Override
public voidonAnimationUpdate(ValueAnimator animation) am{
//获取动画的值,
intanimateValue = (int)animator.getAnimatedValue();
//将动画的值设置给imageview的高度
ViewGroup.LayoutParams params =imageView.getLayoutPars();
params.height
= animateValue;
//params.width = imageView.getWidth() - (imageView.getHeight() - animateValue);
imageView.setLayoutParams(params);
}
});
animator.setInterpolator(new
OvershootInterpolator(3));
animator.setDuration(400).start();
break;
2.自定义的侧滑菜单:
还是继承Fragmlayout,重写三个构造方法,重写onMeasure()方法--测量子view的宽高measureChild(view,宽的测量规则,高的测量规则)--》getmeasureWidth()方法就可以拿到子view的宽高; 重写onlayout()方法,摆放子view,但因为继承了fraglayot,所以上面的两个方法都可以不用写。
--》通过viewDragHelper这个类来实现实现子view的移动(通过layout布局或scrollTo方法也可以)
--》创建viewDragHelper对象,重写回调中的相应方法,tryCaptureView方法,判断是否捕获当前触摸的子view的触摸事件;
clampViewPositionHorizonta中返回left,左右就可以随便滑动了;在这个方法中需要对子view的移动范围进行限制,如主界面向右的最大移动范围设为slidingmenu宽的百分之六十;让主界面不能向左移动,即如果left<0,将left置为0,令left = 0;
clampViewPositionValtical中返回top,上下九可以随便滑动了
onViewPositionChanged方法在子view发生移动时被调用,一般用于实现子view的伴随移动,在这个方法中如果当前滑动的是菜单界面,那么主界面需要实现伴随移动:首先对菜单界面调用layout方法,将菜单界面固定住--》确定伴随移动的最大范围--》主界面调用layout方法,实现主界面的伴随移动--》因为每个view被滑动时都会执行该方法,所以滑动动画在该方法中设置--》给slidingmenu的背景图片添加颜色的遮罩此效果,getBackground().setColorFilter(颜色的计算器,PorterDuff.Mode.SRC_OVER)
onViewReleased方法,当手指抬起的时候会调用该方法,在这个方法中我需要判断当手指抬起时,主界面是滑向左边还是滑回右边--》当主界面的getLeft值也就是它左边的位置大于最大滑动范围的一半时,滑向右边;否则滑回左边--》但在自动滑回的过程中不能采用调用layout方法的方式,这样会瞬间完成滑动,缺少平滑的效果--》因此调用viewDragHelper的smoothSlideViewTo(要滑动的view,最终的left值,最终的top值)方法来实现平滑滑动的效果--》但注意:该方法不能单独使用,没有效果,须要配合computeScroll方法一起使用才会生效--》调用ViewCompat.postInvalidateOnAnimation(SlideMenu.this); (这种方法更省内存)会自动执行omputeScroll方法 --》详情翻看源码
--》最后,因为外界在使用该自定义控件的时候,可能针对view滑动的不同状态,去执行相应的操作--》所以自定义view应该对外暴露出接口,让外界知道view执行过程中的各个状态--》定义监听器,包含三种状态:菜单打开,菜单关闭,菜单滑动--》因为这三个状态都牵涉到子view位置的改变,所以在onViewPositionChanged方法对接口进行回调--》另外需要注意的是:因为该方法会被频繁的调用,所以为了避免频繁的调用回调,应设置状态标识符保存当前view的状态,当满足一定状态时才可以进行回调
--》但注意:要想让回调中的方法生效,必须要给viewDragHelper传入触摸事件,因此须要重写onInterceptTouchEvent(MotionEvent ev)--让viewDragHelper帮我们判断是否拦截触摸事件;重写onTouchEvent(MotionEvent event)--将触摸事件传递给viewDragHelper解析,让它来帮我们处理该事件,这时回调方法才会生效。
--》当菜单打开时,处理主界面的触摸事件,将其拦截并消耗掉--》重新定义一个线性布局,在里面判断当菜单处于打开状态时,拦截并消费掉事件
3.界面布局的搭建:
虽然继承的是帧布局,默认下面的view会覆盖在上一个view上面,但在这里对自定义view的使用没用任何影响,因为本来界面显示的时候就只显示一个,默认主界面覆盖在菜单界面上面;之后当菜单被打开时,主界面缩小,但最终缩小后的主界面还是覆盖在菜单界面上面的,只是仅覆盖了一小部分,所以两个界面都可以显示出来。
--》使用自定义的dragLayout--》在布局文件中外层使用自定义的draglayout,里面嵌套两个framelayout帧布局--》再另创建两个view,都继承fragment,一个主界面的view和一个菜单界面的view--》在主activity中找到两个帧布局,然后通过帧布局管理器将主界面的fragment和菜单界面的fragment分别添加到帧布局中,从而将主界面分成两个模块
--》主界面使用的是pageSlidingTab + viewpPager + radioGroup,来完成整体布局
--》主界面radiogroup + viewPager(自定义的没有滑动效果的viewPager)填充剩余空间
--》
--》在这个viewPager中,将要展示的几个fragment添加到集合中,给viewpager设置适配器展示集合中 的界面(在这里因为适配器展示的都是fragment,所以适配器继承fragmentPagerAdapter)
--》给radiogroup的每个选项设置状态选择器,属性设为state_checked--》给radiogroup设置监听事件(setOnCheckedChangeListener),在switch中根据选中的按钮,调用viewPager.setCurrentItem(第几个fragment,是否取消动画),来实现界面的切换
--》因为每个fragment界面都有相同的部分,加载布局,加载数据--》所以将其抽取到基类baseFragment中,对外暴露出相应的接口,因此子类要做的就是继承baseFragment,然后只需要实现加载布局和加载数据的方法就可以了(强制子类根据自身要加载的布局和加载的数据,去实现这两个方法)
--》在基类baseFragment中通过一个自定义的布局loadingPage(继承帧布局)来加载数据和相应的布局,因为每个界面要加载的布局和数据都是不同的,需要子类自己去实现,所以同样对暴露出两个接口--》因此在基类baseFragment中通过它来加载布局,数据的时候,只需要在oncreateview 方法中创建loadingpager对象(会要求重写加载布局和加载数据的方法),并返回该对象就可以了
--》因为loadingPager是用来加载界面和数据的,但加载中的view(一个圆圈)和加载失败的view,对所有的界面来说都是一样的,因此,可以直接写死在loadingPager中
--》轮播图的viewPager需要自定义,因为需要处理触摸事件,当在第一页且由左向右滑动时,才将触摸事件交由父控件处理,其余情况请求父控件不拦截事件
--》其次需要为轮播图中的图片设置触摸监听 setOnTouchListener,当手指按下的时候停止轮播,手指抬起的时候继续轮播
--》如果不想要viewPager的预加载功能,可以给其设置界面切换监听,只有在界面被选中,也就是界面切换完成的时候在加载数据
侧滑效果怎么取消
主界面的布局搭建
当手指滑动轮播图的时候,轮播图停止自动轮播
#沉浸式说明:
因为手机最上面的导航栏(也就是现实电量,WiFi的那一块)默认是黑色的,感觉和手机app的界面颜色不符,所以搞出来了沉浸式这么一个东西,说白了就是让最上面个的导航栏变透明或个手机应用的actionbar或toolbar的颜色相近