android 滚动栏下拉反弹的效果(相似微信朋友圈)
微信朋友圈上面的图片封面,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 滚动栏下拉反弹的效果(相似微信朋友圈)的更多相关文章
- Android实现系统下拉栏的消息提示——Notification
Android实现系统下拉栏的消息提示--Notification 系统默认样式 默认通知(通用) 效果图 按钮 <Button android:layout_width="match ...
- Android 第三方开源下拉框:NiceSpinner
Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框Spinner所提供的设计样式,而改用自定 ...
- Android之SwipeRefreshLayout下拉刷新组件
SwipeRefreshLayout概述 SwipeRefrshLayout是Google官方更新的一个Widget,可以实现下拉刷新的效果.该控件集成自ViewGroup在support-v4兼容包 ...
- Android:有关下拉菜单导航的学习(供自己参考)
Android:有关==下拉菜单导航==的学习 因为先前的学习都没想着记录自己的学习历程,所以该博客才那么迟才开始写. 内容: ==下拉菜单导航== 学习网站:android Spinner控件详解 ...
- android 开发-spinner下拉框控件的实现
Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...
- Android第三方开源下拉框:NiceSpinner
Android第三方开源下拉框:NiceSpinner Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Andro ...
- UI中经常出现的下拉框下拉自动筛选效果的实现
小需求是当你在第一个下拉框选择了国家时,会自动更新第二个省份的下拉框,效果如下 两个下拉选择Html如下: <select id="country_select"> & ...
- 美团、点评、猫眼App下拉加载效果的源码分享
今天我准备拿大众点评.美团.猫眼电影三款App的实例来分享一下APICloud下拉加载这个模块的效果. 美团App下拉加载效果 以美团中的下拉酷似动画的萌萌着小人儿效果作为参考,来实现的一个加载模 ...
- 谷歌下解决Pop遮罩层无法遮挡滚动栏下问题
今天用pop的弹出窗体里,出现一个问题,当网页出现滚动栏里,不能遮挡住,解决Pop遮罩层无法遮挡滚动栏下问题. 可通过下载获取改动后的代码----->进入下载
随机推荐
- 文字记录而已!!人民币直充/兑换PayPal美金
人民币直充/兑换PayPal美金 用PAYPAL国际使用外国货币,没有信用卡是不能冲值的,到淘宝买吧,被骗的几率大一些,弄来弄去,PAYPAL被冻结. 今天朋友介绍使用 中美互动网 让它给自己的PAY ...
- Android时间戳与字符串相互转换
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public cl ...
- ASP.net 环境搭建
https://www.cnblogs.com/leizhanjun/p/6081928.html
- 4. Vue-Resource / axios 异步插件
安装 cnmp i vue-resource --save (--save 安装到dependencies下) 引用 <script src="node_modules/vue-res ...
- 00089_字节输出流OutputStream
1.字节输出流OutputStream (1)OutputStream此抽象类,是表示输出字节流的所有类的超类.操作的数据都是字节,定义了输出字节流的基本共性功能方法: (2)输出流中定义都是写wri ...
- 【hihocoder 1564】同步H公司的终端
[链接]http://hihocoder.com/problemset/problem/1564 [题意] 在这里写题意 [题解] 如下图 (上图中节点旁边的红色数字为它的权值) 从叶子节点开始考虑. ...
- 并发,three
引言 很久没有跟大家再聊聊并发了,今天LZ闲来无事,跟大家再聊聊并发.由于时间过去的有点久,因此LZ就不按照常理出牌了,只是把自己的理解记录在此,如果各位猿友觉得有所收获,就点个推荐或者留言激励下LZ ...
- 【例题 6-11 UVA-297】Quadtrees
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 发现根本不用存节点信息. 遇到了叶子节点且为黑色,就直接覆盖矩阵就好(因为是并集); [代码] #include <bits/ ...
- Hypervisor scheduler
Techniques for configuring a hypervisor scheduler to make use of cache topology of processors and ph ...
- ThreadLocal深入理解与内存泄露分析
ThreadLocal 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本.所以每个线程都能够独立地改变自己的副本.而不会影响其他线程所相应的副本. ...