仿QQ实现带有阻尼效果的ScrollView的例子

 更新时间:2016年10月2日 16:23  点击:1828
下面我们来看一篇关于仿QQ实现带有阻尼效果的ScrollView的例子,希望这篇文章能够帮助各位朋友,具体的如下文介绍。

在使用QQ的过程中我们会发现一个很短的界面也是可以上下拖动的,这就是带有阻尼效果功能实现,要实现这样的功能呢,系统的ScrollView是没法实现的,必须要自定义继承于ScrollView的控件,先来看下效果图。

先来看看布局:


<?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="match_parent"
    android:orientation="vertical" >
 
    <frame.zmit.cn.stretchscrollview.StretchScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true" >
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#E6E6E6"
            android:orientation="vertical" >
 
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:textSize="16sp"
                android:background="#FFFFFF"
                android:gravity="center"
                android:text="5" />
 
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#E6E6E6" />
 
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:textSize="16sp"
                android:background="#FFFFFF"
                android:gravity="center"
                android:text="5" />
        </LinearLayout>
    </frame.zmit.cn.stretchscrollview.StretchScrollView>
 
</LinearLayout>

Activity啥也没有,就不贴了

下面贴上自定义的StretchScrollView


package frame.zmit.cn.stretchscrollview;
 
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
 
/**
 * A ScrollView which can scroll to (0,0) when pull down or up.
 *
 * @author markmjw
 * @date 2014-04-30
 */
public class StretchScrollView extends ScrollView {
    private static final int MSG_REST_POSITION = 0x01;
 
    /** The max scroll height. */
    private static final int MAX_SCROLL_HEIGHT = 600;
    /** Damping, the smaller the greater the resistance */
    private static final float SCROLL_RATIO = 0.4f;
 
    private View mChildRootView;
 
    private float mTouchY;
    private boolean mTouchStop = false;
 
    private int mScrollY = 0;
    private int mScrollDy = 0;
 
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (MSG_REST_POSITION == msg.what) {
                if (mScrollY != 0 && mTouchStop) {
                    mScrollY -= mScrollDy;
 
                    if ((mScrollDy < 0 && mScrollY > 0) || (mScrollDy > 0 && mScrollY < 0)) {
                        mScrollY = 0;
                    }
 
                    mChildRootView.scrollTo(0, mScrollY);
                    // continue scroll after 20ms
                    sendEmptyMessageDelayed(MSG_REST_POSITION, 20);
                }
            }
        }
    };
 
    public StretchScrollView(Context context) {
        super(context);
 
        init();
    }
 
    public StretchScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
 
        init();
    }
 
    public StretchScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
 
        init();
    }
 
    private void init() {
        // set scroll mode
        setOverScrollMode(OVER_SCROLL_NEVER);
    }
 
    @Override
    protected void onFinishInflate() {
        if (getChildCount() > 0) {
            // when finished inflating from layout xml, get the first child view
            mChildRootView = getChildAt(0);
        }
    }
 
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            mTouchY = ev.getY();
        }
        return super.onInterceptTouchEvent(ev);
    }
 
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (null != mChildRootView) {
            doTouchEvent(ev);
        }
        return super.onTouchEvent(ev);
    }
 
    private void doTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
 
        switch (action) {
            case MotionEvent.ACTION_UP:
                mScrollY = mChildRootView.getScrollY();
                if (mScrollY != 0) {
                    mTouchStop = true;
                    mScrollDy = (int) (mScrollY / 10.0f);
                    mHandler.sendEmptyMessage(MSG_REST_POSITION);
                }
                break;
 
            case MotionEvent.ACTION_MOVE:
                float nowY = ev.getY();
                int deltaY = (int) (mTouchY - nowY);
                mTouchY = nowY;
                if (isNeedMove()) {
                    int offset = mChildRootView.getScrollY();
                    if (offset < MAX_SCROLL_HEIGHT && offset > -MAX_SCROLL_HEIGHT) {
                        mChildRootView.scrollBy(0, (int) (deltaY * SCROLL_RATIO));
                        mTouchStop = false;
                    }
                }
                break;
 
            default:
                break;
        }
    }
 
    private boolean isNeedMove() {
        int viewHeight = mChildRootView.getMeasuredHeight();
        int scrollHeight = getHeight();
        int offset = viewHeight - scrollHeight;
        int scrollY = getScrollY();
 
        return scrollY == 0 || scrollY == offset;
    }
}

下面我们来看一篇关于安卓开发之使用Acache类对数据进行二级缓存(内存+文件)的一个详细使用例子,希望文章能够帮助到各位朋友。

Acache类下载地址:http://pan.baidu.com/s/1gfI0A9X

1、创建Acache实例

