详情参考:http://blog.csdn.net/jdsjlzx/article/details/49512489
学习到的:
1、对自定义布局结合xml+java逻辑代码有了更深的理解
2、post()方法:在构造方法里面布局还没有生成,getChildAt(0)是拿不到东西的,但是post()会把动作放到队列里,等布局完成后再从队列里取出来,所以这里是个小窍门。
3、对ScrollView的滑动有了一定理解。
原理呢,就是计算滑动距离,如果大于蓝色部分原先顶部的内容高度,就将粉色显示的顶部内容,移动到FrameLayout中,否则,仍然在ScrollView中
public class HoverScrollView extends FrameLayout {
/**
* 设置由所显示的ScrollView承载所有布局
*/
public void init() {
post(new Runnable() {
@Override
public void run() {
LogTools.show("执行了init");
mContentView = (ViewGroup) getChildAt(0);
removeAllViews();
MyScrollView scrollView = new MyScrollView(getContext(), HoverScrollView.this);
scrollView.addView(mContentView);
addView(scrollView);
}
});
}
/**
* 设置固定在顶部的ViewGroup
*/
public void setTopView(final int id) {
post(new Runnable() {
@Override
public void run() {
if (mContentView != null) {
mTopView = (ViewGroup) mContentView.findViewById(id);
mTopViewTop = mTopView.getTop();
mTopContent = mTopView.getChildAt(0);
} else {
LogTools.show("mContentView ==null ");
}
}
});
}
/**
* 滑动显示隐藏的关键代码
*
* @param h
*/
public void onScroll(final int h) {
post(new Runnable() {
@Override
public void run() {
/**
* 1、非空判断,逻辑代码中没设置
*/
if (mTopView == null) {
return;
}
/**
* 2、滑动距离大于原来的头部高度,将布局加载FrameLayout中
*/
if (h >= mTopViewTop && mTopContent.getParent() == mTopView) {
mTopView.removeView(mTopContent);
addView(mTopContent);
} else if (h < mTopViewTop && mTopContent.getParent() == HoverScrollView.this) {
removeView(mTopContent);
mTopView.addView(mTopContent);
}
}
});
}
/**
* 该ViewGroup中的唯一元素 ScrollView,由它来承载所有布局内容
*/
private static class MyScrollView extends ScrollView {
private HoverScrollView mScrollView;
public MyScrollView(Context context, HoverScrollView mHoverScrollView) {
super(context);
mScrollView = mHoverScrollView;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
mScrollView.onScroll(t);
}
}
/**
* 构造函数
*
* @param context
*/
public HoverScrollView(Context context) {
super(context, null);
LogTools.show("1");
}
public HoverScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
LogTools.show("2");
}
public HoverScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
LogTools.show("3");
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public HoverScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
LogTools.show("4");
}
/**
* 固定在顶部的View
*/
private ViewGroup mTopView;
/**
* 固定在顶部的View里面的内容
*/
private View mTopContent;
/**
* 固定在顶部的View在滚动条里最上端的位置
*/
private int mTopViewTop;
/**
* 滚动条的内容
*/
private ViewGroup mContentView;
}
myListView.setOnScrollListener(new AbsListView.OnScrollListener()
{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
isScrollIdle = (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE);
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
if (firstVisibleItem <= 1)
{
myTV.setVisibility(View.GONE);
}
else
{
myTV.setVisibility(View.VISIBLE);
}
}
});