由于RecyclerView 设置头部并不想ListView那样联系紧密,所以我还是C的Listview
1.MainAc
public class MainActivity extends AppCompatActivity {
private MyListView mLv;
private ImageView iamge_header;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
List list = new ArrayList<>();
for (int i = 0; i < 30; i++) {
list.add("" + i);
}
MyAdapter myAdapter = new MyAdapter(this, list);
View viewHead = View.inflate(this, R.layout.layout_list_header, null);
mLv.addHeaderView(viewHead);
// mLv.addFooterView(viewFoot);
iamge_header = viewHead.findViewById(R.id.iv_header);
//等View界面全部绘制完毕的时候,去得到已经绘制完控件的宽和高,查一下这个方法,并做一个笔记
iamge_header.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//宽和高已经测量完毕
mLv.setParallaxImage(iamge_header);
//释放资源
mLv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
mLv.setAdapter(myAdapter);
}
private void initView() {
mLv = (MyListView) findViewById(R.id.lv);
}
}
2.Mainxml 就这一个
3.CustomView
public class MyListView extends ListView {
private ImageView iv_header;
/**图片的高度*/
private int drawableHeight;
/**ImageView的原始高度*/
private int originalHeight;
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setParallaxImage(ImageView iv_header) {
this.iv_header = iv_header;
drawableHeight = iv_header.getDrawable().getIntrinsicHeight();
originalHeight = iv_header.getMeasuredHeight();
}
/**
*
* @param deltaX
* @param deltaY 竖直方向的瞬时偏移量, 顶部下拉 -, 底部上拉 +
* @param scrollX
* @param scrollY 垂直方向超出滚动的距离, 顶部-, 底部+
* @param scrollRangeX
* @param scrollRangeY 垂直方向滚动范围
* @param maxOverScrollX
* @param maxOverScrollY 最大超出滚动的距离.
* @param isTouchEvent 是否是手指触摸.true 触摸到边界, false 惯性到边界
* @return
*/
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if(deltaY < 0 && isTouchEvent){/*顶部下拉, 手指触摸*/
int newHeight = (int) (iv_header.getHeight() + Math.abs(deltaY) / 2.0f);/*下拉的瞬时偏移量加给Header*/
if(newHeight <= drawableHeight){/*限制最大范围*/
iv_header.getLayoutParams().height = newHeight;/*让新的高度生效*/
iv_header.requestLayout();
}
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(ev.getAction() == MotionEvent.ACTION_UP){/*弹回去*/
ValueAnimator animator = ValueAnimator.ofInt(iv_header.getHeight(), originalHeight);/*把当前的Header高度(220), 设置回原来的高度160*/
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator anim) {
float fraction = anim.getAnimatedFraction();
Integer newHeight = (Integer) anim.getAnimatedValue();
iv_header.getLayoutParams().height = newHeight;/*让新的高度生效*/
iv_header.requestLayout();
}
});
animator.setInterpolator(new OvershootInterpolator(4));
animator.setDuration(500);
animator.start();
}
return super.onTouchEvent(ev);
}
}
4.Adapter
public class MyAdapter extends BaseAdapter {
private Context context;
private List list;
public MyAdapter(Context context, List list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = View.inflate(context, R.layout.item, null);
holder.textView = view.findViewById(R.id.id_tv_title);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(list.get(i));
return view;
}
static class ViewHolder {
TextView textView;
}
}
5.layout_list_header.xml
OK 图片随意了