Acache acache;

acache = Acache.get(this, “main”);

2、将数据保存起来(内存和文件)

acache.put(key,value,time);

前两个无需赘述,键值对,最后一个time,传入int类型,单位为秒,代表缓存存在的时间,超出这个时间,就会清除掉缓存的数据。

3、获取缓存的数据

以一个例子来描述这个问题:

 代码如下 复制代码

public class MainActivity extends Activity {
private ImageView img;
Acache acache;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
acache = Acache.get(this, "main");
img = (ImageView) findViewById(R.id.img);
 
if (acache.getAsBitmap("pic") != null) {
Log.e("acache","正在使用缓存!");
img.setImageBitmap(acache.getAsBitmap("pic"));
} else {
Picasso.with(this).load("http://www.b.hsgjxt.com/image/cache/data/0-100x100.jpg").into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Log.e("Picasso","正在使用Picasso!");
img.setImageBitmap(bitmap);
acache.put("pic", bitmap, 10);
}
 
@Override
public void onBitmapFailed(Drawable errorDrawable) {
 
}
 
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
 
}
});
}
 
}
}

当我第一次进入的时候,控制台打印如下:

当我立即退出又进去,打印如下:

捕获2

当我延迟了十秒左右再进去,又提示如下:

捕获3

这样可以证明缓存可用,并且缓存的时间也有效果。

ListView实现倒计时的方法有无数种了,我们下面来为各位整理一下ListView中倒计时实现方法及ListView中倒计时过程中碰到的问题及处理 办法。

关于Android实现倒计时呢,对于很多人来说一直是一个头疼的问题,当然我也一样,在开发倒计时功能的时候会遇到很多棘手甚至奇葩的问题或者bug,我在开发倒计时的时候,如果当前页面只有一个倒计时,那么就不是很复杂,开发出来的效果也不是会非常糟糕,网上会有很多的教程实现。如果要在ListView或者GridView中实现倒计时呢,真的是一个很头疼的问题,我在这其中吃了很多苦头和走了很多弯路,还有死了很多脑细胞。下面我来总结一下在ListView中开发倒计时的问题。

先来展示一下我开发出来的效果图,这是在GridView中实现的:

 

view

一:数据混乱

描述一下什么叫数据混乱,比如说我有二十个倒计时在运行,第一个已经结束了,其他的都没有结束,我在往下滑动的时候,发现下面的某些倒计时也已经结束了,再循环滑动,又有不同的倒计时结束了,然后有时候本来已经结束的倒计时又开始倒计时了,这些就是在滑动过程中引发的数据混乱的问题。

二:倒计时重新开始:

描述一下什么叫倒计时重新开始,比如我的listview的第一个item在进行倒计时,从60秒开始减少,当减少到假如说40秒的时候,我往下滑动,使第一个item超出屏幕可见之外,再往上滑回第一个item,这时候你会发现倒计时又开始从60秒重新开始倒计时了,这是因为你的倒计时的时间如果是死的,在滑动回来的时候界面重绘,数据重新加载,所以倒计时又开始重新倒计时。

三:卡顿,超时,甚至崩溃:

这个就不用描述了,倒计时很多的话,就会出现卡顿的情况,如果非常多,手机就会死机崩溃,我在下载其他知名APP存在倒计时的界面进行使用时,一直上拉加载更多数据,出现很多的倒计时,发现也会卡顿,最后界面不能操作死机了。

四:倒计时不易控制和判断:

既然进行倒计时,那么我们就得需要监听倒计时什么时候结束,结束之后进行相应的操作,这是其一。其二,我们需要灵活的使用倒计时,比如是显示“年”、“天”、“时”、“分”、“秒”、“毫秒”等等,都要比较好控制和修改最好。

 

要解决这些问题呢,其实是很困难的,我查过很多的方式来实现发现都不是很好,甚至不能解决问题。最后呢,我找到了一个第三方依赖库,在github上也有,具体地址我找不到了,不过在it蓝豹上也有,这

 

在使用这个方式实现倒计时的时候,只解决了第三和第四的问题,说实话卡顿和控制方面解决了就好多了。另外我在使用的时候发现也会出现第一和第二个问题,当然在他的项目里也有在listview中的Demo,不过有点复杂我就没有深度研究,按照最基本的继承BaseAdapter和ViewHolder优化实现的方式来开发会出现数据错乱和重新开始的bug,最后我就在想能不能把倒计时时间来转化成本地时间进行倒计时,最后的结果是完全可以,不过可能会有一点误差,神奇的是连同数据混乱的bug也消失了。

比如说倒计时需要100秒,那么我就拿本地的时间加上这100秒作为结束时间,然后在倒计时需要开始的时候,拿上这结束时间减去本地时间就是需要倒计时的时间。

