关于ScrollView中嵌套listview焦点问题 解决

在这里我要提出的是,listview能滚动的前提是:当listview本身的高度小于listview里的子view。

第一种方法(简单)

只需在MainActivity中 找到listview 和 scrollview

然后给listview设置监听事件

listview.setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
scrollView.requestDisallowInterceptTouchEvent(false);
}else{
scrollView.requestDisallowInterceptTouchEvent(true);
}
return false;
}
});

 
   

第二种方法(根据自己的方法选择)

(如果你用的自定义ListView,重载onMeasure()方法)

只需重写listview即可

package com.bawei.day06;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;

public class ListViewForScrollView extends ListView {
int mLastMotionY;
boolean bottomFlag;
public ListViewForScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

@Override
/**
* 重写该方法,达到使ListView适应ScrollView的效果
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//设置显示高度
int expandSpec = MeasureSpec.makeMeasureSpec(/*Integer.MAX_VALUE >> 2*/500,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

if (bottomFlag) {
getParent().requestDisallowInterceptTouchEvent(true);
}
return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int y = (int) ev.getRawY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
int deltaY = y - mLastMotionY;
if (deltaY < 0) {
View child = getChildAt(0);
if (child != null) {
if (getLastVisiblePosition() == (getChildCount()-1) && child.getBottom() == (getChildCount()-1)) {
bottomFlag = true;
getParent().requestDisallowInterceptTouchEvent(true);
}

int bottom = child.getBottom();
int padding = getPaddingTop();
if (getLastVisiblePosition() == (getChildCount()-1)
&& Math.abs(bottom - padding) >= 20) {
bottomFlag = true;
getParent().requestDisallowInterceptTouchEvent(true);
}
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
break;
}
return super.onTouchEvent(ev);
}

public void setBottomFlag(boolean flag) {
bottomFlag = flag;
}
}

 
   

(用的计算listview总高度并设置即setListViewHeightBasedOnChildren(listView)这个方法)

需要重写listview和重写ScrollView

重写listview

MyListView.java

package com.bawei.day06_scrollview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;

public class MyListView extends ListView {
int mLastMotionY;
boolean bottomFlag;

public MyListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
// 闂冪粯顒涢悥鍓佽閹凤附鍩呮禍瀣╂
if (bottomFlag) {
getParent().requestDisallowInterceptTouchEvent(true);
}
return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
int y = (int) ev.getRawY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// 妫f牕鍘涢幏锔藉焻down娴滃娆�,鐠佹澘缍峺閸ф劖鐖�
mLastMotionY = y;
break;
case MotionEvent.ACTION_MOVE:
// deltaY > 0 閺勵垰鎮滄稉瀣箥閸旓拷,< 0閺勵垰鎮滄稉濠呯箥閸旓拷
int deltaY = y - mLastMotionY;
if (deltaY < 0) {
View child = getChildAt(0);
if (child != null) {
if (getLastVisiblePosition() == (getChildCount()-1) && child.getBottom() == (getChildCount()-1)) {
bottomFlag = true;
getParent().requestDisallowInterceptTouchEvent(true);
}

int bottom = child.getBottom();
int padding = getPaddingTop();
if (getLastVisiblePosition() == (getChildCount()-1)
&& Math.abs(bottom - padding) >= 20) {// 鏉╂瑩鍣锋稊瀣閻拷3閸欘垯浜掗崚銈嗘焽,娴e棛骞囬崷銊ょ瑝鐞涳拷,鏉╂ɑ鐥呴幍鎯у煂閸樼喎娲�
bottomFlag = true;
getParent().requestDisallowInterceptTouchEvent(true);
}
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
break;
}
return super.onTouchEvent(ev);
}

public void setBottomFlag(boolean flag) {
bottomFlag = flag;
}
}

 
   

重写ScrollView

MyScrollView.java

package com.bawei.day06_scrollview;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class MyScrollView extends ScrollView
{
public interface OnGetBottomListener {
public void onBottom();
}

private OnGetBottomListener onGetBottomListener;

public MyScrollView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

// public void setScrollViewListener(ScrollViewListener scrollViewListener) {
// this.scrollViewListener = scrollViewListener;
// }

@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);

// if(scrollViewListener != null) {
// scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
// }
//闁告帗婢樼花鎶芥焾椤帞绀夌紓浣圭崯istview闁猴拷閻愵剚绶辨繛鎴濈墛娴煎懘鏁嶅畝鍐惧敤闁稿繑鍎奸獮蹇涘矗閺嶎儷鏇㈠箺闂�鎰殤濞寸媴鎷�
if( getChildCount()>=1&&getHeight() - getScrollY() == getChildAt(0).getTop()){
onGetBottomListener.onBottom();
}
}

public interface ScrollViewListener {
void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy);
}

public void setBottomListener(OnGetBottomListener listener){
onGetBottomListener = listener;
}
}

 
   
posted @ 2016-04-14 09:42  只剩下我自己了  阅读(507)  评论(0)    收藏  举报