微信朋友圈上面的图片封面,QQ空间说说上面的图片封面都有下拉反弹的效果,这些都是使用滚动栏实现的。下拉,当松开时候。反弹至原来的位置。下拉时候能看到背景图片。那么这里简介一下这样的效果的实现。

本文源代码下载:点击

1、效果图

这部手机显示的分辨率有限,非常老的手机调试。

2、具有反弹效果BounceScrollView

package com.org.scroll;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView; /**
* ScrollView反弹效果的实现
*/
public class BounceScrollView extends ScrollView {
private View inner;// 孩子View private float y;// 点击时y坐标
// 矩形(这里仅仅是个形式,仅仅是用于推断是否须要动画.)
private Rect normal = new Rect(); private boolean isCount = false;// 是否開始计算 public BounceScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
} /***
* 依据 XML 生成视图工作完毕.该函数在生成视图的最后调用,在全部子视图加入完之后. 即使子类覆盖了 onFinishInflate
* 方法,也应该调用父类的方法,使该方法得以运行.
*/
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
inner = getChildAt(0);
}
} /***
* 监听touch
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (inner != null) {
commOnTouchEvent(ev);
} return super.onTouchEvent(ev);
} /***
* 触摸事件
*
* @param ev
*/
public void commOnTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
// 手指松开.
if (isNeedAnimation()) {
animation();
isCount = false;
}
break;
/***
* 排除出第一次移动计算。由于第一次无法得知y坐标。 在MotionEvent.ACTION_DOWN中获取不到,
* 由于此时是MyScrollView的touch事件传递到到了LIstView的孩子item上面.所以从第二次计算開始.
* 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常运行.
*/
case MotionEvent.ACTION_MOVE:
final float preY = y;// 按下时的y坐标
float nowY = ev.getY();// 时时y坐标
int deltaY = (int) (preY - nowY);// 滑动距离
if (!isCount) {
deltaY = 0; // 在这里要归0.
} y = nowY;
// 当滚动到最上或者最下时就不会再滚动,这时移动布局
if (isNeedMove()) {
// 初始化头部矩形
if (normal.isEmpty()) {
// 保存正常的布局位置
normal.set(inner.getLeft(), inner.getTop(),
inner.getRight(), inner.getBottom());
}
// Log.e("jj", "矩形:" + inner.getLeft() + "," + inner.getTop()
// + "," + inner.getRight() + "," + inner.getBottom());
// 移动布局
inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2,
inner.getRight(), inner.getBottom() - deltaY / 2);
}
isCount = true;
break; default:
break;
}
} /***
* 回缩动画
*/
public void animation() {
// 开启移动动画
TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
normal.top);
ta.setDuration(200);
inner.startAnimation(ta);
// 设置回到正常的布局位置
inner.layout(normal.left, normal.top, normal.right, normal.bottom); // Log.e("jj", "回归:" + normal.left + "," + normal.top + "," + normal.right
// + "," + normal.bottom); normal.setEmpty(); } // 是否须要开启动画
public boolean isNeedAnimation() {
return !normal.isEmpty();
} /***
* 是否须要移动布局 inner.getMeasuredHeight():获取的是控件的总高度
*
* getHeight():获取的是屏幕的高度
*
* @return
*/
public boolean isNeedMove() {
int offset = inner.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
// Log.e("jj", "scrolly=" + scrollY);
// 0是顶部。后面那个是底部
if (scrollY == 0 || scrollY == offset) {
return true;
}
return false;
} }

3、MainActivity

package com.org.activity;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
} }

这个没做什么,主要看布局,以及BounceScrollView类。

4、activity_main布局

<LinearLayout 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:orientation="vertical" > <include layout="@layout/common_title_bg" /> <com.org.scroll.BounceScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/coversation_bg"
android:focusable="true"
android:focusableInTouchMode="true" > <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="10.0dip" > <RelativeLayout
android:id="@+id/accountSetting"
android:layout_width="fill_parent"
android:layout_height="63.0dip"
android:background="#80ffffff"
android:focusable="true" > <FrameLayout
android:id="@+id/frameLayout1"
android:layout_width="54.0dip"
android:layout_height="54.0dip"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip" > <ImageView
android:id="@+id/face"
android:layout_width="50.0dip"
android:layout_height="50.0dip"
android:layout_gravity="center"
android:contentDescription="@null"
android:src="@drawable/h0" /> <ImageView
android:id="@+id/statusIcon"
android:layout_width="18.0dip"
android:layout_height="18.0dip"
android:layout_gravity="bottom|right|center"
android:contentDescription="@null" />
</FrameLayout> <ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10.0dip"
android:contentDescription="@null"
android:duplicateParentState="true" /> <TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/nick"
android:layout_marginRight="10.0dip"
android:layout_toLeftOf="@id/imageView1"
android:duplicateParentState="true"
android:text="在线" /> <TextView
android:id="@+id/nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10.0dip"
android:layout_marginRight="69.0dip"
android:layout_toRightOf="@id/frameLayout1"
android:duplicateParentState="true"
android:ellipsize="end"
android:singleLine="true" />
</RelativeLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="600dp"
android:layout_marginTop="16.0dip"
android:layout_weight="2.13"
android:background="#ffffffff"
android:orientation="vertical" > <TextView
android:id="@+id/my_profile"
android:layout_width="fill_parent"
android:layout_height="44.0dip"
android:background="#800000ff"
android:clickable="true"
android:gravity="center_vertical"
android:paddingLeft="10.0dip"
android:paddingRight="10.0dip"
android:text="标题一" /> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16.0dip"
android:orientation="vertical" > <RelativeLayout
android:id="@+id/set_feedback"
android:layout_width="fill_parent"
android:layout_height="44.0dip"
android:background="#8000ffff"
android:clickable="true"
android:focusable="true" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="12.0dip"
android:duplicateParentState="true"
android:gravity="center_vertical"
android:text="反馈" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</com.org.scroll.BounceScrollView> </LinearLayout>

