Android Listview或ImagevIew中的橡胶垫/松弛效果
我使用下面的自定义ListView来实现橡皮筋效果,它只从上到下拉伸图像 我需要从上到下和从下到上拉伸图像Android Listview或ImagevIew中的橡胶垫/松弛效果,android,Android,我使用下面的自定义ListView来实现橡皮筋效果,它只从上到下拉伸图像 我需要从上到下和从下到上拉伸图像 import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.animation.An
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.ListView;
import java.util.ArrayList;
public class ParallaxListView extends ListView implements OnScrollListener {
public final static double NO_ZOOM = 1;
private ArrayList<OnOverScrollByListener> mOnOverScrollByList = new ArrayList<OnOverScrollByListener>();
private ArrayList<OnTouchEventListener> mOnTouchEventList = new ArrayList<OnTouchEventListener>();
private ImageView mImageView;
private int mDrawableMaxHeight = -1;
private int mImageViewHeight = -1;
private OnOverScrollByListener scrollByListener = new OnOverScrollByListener() {
@Override
public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (mImageView.getHeight() <= mDrawableMaxHeight && isTouchEvent) {
if (deltaY < 0) {
if (mImageView.getHeight() - deltaY / 2 >= mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView
.getHeight() - deltaY / 2 < mDrawableMaxHeight ? mImageView
.getHeight() - deltaY / 2
: mDrawableMaxHeight;
mImageView.requestLayout();
}
} else {
if (mImageView.getHeight() > mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView
.getHeight() - deltaY > mImageViewHeight ? mImageView
.getHeight() - deltaY
: mImageViewHeight;
mImageView.requestLayout();
return true;
}
}
}
return false;
}
};
private OnTouchEventListener touchListener = new OnTouchEventListener() {
@Override
public void onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
if (mImageViewHeight - 1 < mImageView.getHeight()) {
ResetAnimimation animation = new ResetAnimimation(
mImageView, mImageViewHeight);
animation.setDuration(300);
mImageView.startAnimation(animation);
}
}
}
};
private OnOverScrollByListener onScroll = new OnOverScrollByListener() {
@Override
public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (mImageView.getHeight() <= mDrawableMaxHeight && isTouchEvent) {
if (deltaY < 0) {
if (mImageView.getHeight() - deltaY / 2 >= mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView
.getHeight() - deltaY / 2 < mDrawableMaxHeight ? mImageView
.getHeight() - deltaY / 2
: mDrawableMaxHeight;
mImageView.requestLayout();
}
} else {
if (mImageView.getHeight() > mImageViewHeight) {
mImageView.getLayoutParams().height = mImageView
.getHeight() - deltaY > mImageViewHeight ? mImageView
.getHeight() - deltaY
: mImageViewHeight;
mImageView.requestLayout();
return true;
}
}
}
return false;
}
};
private OnTouchEventListener onTouched = new OnTouchEventListener() {
@Override
public void onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
if (mImageViewHeight - 1 < mImageView.getHeight()) {
BackAnimimation animation = new BackAnimimation(mImageView,
mImageViewHeight, false);
animation.setDuration(300);
mImageView.startAnimation(animation);
}
}
}
};
private double mZoomRatio = 1;
public ParallaxListView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public ParallaxListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ParallaxListView(Context context) {
super(context);
init(context, null);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
public void setParallaxImageView(ImageView iv) {
mImageView = iv;
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.ParallaxScrollView, 0, 0);
mZoomRatio = a
.getFloat(R.styleable.ParallaxScrollView_zoomRatio, 1);
}
post(new Runnable() {
@Override
public void run() {
setViewsBounds(mZoomRatio);
}
});
}
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
boolean isCollapseAnimation = false;
Logger.LOGE("overScrollBy",""+true);
for (int i = 0; i < mOnOverScrollByList.size(); i++) {
isCollapseAnimation = mOnOverScrollByList.get(i).overScrollBy(
deltaX, deltaY, scrollX, scrollY, scrollRangeX,
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent)
|| isCollapseAnimation;
}
return isCollapseAnimation ? true : super.overScrollBy(deltaX, deltaY,
scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX,
maxOverScrollY, isTouchEvent);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
Logger.LOGE("onTouchEvent",ev.toString());
for (int i = 0; i < mOnTouchEventList.size(); i++) {
mOnTouchEventList.get(i).onTouchEvent(ev);
}
return super.onTouchEvent(ev);
}
/**
* Set the ImageView that will be used in the parallax changing his
* {@link ImageView.ScaleType} to CENTER_CROP.
*
* @paramview - An {@link ImageView} that will have the parallax effect.
*/
public void setImageViewToParallax(ImageView imageView) {
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
mImageView = imageView;
addOnScrolledListener(onScroll);
addOnTouchListener(onTouched);
}
private void addOnScrolledListener(OnOverScrollByListener onScrolled) {
Logger.LOGE("addOnScrolledLi",onScrolled.toString());
mOnOverScrollByList.add(onScrolled);
}
private void addOnTouchListener(OnTouchEventListener onTouched) {
Logger.LOGE("addOnTouchListener",onTouched.toString());
mOnTouchEventList.add(onTouched);
}
/**
* Set the bounds of the views and set the zoom of the view.
* <p/>
* Necessary to get the size of the Views.
* <p/>
* Have to put in the {@link #onWindowFocusChanged(boolean)} of the
* activity.
*
* @param zoomRatio Double - How many times is the max zoom of the image, minimum
* 1.
*/
public void setViewsBounds(double zoomRatio) {
if (mImageViewHeight == -1) {
mImageViewHeight = mImageView.getHeight();
double imageRatio = ((double) mImageView.getDrawable()
.getIntrinsicWidth()) / ((double) mImageView.getWidth());
mDrawableMaxHeight = (int) ((mImageView.getDrawable()
.getIntrinsicHeight() / imageRatio) * (zoomRatio > 1 ? zoomRatio
: 1));
}
}
private interface OnOverScrollByListener {
public boolean overScrollBy(int deltaX, int deltaY, int scrollX,
int scrollY, int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent);
}
private interface OnTouchEventListener {
public void onTouchEvent(MotionEvent ev);
}
public class ResetAnimimation extends Animation {
int targetHeight;
int originalHeight;
int extraHeight;
View mView;
protected ResetAnimimation(View view, int targetHeight) {
this.mView = view;
this.targetHeight = targetHeight;
originalHeight = view.getHeight();
extraHeight = this.targetHeight - originalHeight;
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
int newHeight;
newHeight = (int) (targetHeight - extraHeight
* (1 - interpolatedTime));
mView.getLayoutParams().height = newHeight;
mView.requestLayout();
}
}
}
导入android.content.Context;
导入android.content.res.TypedArray;
导入android.util.AttributeSet;
导入android.view.MotionEvent;
导入android.view.view;
导入android.view.animation.animation;
导入android.view.animation.Transformation;
导入android.widget.AbsListView;
导入android.widget.AbsListView.OnScrollListener;
导入android.widget.ImageView;
导入android.widget.ListView;
导入java.util.ArrayList;
公共类ParallaxListView扩展ListView实现OnScrollListener{
公共最终静态双无缩放=1;
private ArrayList mOnOverScrollByList=new ArrayList();
private ArrayList mOnTouchEventList=new ArrayList();
私有图像视图mImageView;
private int mDrawableMaxHeight=-1;
private int mImageViewHeight=-1;
私有OnOverScrollByListener scrollByListener=新OnOverScrollByListener(){
@凌驾
公共布尔overScrollBy(int deltaX、int deltaY、int scrollX、,
int scrollY,int scrollRangeX,int scrollRangeY,
int maxOverScrollX,int MaxOverScroly,boolean isTouchEvent){
if(mImageView.getHeight()=mImageViewHeight){
mImageView.getLayoutParams().height=mImageView
.getHeight()-deltaY/2mImageViewHeight){
mImageView.getLayoutParams().height=mImageView
.getHeight()-deltaY>mImageViewHeight?mImageView
.getHeight()-deltaY
:mImageViewHeight;
mImageView.requestLayout();
返回true;
}
}
}
返回false;
}
};
私有OnTouchEventListener touchListener=新OnTouchEventListener(){
@凌驾
公共事件(MotionEvent ev){
if(ev.getAction()==MotionEvent.ACTION\u UP){
if(mImageViewHeight-1mImageViewHeight){
mImageView.getLayoutParams().height=mImageView
.getHeight()-deltaY>mImageViewHeight?mImageView
.getHeight()-deltaY
:mImageViewHeight;
mImageView.requestLayout();
返回true;
}
}
}
返回false;
}
};
私有OnTouchEventListener onTouched=新OnTouchEventListener(){
@凌驾
公共事件(MotionEvent ev){
if(ev.getAction()==MotionEvent.ACTION\u UP){
if(mImageViewHeight-1 <resources>
<declare-styleable name="ParallaxScrollView">
<attr name="zoomRatio" format="float" />
</declare-styleable>
<declare-styleable name="JazzyViewPager">
<attr name="style">
<enum name="standard" value="0" />
<enum name="tablet" value="1" />
<enum name="cubein" value="2" />
<enum name="cubeout" value="3" />
<enum name="flipvertical" value="4" />
<enum name="fliphorizontal" value="5" />
<enum name="stack" value="6" />
<enum name="zoomin" value="7" />
<enum name="zoomout" value="8" />
<enum name="rotateup" value="9" />
<enum name="rotatedown" value="10" />
<enum name="accordion" value="11" />
</attr>
<attr name="fadeEnabled" format="boolean" />
<attr name="outlineEnabled" format="boolean" />
<attr name="outlineColor" format="color|reference" />
</declare-styleable>
<declare-styleable name="ScrimInsetsView">
<attr name="insetForeground" format="reference|color" />
</declare-styleable>
<declare-styleable name="CircleImageView">
<attr name="civ_border_width" format="dimension" />
<attr name="civ_border_color" format="color" />
<attr name="civ_border_overlay" format="boolean" />
<attr name="civ_fill_color" format="color" />
</declare-styleable>
</resources>