具体的代码如下:

具体的代码如下:

本地时间:long curTime = System.currentTimeMillis();//注意:单位毫秒
结束时间:curTime +(100*1000);//注意:单位毫秒,把100秒转化为毫秒
在需要倒计时的地方开启倒计时:

cv_countdownView.start(itemData.getEndtime() - System.currentTimeMillis());
同时,在监听方面,此依赖提供了一个接口:

代码如下:


cv_countdownView.setOnCountdownEndListener(new CountdownView.OnCountdownEndListener() {
 @Override public void onEnd(CountdownView cv) {
 //时间结束 }
 });

在布局中使用也非常简单,

<cn.iwgang.countdownview.CountdownView
    android:id="@+id/cv_countdownView_one"
    android:layout_width="90dp"
    android:layout_height="30dp"
    android:layout_gravity="center_horizontal"
    app:isShowDay="false"
    app:isShowHour="false"
    app:isShowMillisecond="true"
    app:isShowMinute="true"
    app:isShowSecond="true"
    app:suffixGravity="center"
    app:suffixTextColor="#FFFFFF"
    app:suffixTextSize="14sp"
    app:timeTextColor="#FFFFFF"
    app:timeTextSize="14sp" />;

需要显示什么就写为true,否则false就可以了。

我觉得最关键的还是流畅不卡顿最重要。

好了,这就是我在开发倒计时的时候遇到的问题总结,希望能帮助到更多的人。谢谢,此文章是我一字一字打出来的,转载请注明。谢谢

原文来自 :http://blog.it985.com/16781.html

我们来看一篇关于Android自定义View加载gif图片的例子,这样可以动态的加载gif动态图片了,下面看代码如何实现的。

申明:本博客无图无真相,但是我亲测可以加载出来,假设出现只能加载一帧的情况,请在布局中加:

 代码如下 复制代码

android:layerType="software" 

下面是自定义View的代码:

 

 代码如下 复制代码
package cn.zmit.foot.listviewfoot;
 
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
 
import java.io.InputStream;
 
/**
* Created by Administrator on 2016/6/15 0015.
*/
public class MyImageView extends View {
private Movie mMovie;
 
public MyImageView(Context context) {
super(context,null);
}
 
public MyImageView(Context context, AttributeSet attrs) {
super(context, attrs);
InputStream is = getResources().openRawResource(R.raw.img);
mMovie = Movie.decodeStream(is);
}
long mMovieStart = 0;
 
@Override
public void draw(Canvas canvas) {
long curTime = android.os.SystemClock.uptimeMillis();
if (mMovieStart == 0) {
mMovieStart = curTime;
}
if (mMovie != null) {
int duraction = mMovie.duration();
int relTime = (int) ((curTime - mMovieStart) % duraction);
mMovie.setTime(relTime);
mMovie.draw(canvas, 0, 0);
invalidate();
}
super.draw(canvas);
}
 
}
[!--infotagslink--]

相关文章

  • Painter绘制红衣喝酒男水粉画效果教程

    今天小编在这里就来给Painter的这一款软件的使用者们来说一说绘制红衣喝酒男水粉画效果的教程,各位想知道具体绘制步骤的使用者,那么下面就快来跟着小编一起看一看教程...2016-09-14
  • php语言实现redis的客户端

    php语言实现redis的客户端与服务端有一些区别了因为前面介绍过服务端了这里我们来介绍客户端吧,希望文章对各位有帮助。 为了更好的了解redis协议,我们用php来实现...2016-11-25
  • photoshop用各种素材合成闪电侠效果制作教程

    今天小编在这里就来给photoshop的这一款软件的使用者们来说说利用各种素材合成闪电侠效果的制作教程,各位想知道具体制作步骤的使用者们,那么下面就快来跟着小编一起看...2016-09-14
  • jQuery+jRange实现滑动选取数值范围特效

    有时我们在页面上需要选择数值范围,如购物时选取价格区间,购买主机时自主选取CPU,内存大小配置等,使用直观的滑块条直接选取想要的数值大小即可,无需手动输入数值,操作简单又方便。HTML首先载入jQuery库文件以及jRange相关...2015-03-15
  • Linux下PHP安装curl扩展支持https例子

    安装curl扩展支持https是非常的重要现在许多的网站都使用了https了,下面我们来看一篇关于PHP安装curl扩展支持https例子吧。 问题: 线上运行的lamp服务器,默认yu...2016-11-25
  • JS实现的简洁纵向滑动菜单(滑动门)效果

    本文实例讲述了JS实现的简洁纵向滑动菜单(滑动门)效果。分享给大家供大家参考,具体如下:这是一款纵向布局的CSS+JavaScript滑动门代码,相当简洁的手法来实现,如果对颜色不满意,你可以试着自己修改CSS代码,这个滑动门将每一...2015-10-21
  • 美图秀秀把普通照片快速转换成卡通效果教程

    今天小编在这里就来给美图秀秀的这一款软件的使用者们来说下把普通照片快速转换成卡通效果的教程,各位想知道具体制作步骤的使用者们,那么下面就快阿里跟着小编一起看一...2016-09-14
  • JS实现双击屏幕滚动效果代码

    本文实例讲述了JS实现双击屏幕滚动效果代码。分享给大家供大家参考,具体如下:这里演示双击滚屏效果代码的实现方法,不知道有觉得有用处的没,现在网上还有很多还在用这个特效的呢,代码分享给大家吧。运行效果截图如下:在线演...2015-10-30
  • jQuery+slidereveal实现的面板滑动侧边展出效果

    我们借助一款jQuery插件:slidereveal.js,可以使用它控制面板左右侧滑出与隐藏等效果,项目地址:https://github.com/nnattawat/slideReveal。如何使用首先在页面中加载jquery库文件和slidereveal.js插件。复制代码 代码如...2015-03-15
  • photoshop调出时尚个性青色人像照片效果调色教程

    今天小编在这里就来给photoshop的这一款软件的使用者们来说说调出时尚个性青色人像照片效果的调色教程,各位想知道到底该怎么调色的,那么下面就快来跟着小编一起看一看...2016-09-14
  • PHP+jQuery翻板抽奖功能实现

    翻板抽奖的实现流程:前端页面提供6个方块,用数字1-6依次表示6个不同的方块,当抽奖者点击6个方块中的某一块时,方块翻转到背面,显示抽奖中奖信息。看似简单的一个操作过程,却包含着WEB技术的很多知识面,所以本文的读者应该熟...2015-10-21
  • SQLMAP结合Meterpreter实现注入渗透返回shell

    sqlmap 是一个自动SQL 射入工具。它是可胜任执行一个广泛的数据库管理系统后端指印, 检索遥远的DBMS 数据库等,下面我们来看一个学习例子。 自己搭建一个PHP+MYSQ...2016-11-25
  • PHP实现今天是星期几的几种写法

    复制代码 代码如下: // 第一种写法 $da = date("w"); if( $da == "1" ){ echo "今天是星期一"; }else if( $da == "2" ){ echo "今天是星期二"; }else if( $da == "3" ){ echo "今天是星期三"; }else if( $da == "4"...2013-10-04
  • ps怎么制作图片阴影效果

    ps软件是现在很多人比较喜欢的,有着非常不错的使用效果,这次文章就给大家介绍下ps怎么制作图片阴影效果,还不知道制作方法的赶紧来看看。 ps图片阴影效果怎么做方法/...2017-07-06
  • ps立体倒影效果制作方法

    ps软件是现在很多人比较喜欢使用的,有着非常不错的功能。这次文章就给大家介绍下ps立体倒影效果制作方法,还不知道怎么制作的赶紧来看看。 最终效果&#8195;&#8195;1...2017-07-06
  • 原生js实现fadein 和 fadeout淡入淡出效果

    js里面设置DOM节点透明度的函数属性:filter= "alpha(opacity=" + value+ ")"(兼容ie)和opacity=value/100(兼容FF和GG)。 先来看看设置透明度的兼容性代码: 复制代码 代码如下: function setOpacity(ele, opacity) { if (...2014-06-07
  • php使用floor去掉小数点的例子

    floor会产生小数了如果我们不希望有小数我们是可以去除小数点的了,下面一聚教程小编来为各位介绍php使用floor去掉小数点的例子,希望对各位有帮助。 float floor (...2016-11-25
  • ps制作立体文字效果教程

    ps软件是现在非常受大家喜欢的一款软件,有着非常不错的制作效果。下面文章就给大家介绍下ps制作立体文字效果教程,感兴趣的一起来看看。 ps文字立体效果怎么做最终...2017-07-06
  • 利用Photoshop打造科幻片中的人物粒子化消失效果

    本文章分享一篇关于Photoshop打造科幻片中的人物粒子化消失效果,教程重点是画笔的应用,人物身上产生的碎块,颗粒等都是用自定或下载的笔刷来完成,制作之前最好先下载一些...2016-09-14
  • jQuery实现的文字hover颜色渐变效果实例

    这篇文章主要介绍了jQuery实现的文字hover颜色渐变效果,以完整实例形式分析了jQuery实现文字颜色渐变效果的相关技巧,涉及jQuery插件jquery-ui-1.8.16.custom.min.js的使用,需要的朋友可以参考下...2016-02-23