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软件编程有所帮助。

(0)

相关推荐

  • android输入框与文本框加滚动条scrollview示例

    我们都知道EditText与TextView是Android的文本输入框和文本显示框,但是基于手机屏幕的大小因素,如果在需要输入较多文字或者显示较多内容的时候,手机屏幕是远远不够的,因此让文本框具有滚动条的功能是手机上必备的,要加上滚动条,其实很简单,只需要在文本输入框或者文本显示框上面加上滚动条控件即可,该控件名字为ScrollView,以下我们对比下(以TextView举例). 复制代码 代码如下: //A.未加滚动效果 <TextView android:layout_width="

  • Android开发:TextView加入滚动条示例

    利用scrollview来实现,效果会好很多 复制代码 代码如下: <ScrollView android:id="@+id/scrollView1" android:layout_width="match_parent" android:layout_height="150dp" android:fadingEdge="vertical" android:scrollbars="vertical"

  • android开发教程之文本框加滚动条scrollview

    我们都知道EditText与TextView是Android的文本输入框和文本显示框,但是基于手机屏幕的大小因素,如果在需要输入较多文字或者显示较多内容的时候,手机屏幕是远远不够的,因此让文本框具有滚动条的功能是手机上必备的,下面介绍下如何加上滚动条.要加上滚动条,其实很简单,只需要在文本输入框或者文本显示框上面加上滚动条控件即可,该控件名字为ScrollView,以下我们对比下(以TextView举例). 复制代码 代码如下: //A.未加滚动效果 <TextView android:layo

  • Android实现Activity水平和垂直滚动条的方法

    本文实例讲述了Android实现Activity水平和垂直滚动条的方法.分享给大家供大家参考,具体如下: <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="

  • Android ListView 滚动条的设置详解及实例代码

    Android ListView 滚动条的设置详解 1.滚动条的属性 android:scrollbarAlwaysDrawHorizontalTrack 设置是否始终显示水平滚动条.这里用ScrollView.ListView测试均没有效果. android:scrollbarAlwaysDrawVerticalTrack 设置是否始终显示垂直滚动条.这里用ScrollView.ListView测试均没有效果. android:scrollbarDefaultDelayBeforeFade 设

  • Android ListView隐藏右侧滚动条功能

    关于ListView的滚动条几种情形: 1.默认情况:活动(滚动)时显示,不活动时隐藏. 2.活动和不活动时都显示. 3.活动和不活动时都隐藏. 上述集中情况,均有ListView的以下设置属性方法控制 1.setVerticalScrollBarEnabled(boolean b); 设置true时: 存在滚动条 设置false时: 隐藏滚动条 2.setScrollbarFadingEnabled(boolean b); 设置true时: 活动时显示滚动条,不活动时隐藏滚动条 设置false

  • Android滚动条广告实现代码示例

    前言 几乎每个上线的App上面都会有个滚动条广告,滚动条广告主要以文字标题的形式存在,什么点开文章你就能赚一百万啊.看完转走这个你就能平安一生啊这样的标题,都是以标题广告的形式吸引人的,当然开个小玩笑啦,哈哈,毕竟是要赚钱的嘛,接上几个广告是正常滴~~ 之前在项目中要求要做一个滚动条轮播的展示,就是在滚动条上放几条广告进行轮播.一开始知识觉得直接用TextSwitcher或者ViewSwitcher就可以了.虽然这样也能满足需求,但是项目里有好几个地方都用到了滚动条广告.如果每个地方都写一套同样

  • Android仿微信朋友圈实现滚动条下拉反弹效果

    微信朋友圈上面的图片封面,QQ空间说说上面的图片封面都有下拉反弹的效果,这些都是使用滚动条实现的.下拉,当松开时候,反弹至原来的位置.下拉时候能看到背景图片.那么这里简单介绍一下这种效果的实现. 1.效果图 这部手机显示的分辨率有限,很老的手机调试. 2.具有反弹效果BounceScrollView package com.org.scroll; import android.content.Context; import android.graphics.Rect; import androi

  • Android 仿微信朋友圈点赞和评论弹出框功能

    贡献/下载源码:https://github.com/mmlovesyy/PopupWindowDemo 本文简单模仿微信朋友圈的点赞和评论弹出框,布局等细节请忽略,着重实现弹出框.发评论,及弹出位置的控制. 1. 微信弹出框 微信朋友圈的点赞和评论功能,有2个组成部分: 点击左下角的"更多"按钮,弹出对话框: 点击评论,弹出输入框,添加评论并在页面中实时显示: 微信朋友圈点赞和评论功能 2. 实际效果 本文将建一个 ListView,在其 Item 中简单模仿微信的布局,然后着重实现

  • Android仿微信朋友圈全文、收起功能的实例代码

    前言 一般在社交APP中都有类似朋友圈的功能,其中发表的动态内容很长的时候不可能让它全部显示.这里就需要做一个仿微信朋友圈全文.收起功能来解决该问题.在网上看到一个例子-->http://www.jb51.net/article/105251.htm,写的很不错,但是有个bug,他这个Demo只有在条目固定的时候才正常,当增加.删除条目的时候会出现全文.收起显示混乱的问题.原因是他使用了固定的position作为key来保存当前显示的状态.这篇文章在他的基础上进行优化. 效果图 具体代码 (详细

  • Android仿微信朋友圈全文收起功能示例(附源码)

    在众多的社交类软件中,朋友圈是必不可少的,可以与好友.同学等分享自己的日常和有意思的事情,在开发社交类App时,朋友圈发表的内容你不可能让他全部显示,全部显示的话用户体验度会非常不好,这时就要用到全文.收缩的功能,朋友如果想要看你发的动态,只要点一下全文就可以查看所有的全部的内容了,如果不想看,也没有必要把这一篇文章全部都滑到底部,才能看下一条内容. 下边将源码贴出来供大家参考:(代码不是最简便的,但是功能是可以的) 首先写一个布局,这个布局是每个子项的布局 item_text_list.xml

  • Android仿微信朋友圈点赞和评论功能

    最近在做朋友圈的项目,所以写一个Android仿朋友圈点赞和评论功能Demo,代码就是简单实现了一下功能,没有做优化,凑合看 图文排列是用的RecyclerView实现的,弹窗效果是用的自定义的PopupWindow,点赞应该是在本地请求数据库,设置一个flag,获取当前用户的id后,带着id向服务器post一个flag,评论就比较简单了,也是获取当前朋友id(或者昵称),带着内容,向服务器post 贴代码: package com.example.lenovo.dianzandemo; imp

  • Android仿微信朋友圈添加图片的实例代码

    老习惯,先上图,着急用的朋友,直接带走Demo,先拿来用吧,毕竟老板催的紧,先把工作完成了,再看也来得及,是吧! 在项目中这种添加图片上传的效果应该是非常常见的,后面有个添加的按钮应该让有些童鞋不知道咋办了吧,其实没那么复杂,通过GridView就可以实现了 先说明一下,这里主要是讲添加图片的效果,至于图片选择器用的是第三方库photopicker,6.0权限用的是第三方库EasyPermission 1.首先这是用GridView实现的 <?xml version="1.0"

  • android实现微信朋友圈发布动态功能

    本文实例为大家分享了android仿微信朋友圈发布动态功能的具体代码,供大家参考,具体内容如下 效果图: 本文概述 用到的开源库:仿照微信的图片选择器,Luban压缩图片,glide 上面红圈部分,当用户选中图片时,当=9张时,那个加号图片就会消失! 本文主要仿照微信的发布动态功能,主要时针对微信发布动态时,选中图片后的变化状态! 整体布局 这可以看到,控制图片状态的地方就是一个recyclerview 思路 利用recyclerview的多行视图来实现! 微信上的效果是,先选中图片后才会进入这

  • Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. PhotoPicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间左右滑动互相切换的库,同时支持图片删除的库,效果类似微信. (1) 添加PhotoPicker的架包 (2) 使用 选择图片:安卓6.0以后需要在代码中添加读写sd卡和相机的权限 当然清单文件中也需要添加的 PhotoPicker.builder() .setPhotoCount(maxPhoto)

  • Android 高仿微信朋友圈动态支持双击手势放大并滑动查看图片效果

    最近参与了开发一款旅行APP,其中包含实时聊天和动态评论功能,终于耗时几个月几个伙伴完成了,今天就小结一下至于实时聊天功能如果用户不多的情况可以scoket实现,如果用户万级就可以采用开源的smack + opnefile实现,也可以用mina开源+XMMP,至于怎么搭建和实现,估计目前github上一搜一大把,至于即时通讯怕误人子弟,暂且不做介绍,现就把实现的一个微信朋友圈的小功能介绍一下. 先上效果图: 一拿到主流的UI需求,大致分析下,需要我ListView嵌套Gridview,而grid

  • Android自定义TextView仿微信朋友圈文字展开全文功能

    Android自定义TextView仿微信朋友圈文字信息,展开全文功能 代码及注释如下: 首先写一个xml文件 showmore.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical

随机推荐