自定义控件-视觉特效
老规矩,先放效果图
继承ListView ,添加头布局,实现动态改变现实图片的高度,显示视觉效果,重要的是在ViewTree节点结束后获取图片的实际显示高度
plv_parallax.addHeaderView(view);
//添加渲染监听,当渲染完成后传出ImageView,难道只能放这儿吗
iv_parallax.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
plv_parallax.init(iv_parallax);
iv_parallax.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
plv_parallax.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Cheeses.NAMES));
}
1.创建构造函数,对图片进行测量高度
public ParallaxListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ParallaxListView(Context context) {
super(context);
}
/**
* 获取图片初始和原始高度
*
* @param view
*/
public void init(final View view) {
this.view = (ImageView) view;
globalHeight = view.getHeight();
intriHeight = ((ImageView) view).getDrawable().getIntrinsicHeight();
System.out.println(globalHeight);
}
2.实现overScrollBy(),边界滑动事件,通过方法中的参数获取偏离度,以及是否下拉
/**
* 边界滑动事件
*
* @param deltaX 拖拽的力道 向下为-
* @param deltaY
* @param scrollX
* @param scrollY
* @param scrollRangeX 超出边界X范围
* @param scrollRangeY 超出边界Y范围
* @param maxOverScrollX 超出边界最大X
* @param maxOverScrollY 超出边界最大Y
* @param isTouchEvent 是否是手指触摸
* @return
*/
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
System.out.println(deltaX + "--" + deltaY + "--" + scrollY + "--" + scrollRangeY + "--" + maxOverScrollY);
if (isTouchEvent && deltaY < 0) {
flag = true;
//获取新的距离,每次都是加上上一个位置
int newHeight = -deltaY + view.getHeight();
//更新位置
System.out.println("newHeight: " + newHeight);
//设置位置
view.getLayoutParams().height = newHeight;
//请求更新
view.requestLayout();
} else {//如果不是下拉状态,就返回false
flag = false;
}
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
2.根据手指抬起的点设定值动画,回弹效果
/**
* 手指抬起后动态的点
*/
private float setHeight;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
//手指刚抬起的图片高度
setHeight = view.getHeight();
//抬起手指后设定falg = false;
flag = false;
//设定值动画
ValueAnimator va = ValueAnimator.ofFloat(setHeight, globalHeight);
va.setDuration(2000);
va.start();
//动画监听,为了获取动态的数值
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获取动画设定的分数值
float fraction = animation.getAnimatedFraction();
//获取动画设定的间值
setHeight = (float) animation.getAnimatedValue();
System.out.println(setHeight);
System.out.println(fraction);
//动态shedding高度,并请求动画更新
view.getLayoutParams().height = (int) setHeight;
view.requestLayout();
}
});
break;
case MotionEvent.ACTION_DOWN:
//记录按下的点
down_dot = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
//判断是否可以滑动
if (flag) {
//设定滑动
int move2down = (int) (ev.getY() - down_dot);
int newHeight = view.getHeight() + move2down / 15;
System.out.println(newHeight + "-----");
if (newHeight > intriHeight) {//设定图片可以放置的最大值
newHeight = intriHeight;
}
//请求刷新Layout
// view.getLayoutParams().height = newHeight;
// view.requestLayout();
}
break;
}
return super.onTouchEvent(ev);
}
4,简单的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context="com.oblivion.parallax.MainActivity">
<com.oblivion.ui.ParallaxListView
android:id="@+id/plv_parallax"
android:layout_width="match_parent"
android:layout_height="match_parent"></com.oblivion.ui.ParallaxListView>
</RelativeLayout>