当前位置: 移动技术网 > IT编程>移动开发>Android > Android运用onTouchEvent自定义滑动布局

Android运用onTouchEvent自定义滑动布局

2019年07月24日  | 移动技术网IT编程  | 我要评论

齐敬轩,dnf净化女神殿,如意算盘

写在自定义之前

我们也许会遇到,自定义控件的触屏事件处理,先来了解一下view类中的,ontouch事件和ontouchevent事件。

1、boolean ontouch(view v, motionvent event)
触摸事件发送到视图时调用(v:视图,event:触摸事件)
返回true:事件被完全消耗(即,从down事件开始,触发move,up所有的事件)
返回fasle:事件未被完全消耗(即,只会消耗掉down事件)

2、boolean ontouchevent(motionevent event)
触摸屏幕时调用
返回值,同上

须知

1、ontouch优先级比ontouchevent高
2、如果button设置了ontouchlistener监听,ontouch方法返回了true,就不会调用这个button的click事件

运用ontouchevent写一个能滑动的布局

需求:

1.刚进入界面外层布局,自动下滑一段距离,露出内层布局。
2.外层布局可以上下滑动,并且带有透明度渐变效果,改变内边距效果。

需求分析:

1.显然,外层布局要默认覆盖内层布局了,这个容易。自动下滑,要用到动画,objectanimator
2.外层布局要实现上下滑动,那么需要自定义,对ontouchevent重写(核心逻辑)
也许描述的有一些模糊,看一下效果图:

效果图:

下面是源码,链接地址

/** 
 * author:biligle. 
 * 自定义布局 
 */ 
 
public class myviewgroup extends viewgroup { 
 
 private myviewgrouplistener listener;//接口,监听滑动事件 
 private int vertical = 0;//布局距离顶端距离(默认0) 
 
 public myviewgroup(context context) { 
  super(context); 
 } 
 
 public myviewgroup(context context, attributeset attrs) { 
  super(context, attrs); 
 } 
 
 public myviewgroup(context context, attributeset attrs, int defstyleattr) { 
  super(context, attrs, defstyleattr); 
 } 
 
 @requiresapi(api = build.version_codes.lollipop) 
 public myviewgroup(context context, attributeset attrs, int defstyleattr, int defstyleres) { 
  super(context, attrs, defstyleattr, defstyleres); 
 } 
 
 
 private int downy = 0;//按下时的点 
 private int slide = 0;//最终移动距离 
 @override 
 public boolean ontouchevent(motionevent event) { 
  switch (event.getaction()){ 
   case motionevent.action_down: 
    downy = (int) event.gety(); 
    break; 
   case motionevent.action_move: 
    slide = downy - (int)event.gety(); 
    if(slide < 0){//下滑 
     vertical = listener.margintop(math.abs(slide)); 
    }else if(slide > 0){//上滑 
     vertical = listener.margintop(-slide); 
    } 
    break; 
   case motionevent.action_up: 
    if(vertical < 300){ 
     //布局距离屏幕顶部小于300,就让布局充满整个屏幕 
     vertical = listener.margintop(0); 
    } 
    break; 
  } 
  return true; 
 } 
 
 /** 
  * 测量子view 
  * @param widthmeasurespec 
  * @param heightmeasurespec 
  */ 
 @override 
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { 
  super.onmeasure(widthmeasurespec, heightmeasurespec); 
  for (int i = 0; i < getchildcount(); i++) { 
   view child = getchildat(i); 
   //系统测量 
   measurechild(child, widthmeasurespec, heightmeasurespec); 
  } 
 } 
 
 /** 
  * 安排子view的位置 
  * @param changed 
  * @param l 左边距 
  * @param t 上边距 
  * @param r 右边距 
  * @param b 下边距 
  */ 
 @override 
 protected void onlayout(boolean changed, int l, int t, int r, int b) { 
  int left = 0, top = 0, right = 0, bottom = 0; 
  for (int i = 0; i < getchildcount(); i++) { 
   view child = getchildat(i); 
   right = left + child.getmeasuredwidth(); 
   bottom = top + child.getmeasuredheight(); 
   child.layout(left, top, right, bottom); 
  } 
 } 
 
 public void setlistener(myviewgrouplistener listener){ 
  this.listener = listener; 
 } 
 
 interface myviewgrouplistener { 
  /** 
   * 设置topmargin,上下滑动时触发 
   * @param slide 滑动距离 
   * @return 当前上边距 
   */ 
  int margintop(int slide); 
 } 
}

public class mainactivity extends appcompatactivity implements myviewgroup.myviewgrouplistener{ 
 
