当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义viewgroup 使用adapter适配数据(6)

Android自定义viewgroup 使用adapter适配数据(6)

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

在自定义viewgroup(5):的基础上,添加使用adapter来适配数据,这样更加的方便,这里只是使用adapter适配数据,不能更新。

package com.example.libingyuan.horizontallistview.scrollviewgroup;

import android.content.context;
import android.util.attributeset;
import android.util.displaymetrics;
import android.util.log;
import android.view.gesturedetector;
import android.view.motionevent;
import android.view.view;
import android.view.viewgroup;
import android.view.windowmanager;
import android.widget.baseadapter;
import android.widget.gridview;
import android.widget.scroller;

/**
 * 自定义viewgroup(横向滚动)
 */
public class scrollviewgroup extends viewgroup {
  //滚动计算辅助类
  private scroller mscroller;
  //屏幕宽度
  private int screenwidth;
  //可以移动的最大距离
  private int mmaxdistance;
  //自定义手势监听类
  private scrolltouchlisener mtouchlisener;
  //手势监听
  private gesturedetector mdetector;

  private baseadapter madapter;

  /**
   * 使用new关键字创建对象的时候调用
   */
  public scrollviewgroup(context context) {
    this(context, null);
  }

  /**
   * 在xml文件中使用的时候调用
   */
  public scrollviewgroup(context context, attributeset attrs) {
    this(context, attrs, 0);
  }

  /**
   * 在xml文件中调用,并且使用了自定义属性的时候调用
   */
  public scrollviewgroup(context context, attributeset attrs, int defstyleattr) {
    super(context, attrs, defstyleattr);
    init(context);
  }

  /**
   * 初始化方法
   * 初始化滚动辅助类scroller以及计算出屏幕宽度
   */
  private void init(context context) {
    //初始化辅助类
    mscroller = new scroller(context);
    //获取屏幕宽度
    windowmanager manager = (windowmanager) context
        .getsystemservice(context.window_service);
    displaymetrics outmetrics = new displaymetrics();
    manager.getdefaultdisplay().getmetrics(outmetrics);
    screenwidth = outmetrics.widthpixels;
    //手势指示器初始化
    mtouchlisener = new scrolltouchlisener();
    mdetector = new gesturedetector(context, mtouchlisener);
  }

  /**
   * 滚动时需要重写的方法,用于控制滚动
   */
  @override
  public void computescroll() {
    //判断滚动时候停止
    if (mscroller.computescrolloffset()) {
      //滚动到指定的位置
      scrollto(mscroller.getcurrx(), mscroller.getcurry());
      //这句话必须写,否则不能实时刷新
      invalidate();
    }
  }

  /**
   * 手指触屏事件监听
   */
  @override
  public boolean ontouchevent(motionevent event) {
    mdetector.ontouchevent(event);
    if (event.getaction() == motionevent.action_up) {
      this.onup(event);
    }
    return true;
  }


  public void setadapter(baseadapter adapter) {
    this.madapter = adapter;
    requestlayout();
  }

