2.ViewGroup实现上下切换view

(已经更新了,请看另外一篇)

一.前提

好久没玩安卓了,把上下切换view的源码跟大家分享,方法为原创,没有参考别人的作品,

可能不是最优的,但效果是一样的,原理跟SlideMenu是相似的,核心代码就是viewgroup

的重构,所以只贴出该核心的代码,及讲解,因为本人已返回去开发arm了,以前觉得简单

没有过多的解析,现在补充上...(核心代码,木有经过润泽,几十行简洁)

二.源码

 

//往这个viewgroup里add两个view就可以了

public class ViewMore extends ViewGroup {
       private Scroller scroller;
       private static float lX,lY,bX,bY,lYY;
       private static boolean Menushowflag,Menuflag=true;
       public ViewMore(Context context) {super(context);scroller = new Scroller(context);}

       public ViewMore(Context context, AttributeSet attrs) {super(context, attrs);}

       public ViewMore(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}
//1.子view的布局
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
       int viewCount = getChildCount();        //得到viewgroup的子view,该viewgroup有上下两个view
       for(int count=0;count<viewCount;count++){
       View child = getChildAt(count);
       int height = child.getMeasuredHeight();
       int width = child.getMeasuredWidth();
       child.layout(0, 0, width, height);
       }
}
public int displaynView(boolean flag){       //显示不同的view
    return flag? 1:0;
}
//2.布局时提供参数,经测试不重写无法正常给子类view布局()
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      int width = MeasureSpec.getSize(widthMeasureSpec);
      int height = MeasureSpec.getSize(heightMeasureSpec);
      setMeasuredDimension(width, height);
      Log.i("MainActivity", "--->>getChildCount:"+getChildCount());
      for (int i = 0; i < getChildCount(); i++) {
             getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
      }
}

//3.重写computeScroll(),处理scroller.startScroll扔过来的数据,(这个才是滑动view的关键方法)
@Override
public void computeScroll() {
  if(scroller.computeScrollOffset()){    //判断上次是否划完了(因为我们是把滑动view的动作分解成n个事件来处理的)
      getChildAt(displaynView(true)).layout(0, scroller.getCurrY(), getWidth(), scroller.getCurrY()+getHeight());
            getChildAt(displaynView(false)).layout(0, -getHeight()+scroller.getCurrY(), getWidth(), scroller.getCurrY());
      Log.i("Mainactivity", "CountL_"+scroller.getCurrY()+"---"+(scroller.getCurrY()+getHeight()));
            postInvalidate();
  }
  super.computeScroll();
}
public void ShowViewSroll(float currN,float currY){

//4.给computeScroll提供数据,这段代码区要简洁,不然会卡屏,因为我们要使用这个方法n次
  scroller.startScroll(0,(int)currN,0,(int)currY-(int)currN);
  invalidate();
  Menushowflag = true;
} 
public void CloseViewSroll(float currN){//关闭menu
  scroller.startScroll(0,(int)currN,0,-(int)currN);
  invalidate();
  Menushowflag = false;
  Menuflag = true;//第一页
}
public void DissViewSroll(float currN){//关闭menu
  scroller.startScroll(0,(int)currN,0,getHeight()-(int)currN);
  invalidate();
  Menushowflag = false;
  Menuflag = false;//第二页
}  

//5.核心的方法,用dispatchTouchEvent捕捉触屏事件,该方法原本是用来分发触屏事件的,经测试后用我的方法

(实现上下view动态切换时,只有该方法才能捕捉到正确的x,y坐标,不知道问题出在哪里,当初觉得可以用此方

法,所以就没去调试问题出在哪里了)
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
        Log.i("Mainactivity", "dispatchTouchEvent"+event.getY());
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        lYY = event.getY();//捕捉到触屏动作,开始记录y坐标(因为我们要实现上下滑动,所以只捕捉y),初始化时使用
  break;  
  case MotionEvent.ACTION_MOVE:
   if(lYY<=40&&Menuflag){         // 判断开始触屏的位置是不是顶部且尚未滑动上下view
           bY = event.getY();           // (before y简称by )得到真正可以滑动view时的启示y
           ShowViewSroll(bY,lY);    // 开始滑动一小小段(量变到质变),by等变量要为静态的,因为我们要反复使用这些捕捉到的数据
           lY = event.getY();            //记录n毫秒后的y坐标,实现ly-by的差距,然后才能交给scroller的startScroll去滑动
   }else if(((int)getHeight()-40)<lYY&&!Menuflag){
           bY = event.getY();           //处理当上面的view滑下来后的把view滑上去事件
          ShowViewSroll(bY,lY);
          lY = event.getY(); 
   }
   break;
  case MotionEvent.ACTION_UP:
          bY = 0;
          if(Menushowflag&&(event.getY()<getHeight()/2)){        //当手指提起时判断是要划回去还是划回来
          CloseViewSroll(event.getY());
   }else if(Menushowflag&&event.getY()>=getHeight()/2){       
          DissViewSroll(event.getY());
   }
  break;     
  default:
   break;
  }
  return super.dispatchTouchEvent(event);           //把触屏事件分发回给各个组件
}

}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# -*- coding: UTF-8 -*- from lib2to3.pgen2 import driver from appium import webdriver from appium.webdriver.common.appiumby import AppiumBy el1 = driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value="通讯录") el1.click() el2 = driver.find_element(by=AppiumBy.XPATH, value="/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[1]/android.widget.FrameLayout/android.widget.ListView/android.widget.FrameLayout[3]/android.widget.RelativeLayout") el2.click() el3 = driver.find_element(by=AppiumBy.XPATH, value="/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.view.ViewGroup/android.view.ViewGroup/androidx.recyclerview.widget.RecyclerView/android.view.ViewGroup[1]/android.widget.TextView") el3.click() el4 = driver.find_element(by=AppiumBy.XPATH, value="/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.view.ViewGroup/android.view.ViewGroup/androidx.recyclerview.widget.RecyclerView/android.view.ViewGroup[8]") el4.click() el5 = driver.find_element(by=AppiumBy.XPATH, value="/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.view.ViewGroup/android.view.ViewGroup/androidx.recyclerview.widget.RecyclerView/android.view.ViewGroup[11]") el5.click()
最新发布
06-08

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值