不废话,直接上代码,
1,先简单复写ScrollVIew:
package demo.com.listviewinscrollview;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
/**
* Created by Alv_chi on 2016/12/6.
*/
public class MyScrollView extends ScrollView {
private static final String TAG = "MyScrollView";
private int currentYPosition;
public MyScrollView(Context context) {
this(context, null);
}
public MyScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, y);
currentYPosition = y;
}
public int getcurrentYPosition() {
return currentYPosition;
}
}
2,再复写嵌套在ScrollVIew中的ListView:
package demo.com.listviewinscrollview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.AbsListView;
import android.widget.ListView;
/**
* Created by Alv_chi on 2016/12/6.
*/
public class MyListView extends ListView implements AbsListView.OnScrollListener {
private static final String TAG = "MyListView";
private MyScrollView myScrollView;
private boolean isPullup;
private int svCurrentYPosition;
private boolean isLastItem = false;
private boolean isEndOfListView = false;
private boolean isFirstItem = false;
private float downY;
private float moveY;
private boolean isStartOfListView = false;
public MyListView(Context context) {
this(context, null);
}
public MyListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public MyListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setOnScrollListener(this);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
moveY = ev.getY();
break;
}
// 用于判断手指是向上滑动还是向下滑动;
isPullup = downY > moveY ? true : false;
return super.onTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int lvTop = getTop();
int height = getHeight();
height += lvTop;
lvTop -= 10;
// 此处获取ScrollView对象,也可以用Setter方法set进来;
myScrollView = (MyScrollView) (getParent().getParent());
if (myScrollView != null) {
svCurrentYPosition = myScrollView.getcurrentYPosition();
Log.e(TAG, "onTouchEvent: svCurrentYPosition=" + svCurrentYPosition);
}
// 当LIstView到达屏幕顶部时(一定范围内),不让其父ScrollView拦截,
// 也就是让ListView去滚动(消费),超出范围就拦截ScrollView滚动(消费);
if (svCurrentYPosition < height && svCurrentYPosition > lvTop) {
// 判断是否listVIew划到两端的尽头,如果是就让ScrollView截断事件,让ScrollVIew滚动,而不是ListVIew滚动;
if ((isEndOfListView && isPullup) || (isStartOfListView && !isPullup)) {
myScrollView.requestDisallowInterceptTouchEvent(false);
} else {
myScrollView.requestDisallowInterceptTouchEvent(true);
}
} else {
myScrollView.requestDisallowInterceptTouchEvent(false);
}
return super.dispatchTouchEvent(ev);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE && isLastItem) {
isEndOfListView = true;
} else {
isEndOfListView = false;
}
if (scrollState == SCROLL_STATE_IDLE && isFirstItem) {
isStartOfListView = true;
} else {
isStartOfListView = false;
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
isLastItem = (firstVisibleItem + visibleItemCount == totalItemCount);
isFirstItem = firstVisibleItem == 0 ? true : false;
}
}
3,activity以及其布局:
package demo.com.listviewinscrollview;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import butterknife.Bind;
import butterknife.ButterKnife;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "lvTop";
@Bind(R.id.tv1)
TextView tv1;
@Bind(R.id.lv)
MyListView lv;
@Bind(R.id.tv2)
TextView tv2;
@Bind(R.id.sv)
MyScrollView sv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
tv1.setText(R.string.myText);
tv2.setText(R.string.myText);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="demo.com.listviewinscrollview.MainActivity">
<demo.com.listviewinscrollview.MyScrollView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<demo.com.listviewinscrollview.MyListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="300dp"
android:entries="@array/strArr" />
<TextView
android:id="@+id/tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</demo.com.listviewinscrollview.MyScrollView>
</LinearLayout>
源码下载:点击打开链接下载源码