在项目中经常会遇到控件嵌套的问题,尤其在电商项目中会遇到ViewPager 嵌套 ViewPager问题,
如果没有做设置的话那么内层的viewpager 滑动是异常的。
网上也有很多通过事件分发来解决的方法。
这边我是使用HorizontalScrollView 重写的方法来避免这个情况 ,事件奋操作我留给了系统去了。
使用情境 商品详情页 viewpager 套 ScrollView 再套 自定义 HorizontalScrollView。
源码如下:
public class ViewPagerHorizontalScrollView extends HorizontalScrollView {
Context context;
PagerScrollAdapter pagerScrollAdapter;
LinearLayout linearLayout;
boolean isOnce = true;
int mWitdh;
private FrameLayout.LayoutParams layoutParams;
int xDown;
long startTime, endTime;
int lastIndex;
public ViewPagerHorizontalScrollView(Context context,
PagerScrollAdapter pagerScrollAdapter) {
super(context);
this.context = context;
this.pagerScrollAdapter = pagerScrollAdapter;
setHorizontalScrollBarEnabled(false);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed && isOnce) {
isOnce = false;
linearLayout= new LinearLayout(context);
layoutParams=new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setBackgroundColor(context.getResources().getColor(android.R.color.holo_red_light));
removeAllViews();
addView(linearLayout);
if (pagerScrollAdapter.getCount()<=0) {
return;
}
//add child
linearLayout.removeAllViews();
for (int i = 0; i < pagerScrollAdapter.getCount(); i++) {
View itemView=pagerScrollAdapter.getView(i);
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(getWidth(), getHeight());
itemView.setLayoutParams(layoutParams);
linearLayout.addView(itemView);
}
mWitdh = getWidth();
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction()==MotionEvent.ACTION_DOWN) {
startTime = System.currentTimeMillis();
xDown = (int)ev.getRawX();
}
if (ev.getAction()==MotionEvent.ACTION_UP || ev.getAction()==MotionEvent.ACTION_CANCEL) {
StopScrollView(ev);
return true;
}
return super.onTouchEvent(ev);
}
void StopScrollView(MotionEvent ev){
endTime = System.currentTimeMillis();
int xUp = (int)ev.getRawX();
int distance = Math.abs(xUp-xDown);
int moveNums = xUp - xDown;
int moveX = getScrollX();
int leftorright = moveX%mWitdh;
int nums = moveX/mWitdh;
if ( (endTime-startTime)<470 && distance > 50 ) {
if (moveNums<0) {
// xiang left
smoothScrollTo(((nums+1)*mWitdh), 0);
if (mListener!= null && lastIndex!=(nums+1)) {
mListener.currentPgae(nums+1);
lastIndex=nums+1;
}
}else {
// xiang right
smoothScrollTo((nums*mWitdh), 0);
if (mListener!= null && lastIndex!=(nums)) {
mListener.currentPgae(nums);
lastIndex=nums;
}
}
return;
}
if (leftorright< mWitdh/2) {
//left
smoothScrollTo((nums*mWitdh), 0);
if (mListener!= null && lastIndex!=(nums)) {
mListener.currentPgae(nums);
lastIndex=nums;
}
}else {
//right
smoothScrollTo(((nums+1)*mWitdh), 0);
if (mListener!= null && lastIndex!=(nums+1)) {
mListener.currentPgae(nums+1);
lastIndex=nums+1;
}
}
}
public interface PagerScrollAdapter {
int getCount();
View getView(int pos);
}
onPageChangeListener mListener;
public void setPageListener(onPageChangeListener mChangeListener){
this.mListener = mChangeListener;
}
public interface onPageChangeListener{
void currentPgae(int index);
}
}
使用代码如下:
viewPagerHorizontalScrollView=new ViewPagerHorizontalScrollView(getActivity(), new ViewPagerHorizontalScrollView.PagerScrollAdapter() {
@Override
public View getView(int pos) {
// TODO Auto-generated method stub
ImageView imageView=new ImageView(getActivity());
imageView.setImageDrawable(getActivity().getResources().getDrawable(R.drawable.ic_launcher));
return imageView;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return 10;
}
});
viewPagerHorizontalScrollView.setPageListener(new ViewPagerHorizontalScrollView.onPageChangeListener() {
@Override
public void currentPgae(int index) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), ""+index, Toast.LENGTH_SHORT).show();
}
});
frameLayout.removeAllViews();
frameLayout.addView(viewPagerHorizontalScrollView);
那么控件只能用代码创建键入 framelayout 不能直接写在xml 中 ,以后会继续完善。!!!