@wangwangheng
        
        2015-06-17T12:51:45.000000Z
        字数 4042
        阅读 2534
    不可发布
- 实现这个功能需要理解Android中对触摸事件的分发
 - 关于事件分发,我自己花了一张图,可以参考下Android View之间的触摸事件传递图
 
整体思路 在页面加载完成之后,把ViewPager的高度设置为ScrollView的高度减去Tab的高度,然后在ScrollView、ListView的触摸时间分发上想办法完成想要的功能;
在HomeFragment中,调用时机是页面刷新完成之后:
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {if(!resized && getActivity() != null){LayoutParams params = mViewPager.getLayoutParams();// 只能通过屏幕高度设置,当有虚拟键盘的时候有问题// 为什么要加上底部的虚拟按钮条的高度?因为手机有虚拟按钮// 有的手机没有;而且,具有虚拟按钮的手机的具体表现还不一样;int virtualBackBarHeight = CuliuUtils.getScreenHeight()- getActivity().getWindow().getDecorView().getHeight();// top bar和bottom bar的高度int topbarHeight = getResources().getDimensionPixelSize(R.dimen.topbar_height);int bottomBarHeight = getResources().getDimensionPixelSize(R.dimen.bottom_bar_height);int topAndBottomBarHeight = topbarHeight + bottomBarHeight;LinearLayout.LayoutParams p = (android.widget.LinearLayout.LayoutParams)mTabs.getLayoutParams();int margin = p.topMargin + p.bottomMargin+ mTabsBottomDividerView.getHeight();params.height = CuliuUtils.getScreenHeight() - statusBarHeight -mTabs.getHeight() - topAndBottomBarHeight- virtualBackBarHeight - margin;mViewPager.setLayoutParams(params);mScrollView.setInterceptParams(mViewPager);resized = true;}}});
特别注意的是,ViewPager 的高度只要设置一次就行了,所以要有排斥机制,并且在内存被回收之后,要重新设置高度(使用保存了的ViewPager的高度)
主要思路: 在自定义的ScrollView的onInterceptTouchEvent()方法中(MyScrollView),判断手指在屏幕X轴上和Y轴上移动的距离的大小,如果在X轴移动的距离大于在Y轴上移动的距离,则把事件分发到子View上(返回false);否则直接自己处理(返回true)
case MotionEvent.ACTION_DOWN:xDistance = yDistance = 0f;lastX = ev.getX();lastY = ev.getY();break;case MotionEvent.ACTION_MOVE:final float curX = ev.getX();final float curY = ev.getY();xDistance += Math.abs(curX - lastX);yDistance += Math.abs(curY - lastY);lastX = curX;lastY = curY;if(xDistance > yDistance){return false;}break;
因为
MyScrollView extends ScrollView, 所以,如果在X轴移动的距离不大于在Y轴移动的距离,会调用ScrollView的onInterceptTouchEvent(),在ACTION_MOVE的时候,如果在Y轴的手指滑动距离大于ViewConfiguration所以定义的最小滑动距离(touchSlop,从这个方法ViewConfiguration.get(context).getScaledTouchSlop()得到)的话,则返回true这一块内容,可以继续做优化:可以在X轴移动距离大于Y轴距离的时候,添加上X轴移动距离和TouchSlop的比较逻辑
主要思路: 需要处理MyScrollView的onInterceptTouchEvent()以及HomeListView的onTouchEvent以及onScroll方法
通过VelocityTracker得到当前Y轴的移动速度,如果>0说明手指正在往下滑动,如果<0,则说明正在往上滑动;关于VelocityTracker可以参考网上的文章,如Android VelocityTracker简介
得到View的显示区域的方法:
Rect global = new Rect();
mNoInterceptView.getGlobalVisibleRect(global);
主界面底部Tabbar和Fragment是一一关联的关系,逻辑比较简单,但是有一点需要注意的就是,当内存被干掉之后(onSaveInstanceState()方法),Android其实是会保存Fragment的状态的,所以要在状态恢复(onRestoreInstanceState()或者onCreate()方法)的时候,恢复这些Fragment;否则会导致页面混乱
每次进入应用请求Settings,会返回列表界面和微店的备用ip列表信息,程序中也固定一个列表界面和微店的ip;
如果请求Settings失败,则使用列表界面的备用ip重新请求,如果请求成功则切换列表的请求ip为列表备用ip列表中的一个;
如果列表界面请求失败,用户下次请求的的时候把列表界面的请求ip切换为settings请求下来的ip列表中的任意一个;如果settings中的ip列表为空,则使用备用列表;并设置host为api.chuchujie.com
如果微店请求失败,用户下次请求微店的时候把地址切换为Settings中请求的下来的微店ip列表中的任意一个,如果Settings中没有微店ip列表,则使用微店的备用Ip;并设置host为wxapi.chuchujie.com
具体的逻辑,可以参考
SwitchHostManager类
订单评论页中的店铺评价(EditText中的内容),是在失去焦点的时候设置到保存评价信息的对象中去的,这一点要注意一下
新分类主要使用大荣写的一个通用的列表界面框架,这个可以和大荣沟通
目前主界面中使用的Banner都是BannerFragment来实现的,自动跳转下一个Banner的逻辑都在BannerViewPager类中;
实现无限循环滚动的逻辑可以看一下ViewPager无限循环,并做了优化————到最后一个和第0个切换的时候的逻辑从onPageSelected()方法移动到了onPageScrolled()方法。