仿凤凰FM图文滑动特效

模仿凤凰FM图文完成滑动特效。在使用的过程中,发现一些问题,再次修正一下。

这里写图片描述

1.结合代码讲解原理

-定义 BlockScrollView,拦截WebView的活动事件

package com.example.androidimagetextdemo;

public class BlockScrollView extends ScrollView {
    private ScroollViewScrollListener mListener;
    public interface  ScroollViewScrollListener{
         void onScrollChanged(int l, int t, int oldl, int oldt);
    }

    public BlockScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    //可以通过监听该方法,获取当前滑动的位置,进行标题栏背景色的渐变
    public void setScrollListener(ScroollViewScrollListener scrollListener){
        this.mListener=scrollListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if(mListener!=null){
            mListener.onScrollChanged(l, t, oldl, oldt);
        }

    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }

  • 定义布局文件
<FrameLayout 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"
    android:layout_gravity="center"
    android:orientation="vertical"
    tools:context="${relativePackage}.${activityClass}" >
        <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/black"
        android:contentDescription="@null"
        android:scaleType="matrix"
        android:src="@drawable/ic_launcher" />
    <com.example.androidimagetextdemo.BlockScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >
            <View
                android:id="@+id/blank"
                android:layout_width="match_parent"
                android:layout_height="200dp" />
            <WebView
                android:id="@+id/view_web"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </com.example.androidimagetextdemo.BlockScrollView>
</FrameLayout>

WebView嵌套在ScrollView中,通过添加blank View,使WebView相对于ImageView向下发生移动,让ImageView不会被覆盖(通过 控制blankView的尺寸,来控制图片的显示尺寸)。
注意:
这里如果使用WebView setTranslationY,当WebView滑动底端后,其内容不能够完全展示。
- 主页面BlockScrollView touch事件的处理

    OnTouchListener touchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix); // 把原始 Matrix对象保存起来
                pullPoint.set(event.getX(), event.getY()); // 设置x,y坐标
                break;
            case MotionEvent.ACTION_UP: {
                float pullDistance = movedYDistance(event);
                if (v.getScrollY() <= 0 && pullDistance > 0) {
                    RectF drawableRect = new RectF(0, 0, bitmap.getWidth(),
                            bitmap.getHeight());
                    RectF viewRect = new RectF(0, 0,
                            getScreenWidth(MainActivity.this),
                            getScreenWidth(MainActivity.this));
                    matrix.reset();
                    matrix.setRectToRect(drawableRect, viewRect,
                            Matrix.ScaleToFit.FILL);
                    mWebView.setTranslationY(0);

                    MODE = TOUCH_RESUME;
                }
            }

                break;
            case MotionEvent.ACTION_MOVE:
            //研究过安卓中touch事件传递的同学都知道,只要手指放到屏幕上,必然会调用Action_move.
            //所以这里如果为0,手指只要手指放到屏幕上,就会有滑动效果,用户会感觉很奇怪
            if (v.getScrollY() > 20) {
                    MODE = TOUCH_NONE;
                } else {
                    float pullDistance = movedYDistance(event);
                    if (pullDistance > 0) {
                        matrix.set(savedMatrix);
                        float scale = 1 + pullDistance
                                / getScreenWidth(MainActivity.this);
                        // matrix.postScale(scale, scale,
                        // 0, 0);
                        matrix.postScale(scale, scale,
                                getScreenWidth(MainActivity.this) / 2, 0);
                        mWebView.setTranslationY(pullDistance);
                        MODE = TOUCH_PULL;
                    } else {
                        MODE = TOUCH_NONE;
                    }
                }
                break;
            }
            if (MODE == TOUCH_PULL || MODE == TOUCH_RESUME) {
                imageView.setImageMatrix(matrix);
                return true;
            } else {
                return false;
            }
        }
    };

1.用户按下后,记录用户按下的位置,保存原始的Matrix对象

2.当前页面滑动后,如果是向上滑动,交给系统进行处理;否则,根据用户滑动的距离计算缩放比例;通过matrix进行ImageView的缩放,并对WebView进行偏移

3.当用户抬起手指后,
通过ScrollView,getScrollY()<=0,判断显示是否为ScrollView的初始展示状态(也就是没有进行向上的scroll);
通过movedYDistance,判断用户是否向下进行了拉伸;如果两者都满足对滑动过程中发生拉伸的ImageView&&WebView进行恢复,否则交给系统处理
- 主页面完整代码

package com.example.androidimagetextdemo;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebView.HitTestResult;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;

public class MainActivity extends Activity {
    public static final String TAG = MainActivity.class.getSimpleName();
    private static final int TOUCH_NONE = 0;
    private static final int TOUCH_PULL = 1;
    private static final int TOUCH_RESUME = 2;
    private static final String URL_WEB = "http://www.dingdongfm.com/wechat/jsp/Topic/topicDetail.jsp?topicId=1SUegBSg-1460950984623-14625233706364205&type=circle";

