效果图
项目结构:
TBLayout中
package com.taobao.detailview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;
//com.taobao.detailview.TBLayout
public class TBLayout extends LinearLayout {
private OnPullListener pullListener;
private OnPageChangedListener ctListener;
public void setOnPullListener(OnPullListener listener) {
this.pullListener = listener;
}
public void setOnContentChangeListener(OnPageChangedListener ler) {
this.ctListener = ler;
}
private View mHeader;
private View mFooter;
private Scroller scroller;
private int mTouchSlop = 0;
private int mLastY;
private int mLastInterceptY;
private int mHeaderHeight;
public final static int SCREEN_HEADER = 11;
public final static int SCREEN_FOOTER = 12;
private int screen = SCREEN_HEADER;
@SuppressLint("NewApi")
public TBLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public TBLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TBLayout(Context context) {
super(context);
init();
}
private void init() {
scroller = new Scroller(getContext());
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus && mHeader == null && mFooter == null) {
initData();
}
}
private void initData() {
mHeader = findViewById(R.id.header);
mFooter = findViewById(R.id.footer);
ViewGroup.LayoutParams lps = mFooter.getLayoutParams();
mHeaderHeight = mHeader.getMeasuredHeight();
lps.height = mHeaderHeight;
mFooter.setLayoutParams(lps);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean result = false;
final int y = (int) ev.getY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastInterceptY = mLastY = y;
break;
case MotionEvent.ACTION_MOVE:
int dy = y - mLastInterceptY;
if (dy > mTouchSlop && screen == SCREEN_FOOTER) {// pull down
result = (pullListener != null && pullListener
.footerHeadReached(ev));
} else if (dy < -mTouchSlop && screen == SCREEN_HEADER) { // pull up
result = (pullListener != null && pullListener
.headerFootReached(ev));
}
break;
case MotionEvent.ACTION_UP:
mLastInterceptY = 0;
break;
}
return result;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
int dy = y - mLastY;
switch (screen) {
case SCREEN_HEADER:
int sy = -dy;
if (sy < 0) {
sy = 0;
} else if (sy > getHeight()) {
sy = getHeight();
}
scrollTo(0, sy);
break;
case SCREEN_FOOTER:
if (dy > 0) {
scrollTo(0, mHeaderHeight - dy);
} else { // dy < 0
}
break;
}
break;
case MotionEvent.ACTION_UP:
int t = 0;
switch (screen) {
case SCREEN_HEADER:
t = mHeaderHeight / 4;
break;
case SCREEN_FOOTER:
t = mHeaderHeight * 3 / 4;
break;
}
int sy = getScrollY();
if (sy > t) { // scroll to footer
scroller.startScroll(0, sy, 0, mHeaderHeight - sy, 150);
screen = SCREEN_FOOTER;
if (ctListener != null) {
ctListener.onPageChanged(SCREEN_FOOTER);
}
invalidate();
} else { // scroll to header
scroller.startScroll(0, sy, 0, -sy, 150);
screen = SCREEN_HEADER;
if (ctListener != null) {
ctListener.onPageChanged(SCREEN_HEADER);
}
invalidate();
}
mLastY = 0;
break;
}
return true;
}
@Override
public void computeScroll() {
if (scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(), scroller.getCurrY());
postInvalidate();
}
}
public interface OnPullListener {
// 到达Header(第一页)的底部
public boolean headerFootReached(MotionEvent event);
// 到达Footer(第二页)的顶部
public boolean footerHeadReached(MotionEvent event);
}
public interface OnPageChangedListener {
// 页面改变事件
public void onPageChanged(int stub);
}
}
Activity_ScrollView中
package com.taobao.detailview;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.taobao.detailview.TBLayout.OnPageChangedListener;
import com.taobao.detailview.TBLayout.OnPullListener;
/**
* Header's root is ScrollView , Footer's root is ScrollView
*
* @author zy
*
*/
@SuppressWarnings("unused")
public class Activity_ScrollView extends Activity {
// 滑动翻页的外层自定义控件
private TBLayout tblayout;
// 第一页的ScrollView
private ScrollView header;
// 和第二页的ScrollView
private ScrollView footer;
// 第一页ScrollView的内容
private LinearLayout mHeaderContent;
// 第二页ScrollView的内容
private LinearLayout mFooterContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrollview);
tblayout = (TBLayout) findViewById(R.id.tblayout);
header = (ScrollView) findViewById(R.id.header);
footer = (ScrollView) findViewById(R.id.footer);
mHeaderContent = (LinearLayout) header.getChildAt(0);
mFooterContent = (LinearLayout) footer.getChildAt(0);
tblayout.setOnPullListener(new OnPullListener() {
@Override
public boolean headerFootReached(MotionEvent event) {
if (header.getScrollY() + header.getHeight() >= mHeaderContent
.getHeight()) {
return true;
}
return false;
}
@Override
public boolean footerHeadReached(MotionEvent event) {
if (footer.getScrollY() == 0) {
return true;
}
return false;
}
});
// 翻页
tblayout.setOnContentChangeListener(new OnPageChangedListener() {
@Override
public void onPageChanged(int stub) {
switch (stub) {
case TBLayout.SCREEN_HEADER:
Log.d("tag", "SCREEN_HEADER");
Toast.makeText(Activity_ScrollView.this,"第一页",Toast.LENGTH_SHORT).show();
break;
case TBLayout.SCREEN_FOOTER:
Log.d("tag", "SCREEN_FOOTER");
Toast.makeText(Activity_ScrollView.this,"第2页",Toast.LENGTH_SHORT).show();
break;
}
}
});
}
}
activity_scrollview.xml中
page1_scrollview.xml
page2_scrollview.xml
id.xml
- 12
- 34
源码下载:
http://download.csdn.net/detail/zhaihaohao1/9815988