自定义ScrollView控件 -- 拉申时跟随缩放效果

来源:互联网 发布:平板电脑js加载错误 编辑:程序博客网 时间:2024/06/04 17:44

需求就是让第一张的图片在拉申时跟随缩放效果。


一个可以滑动的自定义ScrollView控件,放大第一个子控件。还能监听它滑动时位置

不废话直接上效果图

  • 这个中间放大的效果图:

这里写图片描述


直接上代码了:

  • 自定义的ScrollView控件
/** * 自定义的下拉放大scrollView,还具备监听滑动位置的功能 * 这个控件只是将它里面第一个控件放大 * 只需要将第一个放ImageView控件 */public class DropEnlargeScrollView extends ScrollView implements View.OnTouchListener {    // 记录首次按下位置    private float mFirstPosition = 0;    // 是否正在放大    private Boolean mScaling = false;    private View dropZoomView;    private int dropZoomViewWidth;    private int dropZoomViewHeight;    public DropEnlargeScrollView(Context context) {        super(context);    }    public DropEnlargeScrollView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public DropEnlargeScrollView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onFinishInflate() {        super.onFinishInflate();        init();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    private void init() {        setOverScrollMode(OVER_SCROLL_NEVER);        if (getChildAt(0) != null) {            ViewGroup vg = (ViewGroup) getChildAt(0);            if (vg.getChildAt(0) != null) {                dropZoomView = vg.getChildAt(0);                setOnTouchListener(this);            }        }    }    @Override    public boolean onTouch(View v, MotionEvent event) {        if (dropZoomViewWidth <= 0 || dropZoomViewHeight <= 0) {            dropZoomViewWidth = dropZoomView.getMeasuredWidth();            dropZoomViewHeight = dropZoomView.getMeasuredHeight();        }        switch (event.getAction()) {            case MotionEvent.ACTION_UP:                //手指离开后恢复图片                mScaling = false;                replyImage();                break;            case MotionEvent.ACTION_MOVE:                if (!mScaling) {                    if (getScrollY() == 0) {                        mFirstPosition = event.getY();// 滚动到顶部时记录位置,否则正常返回                    } else {                        break;                    }                }                int distance = (int) ((event.getY() - mFirstPosition) * 0.6); // 滚动距离乘以一个系数                if (distance < 0) { // 当前位置比记录位置要小,正常返回                    break;                }                // 处理放大                mScaling = true;                setZoom(distance);                return true; // 返回true表示已经完成触摸事件,不再处理        }        return false;    }    // 回弹动画 (使用了属性动画)    public void replyImage() {        final float distance = dropZoomView.getMeasuredWidth() - dropZoomViewWidth;        // 设置动画        ValueAnimator anim = ObjectAnimator.ofFloat(0.0F, 1.0F).setDuration((long) (distance * 0.7));        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                float cVal = (Float) animation.getAnimatedValue();                setZoom(distance - ((distance) * cVal));            }        });        anim.start();    }    //缩放    public void setZoom(float s) {        if (dropZoomViewHeight <= 0 || dropZoomViewWidth <= 0) {            return;        }        ViewGroup.LayoutParams lp = dropZoomView.getLayoutParams();        lp.width = (int) (dropZoomViewWidth + s);        lp.height = (int) (dropZoomViewHeight * ((dropZoomViewWidth + s) / dropZoomViewWidth));        dropZoomView.setLayoutParams(lp);    }    private ScrollViewListener scrollViewListener = null;    /**     * 需要监听滑动就在activity中,因为直接在activity中监听不了onScrollChanged事件     * 如:view.setScrollViewListener(scrollViewListener)     *     * @param scrollViewListener 滑动监听     */    public void setScrollViewListener(ScrollViewListener scrollViewListener) {        this.scrollViewListener = scrollViewListener;    }    //滑动时就触发这个方法    @Override    protected void onScrollChanged(int x, int y, int oldx, int oldy) {        super.onScrollChanged(x, y, oldx, oldy);        if (scrollViewListener != null) {            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);        }    }}

  • 回调接口
/** * 这个是监听滑动的回调接口 */public interface ScrollViewListener {    void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy);}

  • 页面:Main2Activity
public class Main2Activity extends AppCompatActivity implements ScrollViewListener {    private String TAG = "Main2Activity";    private DropEnlargeScrollView de_scrollview;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        de_scrollview = (DropEnlargeScrollView)findViewById(R.id.de_scrollview);        de_scrollview.setScrollViewListener(this);    }    @Override    public void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy) {        Log.d(TAG, "x = "+x+", "+"y = "+y+", "+"oldx = "+oldx+", "+"oldy = "+oldy);    }}

  • 布局页面:activity_main2.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="#66666666"    android:orientation="vertical">    <!--注意,注意,,这个就是你存放DropEnlargeScrollView的完整路径-->    <com.example.administrator.test.view.DropEnlargeScrollView        android:id="@+id/de_scrollview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:scrollbars="none">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:background="#ffffff"            android:orientation="vertical">            <ImageView                android:id="@+id/iv_mo_img"                android:layout_width="match_parent"                android:layout_height="150dp"                android:layout_weight="1"                android:layout_gravity="center"                android:scaleType="fitXY"                android:src="@mipmap/img" />            <View                android:layout_width="match_parent"                android:layout_height="1000dp"/>        </LinearLayout>    </com.example.administrator.test.view.DropEnlargeScrollView></LinearLayout>

外话:

  • 如果要左上顶点放大的效果图:

这里写图片描述

只需要将ImageView的属性 android:layout_gravity=”center”,去掉即可。

阅读全文
1 0
原创粉丝点击