    private int MODE = TOUCH_NONE;

    ImageView imageView;
    WebView mWebView;
    View blankView;
    BlockScrollView myScrollView;

    private PointF pullPoint = new PointF();
    private Matrix matrix = new Matrix();
    private Matrix savedMatrix = new Matrix();
    Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_visual);
        imageView = (ImageView) findViewById(R.id.iv);
        mWebView = (WebView) findViewById(R.id.view_web);
        blankView = findViewById(R.id.blank);
        myScrollView = (BlockScrollView) findViewById(R.id.scroll_view);
        initLayoutParams();

        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        mWebView.getSettings().setBuiltInZoomControls(false); // 设置支持缩放
        mWebView.getSettings().setAllowFileAccess(true);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
        mWebView.getSettings().setAllowFileAccess(true);
        mWebView.getSettings().setAppCacheEnabled(true);
        mWebView.getSettings().setDomStorageEnabled(true);
        mWebView.getSettings().setDatabaseEnabled(true);
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                HitTestResult hit = view.getHitTestResult();
                if (hit != null) {
                    int hitType = hit.getType();
                    if (hitType == HitTestResult.SRC_ANCHOR_TYPE
                            || hitType == HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {// 点击超链接
                        Intent i = new Intent(Intent.ACTION_VIEW);
                        i.setData(Uri.parse(url));
                    }
                } else {
                    view.loadUrl(url);
                }

                return true;
            }
        });
        mWebView.loadUrl(URL_WEB);
        myScrollView.setOnTouchListener(touchListener);
        imageView.setScaleType(ScaleType.MATRIX);
        bitmap = BitmapFactory.decodeResource(getResources(),
                R.drawable.ic_launcher);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
        RectF drawableRect = new RectF(0, 0, bitmap.getWidth(),
                bitmap.getHeight());
        RectF viewRect = new RectF(0, 0, getScreenWidth(this),
                getScreenWidth(this));
        matrix.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.FILL);
        imageView.setImageMatrix(matrix);

    }

    public static int getScreenHeight(Activity packageContext) {
        DisplayMetrics metrics = new DisplayMetrics();
        packageContext.getWindowManager().getDefaultDisplay()
                .getMetrics(metrics);
        return metrics.heightPixels;

    }

    public static int getScreenWidth(Activity packageContext) {
        DisplayMetrics metrics = new DisplayMetrics();
        packageContext.getWindowManager().getDefaultDisplay()
                .getMetrics(metrics);
        return metrics.widthPixels;

    }

    OnTouchListener touchListener = new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix); // 把原始 Matrix对象保存起来
                pullPoint.set(event.getX(), event.getY()); // 设置x,y坐标
                break;
            case MotionEvent.ACTION_UP: {
                float pullDistance = movedYDistance(event);
                if (v.getScrollY() <= 0 && pullDistance > 0) {
                    RectF drawableRect = new RectF(0, 0, bitmap.getWidth(),
                            bitmap.getHeight());
                    RectF viewRect = new RectF(0, 0,
                            getScreenWidth(MainActivity.this),
                            getScreenWidth(MainActivity.this));
                    matrix.reset();
                    matrix.setRectToRect(drawableRect, viewRect,
                            Matrix.ScaleToFit.FILL);
                    mWebView.setTranslationY(0);

                    MODE = TOUCH_RESUME;
                }
            }

                break;
            case MotionEvent.ACTION_MOVE:
                if (v.getScrollY() > 20) {
                    MODE = TOUCH_NONE;
                } else {
                    float pullDistance = movedYDistance(event);
                    if (pullDistance > 0) {
                        matrix.set(savedMatrix);
                        float scale = 1 + pullDistance
                                / getScreenWidth(MainActivity.this);
                        // matrix.postScale(scale, scale,
                        // 0, 0);
                        matrix.postScale(scale, scale,
                                getScreenWidth(MainActivity.this) / 2, 0);
                        mWebView.setTranslationY(pullDistance);
                        MODE = TOUCH_PULL;
                    } else {
                        MODE = TOUCH_NONE;
                    }
                }
                break;
            }
            if (MODE == TOUCH_PULL || MODE == TOUCH_RESUME) {
                imageView.setImageMatrix(matrix);
                return true;
            } else {
                return false;
            }
        }
    };

    private float movedYDistance(MotionEvent event) {
        float y = event.getY(0) - pullPoint.y;
        return y;
    }

    public void initLayoutParams() {

        LinearLayout.LayoutParams blankParams = (LinearLayout.LayoutParams) blankView
                .getLayoutParams();
        blankParams.height = getScreenWidth(this);

    }
}

2.Demo下载

http://download.csdn.net/detail/guchuanhang/9516181

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值