 /** 自定义布局(外层布局)*/ 
 private myviewgroup myviewgroup; 
 /** 两个圆形图(在外层布局)*/ 
 private imageview iv1,iv2/*,cloud*/; 
 /** 包裹圆形图的布局*/ 
 private relativelayout relativelayout; 
 /** 外层布局参数类(这里用到了params.topmargin:上边距)*/ 
 private viewgroup.marginlayoutparams params; 
 /** 透明值(改变两个圆图的透明值)*/ 
 private float f; 
 /** 左右内边距(改变relativelayout内边距)*/ 
 private int p; 
 
 @override 
 protected void oncreate(bundle savedinstancestate) { 
  super.oncreate(savedinstancestate); 
  setcontentview(r.layout.activity_main); 
  myviewgroup = (myviewgroup) findviewbyid(r.id.my); 
  myviewgroup.setlistener(this); 
  iv1 = (imageview) findviewbyid(r.id.iv1); 
  iv2 = (imageview) findviewbyid(r.id.iv2); 
  relativelayout = (relativelayout) findviewbyid(r.id.relative); 
  params = (viewgroup.marginlayoutparams) myviewgroup.getlayoutparams(); 
  //初始化动画(自动下滑一段儿距离),我这里写死了900 
  objectanimator animator = objectanimator.offloat(myviewgroup,"translationy", 900); 
  animator.setduration(2000); 
  animator.addupdatelistener(new valueanimator.animatorupdatelistener() { 
   @override 
   public void onanimationupdate(valueanimator animation) { 
    float y = (float)animation.getanimatedvalue(); 
    f = y/800; 
    p = (int) y/3; 
    alpha(f); 
    padding(p); 
   } 
  }); 
  animator.start(); 
//  cloud = (imageview) findviewbyid(r.id.cloud); 
 } 
 
 
 /** 
  * 设置上边距 
  * @param slide 滑动距离 
  * @return 返回下滑布局,距离屏幕左上角的垂直距离 
  */ 
 @override 
 public int margintop(int slide) { 
  params.topmargin += slide; 
  myviewgroup.setlayoutparams(params); 
  int vertical = (900 + params.topmargin); 
  if(slide == 0){ 
   //为了隐藏两张圆图,所以把relativelayout的高度一并减除。 
   params.topmargin -= (vertical+relativelayout.getheight()); 
   myviewgroup.setlayoutparams(params); 
  } 
  float alpha = f + (float) params.topmargin/800;//自定义一个算法 
  alpha(alpha); 
  int padding = p + params.topmargin/3;//自定义一个算法 
  padding(padding); 
  return vertical; 
 } 
 
 /** 
  * 设置透明度 
  * @param alpha 透明值 
  */ 
 public void alpha(float alpha) { 
  iv1.setalpha(alpha); 
  iv2.setalpha(alpha); 
 } 
 
 /** 
  * 设置左右边距 
  * @param padding 边距值 
  */ 
 public void padding(int padding) { 
  relativelayout.setpadding(padding, 0, padding, 0); 
 } 
<?xml version="1.0" encoding="utf-8"?> 
<relativelayout 
 xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:app="http://schemas.android.com/apk/res-auto" 
 xmlns:tools="http://schemas.android.com/tools" 
 android:id="@+id/activity_main" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 tools:context="com.wgl.viewgroup1.mainactivity"> 
 <imageview 
  android:id="@+id/iv" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:src="@mipmap/pic" 
  android:scaletype="fitxy"/> 
  <!--<imageview--> 
   <!--android:id="@+id/cloud"--> 
   <!--android:layout_width="wrap_content"--> 
   <!--android:layout_height="wrap_content"--> 
   <!--android:layout_centerhorizontal="true"--> 
   <!--android:alpha="0.8"--> 
   <!--android:src="@mipmap/cloud3"--> 
   <!--android:clickable="true"/>--> 
 
 <com.wgl.viewgroup1.myviewgroup 
  android:id="@+id/my" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:alpha="0.8" 
  android:layout_alignparenttop="true"> 
  <linearlayout 
   android:layout_width="match_parent" 
   android:layout_height="match_parent" 
   android:orientation="vertical"> 
   <relativelayout 
    android:id="@+id/relative" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 
    <com.wgl.viewgroup1.circleimageview 
     android:id="@+id/iv1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@mipmap/iv1" 
     app:civ_border_width="2dp" 
     app:civ_border_color="@color/coloraccent" 
     android:layout_alignparentleft="true"/> 
 
    <com.wgl.viewgroup1.circleimageview 
     android:id="@+id/iv2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:src="@mipmap/iv2" 
     app:civ_border_width="2dp" 
     app:civ_border_color="@color/coloraccent" 
     android:layout_alignparentright="true"/> 
   </relativelayout> 
   <linearlayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:alpha="0.8" 
    android:background="@color/colorprimary"> 
 
   </linearlayout> 
  </linearlayout> 
 
 </com.wgl.viewgroup1.myviewgroup> 
</relativelayout> 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网