松开向上弹时候,还能够设置一下,详细用的时候再调试设置一下吧!

本文源代码下载:点击

android 滚动栏下拉反弹的效果(相似微信朋友圈)的更多相关文章

  1. Android实现系统下拉栏的消息提示——Notification

    Android实现系统下拉栏的消息提示--Notification 系统默认样式 默认通知(通用) 效果图 按钮 <Button android:layout_width="match ...

  2. Android 第三方开源下拉框:NiceSpinner

    Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定 ...

  3. Android之SwipeRefreshLayout下拉刷新组件

    SwipeRefreshLayout概述 SwipeRefrshLayout是Google官方更新的一个Widget,可以实现下拉刷新的效果.该控件集成自ViewGroup在support-v4兼容包 ...

  4. Android:有关下拉菜单导航的学习(供自己参考)

    Android:有关==下拉菜单导航==的学习 因为先前的学习都没想着记录自己的学习历程,所以该博客才那么迟才开始写. 内容: ==下拉菜单导航== 学习网站:android Spinner控件详解 ...

  5. android 开发-spinner下拉框控件的实现

    Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...

  6. Android第三方开源下拉框:NiceSpinner

     Android第三方开源下拉框:NiceSpinner Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Andro ...

  7. UI中经常出现的下拉框下拉自动筛选效果的实现

    小需求是当你在第一个下拉框选择了国家时,会自动更新第二个省份的下拉框,效果如下 两个下拉选择Html如下: <select id="country_select"> & ...

  8. 美团、点评、猫眼App下拉加载效果的源码分享

    今天我准备拿大众点评.美团.猫眼电影三款App的实例来分享一下APICloud下拉加载这个模块的效果. 美团App下拉加载效果   以美团中的下拉酷似动画的萌萌着小人儿效果作为参考,来实现的一个加载模 ...

  9. 谷歌下解决Pop遮罩层无法遮挡滚动栏下问题

    今天用pop的弹出窗体里,出现一个问题,当网页出现滚动栏里,不能遮挡住,解决Pop遮罩层无法遮挡滚动栏下问题. 可通过下载获取改动后的代码----->进入下载

随机推荐

  1. 设计模式六大原则(三):依赖倒置原则(Dependence Inversion Principle)

    依赖倒置原则(DIP)定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象:抽象不应该依赖细节:细节应该依赖抽象. 问题由来: 类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码 ...

  2. 华为OJ:字符串反转

    非常easy,逆向输出就好了. import java.util.Scanner; public class convertString { public static void main(Strin ...

  3. Spring MVC框架实例

    Spring  MVC 背景介绍 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC 架构,能够选择是使用内置的 Spring Web 框架还是 ...

  4. Linux下常用的中文输入法平台有IBus、fcitx和scim

    Linux下常用的中文输入法平台有IBus.fcitx和scim.scim现在维护滞后,不推荐使用. IBus ("Intelligent Input Bus") 是一个 输入法框 ...

  5. jquery点击完一个按钮,并且触发另一个按钮

    $a.click(function(){ $b.trigger('click'); });

  6. echarts+百度地图+vue 填坑记(一)(百度地图、鼠标移入移出标注,信息框会产生闪烁)

    大概七月底开始实习,到现在经历了两个完整的项目(c2b). 因为开发时间紧,任务重,所以在开发过程踩到的坑都没时间去记录. 现在在开发一个某链运输监控系统,到了收尾阶段,有时间写博客了!开心! 一.鼠 ...

  7. HDU 2473 Junk-Mail Filter 并查集删除(FZU 2155盟国)

    http://acm.hdu.edu.cn/showproblem.php?pid=2473 http://acm.fzu.edu.cn/problem.php?pid=2155 题目大意: 编号0~ ...

  8. liunx基本操作常用命令

    liunx通常用作服务器,运行服务器软件,服务器要等待,类似超市学关键命令操作 内核,外壳 shell命令跟内核打交道用的是发行版本,不是内核,Radhat公司的CentOS,阿里巴巴也用这个 liu ...

  9. Surging 分布式微服务框架使用入门

    原文:Surging 分布式微服务框架使用入门 前言 本文非 Surging 官方教程,只是自己学习的总结.如有哪里不对,还望指正. 我对 surging 的看法 我目前所在的公司采用架构就是类似与S ...

  10. UVA 11136 - Hoax or what (可以提交了,不会Submission error了)

    看题传送门:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...