首页 > 系统 > Android > 正文

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

2020-04-11 10:53:37
字体:
来源:转载
供稿:网友

微信朋友圈上面的图片封面,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软件编程有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表