  /*
   *测量方法,测量父布局的宽度和高度
   */
  @override
  protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
    removeallviews();
    for (int i = 0; i < madapter.getcount(); i++) {
      view child = madapter.getview(i, null, null);
      addview(child);
    }
    //重新设置宽高
    this.setmeasureddimension(measurewidth(widthmeasurespec, heightmeasurespec), measureheight(widthmeasurespec, heightmeasurespec));
  }

  /**
   * 测量宽度
   */
  private int measurewidth(int widthmeasurespec, int heightmeasurespec) {
    // 宽度
    int sizewidth = measurespec.getsize(widthmeasurespec);
    int modewidth = measurespec.getmode(widthmeasurespec);
    //父控件的宽(wrap_content)
    int width = 0;
    int childcount = getchildcount();

    //重新测量子view的宽度,以及最大高度
    for (int i = 0; i < childcount; i++) {
      view child = getchildat(i);
      measurechild(child, widthmeasurespec, heightmeasurespec);
      // layoutparams lp = child.getlayoutparams();
      /* marginlayoutparams lp = (marginlayoutparams) child.getlayoutparams();
      int childwidth = child.getmeasuredwidth() + lp.leftmargin + lp.rightmargin;
      width += childwidth;*/
      width += child.getmeasuredwidth();
    }
    return modewidth == measurespec.exactly ? sizewidth : width;
  }


  /**
   * 测量高度
   */
  private int measureheight(int widthmeasurespec, int heightmeasurespec) {
    //高度
    int sizeheight = measurespec.getsize(heightmeasurespec);
    int modeheight = measurespec.getmode(heightmeasurespec);
    //父控件的高(wrap_content)
    int height = 0;
    int childcount = getchildcount();

    //重新测量子view的宽度,以及最大高度
    for (int i = 0; i < childcount; i++) {
      view child = getchildat(i);
      measurechild(child, widthmeasurespec, heightmeasurespec);
      /* marginlayoutparams lp = (marginlayoutparams) child.getlayoutparams();
      int childheight = child.getmeasuredheight() + lp.topmargin + lp.bottommargin;
      height += childheight;*/
      height += child.getmeasuredheight();
    }
    height = height / childcount;
    return modeheight == measurespec.exactly ? sizeheight : height;
  }

  /**
   * 给子布局设定位置
   */
  @override
  protected void onlayout(boolean changed, int l, int t, int r, int b) {
    int childleft = 0;//子view左边的间距
    int childwidth;//子view的宽度
    int height = getheight();//屏幕的宽度
    int childcount = getchildcount();//子view的数量
    for (int i = 0; i < childcount; i++) {
      view child = getchildat(i);
     /*  marginlayoutparams lp = (marginlayoutparams) child.getlayoutparams();
      childwidth = child.getmeasuredwidth() + lp.leftmargin + lp.rightmargin;*/
      childwidth = child.getmeasuredwidth();
      child.layout(childleft, 0, childleft + childwidth, height);
      childlayout(child);
      childleft += childwidth;
    }
  }

  /**
   *让子view的子view和子view大小一样
   */
  private void childlayout(view child){
    if (child==null){
      throw new illegalstateexception("scrollviewgroup must has one child");
    }
    if (child instanceof viewgroup){
      if(((viewgroup)child).getchildcount()>0)
        throw new illegalstateexception("view can host only one direct child");
      ((viewgroup) child).getchildat(0).layout(0,0,child.getwidth(),child.getheight());
    }

  }
  @override
  public layoutparams generatelayoutparams(attributeset attrs) {
    return new marginlayoutparams(getcontext(), attrs);
  }

  /*
   *按下事件 action_down
   */
  public boolean ondown(motionevent e) {
    //得到最后一个子view
    view lastchild = getchildat(getchildcount() - 1);
    //获取滑动的最大滑动距离(最后一个child的右边框的坐标减去屏幕的宽度)
    int finalychild = (int) (lastchild.getx() + lastchild.getwidth() - screenwidth);
    mmaxdistance = finalychild;
    //如果停止滚动则取消动画(即手指按下就停止滚动)
    if (!mscroller.isfinished()) {
      mscroller.abortanimation();
    }
    return false;
  }

  /*
  *抬起事件 action_up
  */
  public boolean onup(motionevent e) {
    //如果滑动的距离小于第一个控件的最左边(0)则回弹至(0,0)点
    if (getscrollx() <= 0) {
      scrollto(0, 0);
    }
    //如果滑动的距离大于最大可滑动距离则滑动到最后一个子view
    if (getscrollx() >= mmaxdistance) {
      scrollto(mmaxdistance, 0);
    }
    //刷新界面
    invalidate();
    return false;
  }

  /*
   *action_down 、短按不移动
   */
  public void onshowpress(motionevent e) {
  }

  /*
   *短按action_down、action_up
   */
  public boolean onsingletapup(motionevent e) {
    return false;
  }

  /*
   *action_down 、慢滑动
   */
  public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey) {
    //滚动
    scrollby((int) distancex, 0);
    return false;
  }

  // action_down 、长按不滑动
  public void onlongpress(motionevent e) {
  }

  /*
   *action_down 、快滑动、 action_up
   */
  public boolean onfling(motionevent e1, motionevent e2, float velocityx, float velocityy) {
    mscroller.fling(getscrollx(), 0, (int) -velocityx, 0, 0, mmaxdistance, 0, 0);
    return false;
  }

  /**
   * 自定义手势监听类
   */
  private class scrolltouchlisener implements gesturedetector.ongesturelistener {

    //按下事件
    @override
    public boolean ondown(motionevent e) {
      return scrollviewgroup.this.ondown(e);
    }

    //单击事件
    @override
    public void onshowpress(motionevent e) {
      scrollviewgroup.this.onshowpress(e);
    }

    //手指抬起事件
    @override
    public boolean onsingletapup(motionevent e) {
      return scrollviewgroup.this.onsingletapup(e);
    }

    //滚动事件
    @override
    public boolean onscroll(motionevent e1, motionevent e2, float distancex, float distancey) {
      return scrollviewgroup.this.onscroll(e1, e2, distancex, distancey);
    }

    //长按事件
    @override
    public void onlongpress(motionevent e) {
      scrollviewgroup.this.onlongpress(e);
    }

    //滑动事件
    @override
    public boolean onfling(motionevent e1, motionevent e2, float velocityx, float velocityy) {
      return scrollviewgroup.this.onfling(e1, e2, velocityx, velocityy);
    }
  }

}

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网