真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android中怎么自定義一個底部上拉控件

Android中怎么自定義一個底部上拉控件,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作、廣靈網(wǎng)絡(luò)推廣、成都小程序開發(fā)、廣靈網(wǎng)絡(luò)營銷、廣靈企業(yè)策劃、廣靈品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供廣靈建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

1. 在Project的build.gradle文件中添加:

allprojects {
 repositories {
  ...
  maven { url 'https://jitpack.io' }
 }
}

2.在Module的build.gradle文件中添加:

dependencies {
   compile 'com.github.qingmei2:SlideBottomLayout-Android:1.2.3'
}

3.Add view in your layout:

需要注意的是:為了簡單實(shí)現(xiàn),筆者偷了個懶,設(shè)定為該布局下只能有一個直接的子View(類似ScrollView)

因此如果您添加需要一個布局,請?jiān)谕饷媲短滓粋€ViewGroup:


    
    
    
      
      
      
    
  

實(shí)現(xiàn)步驟

具體代碼如下,其中上述需求的設(shè)置方式都已經(jīng)在代碼中聲明:

先看下屬性聲明:



  
    
  
public class SlideBottomLayout extends LinearLayout {
  public void setShortSlideListener(ShortSlideListener listener) {
    this.shortSlideListener = listener;
  }
  private ShortSlideListener shortSlideListener;
  /**
   * The {@link MotionEvent#ACTION_DOWN} gesture location.
   */
  private int downY;
  /**
   * The {@link MotionEvent#ACTION_MOVE} gesture location.
   */
  private int moveY;
  /**
   * the value of moved distance by the gesture. When the value was modified and not exceed
   * the {@link #movedMaxDis}, then make this ViewGroup move.
   */
  private int movedDis;
  /**
   * The max distance that the {@link SlideBottomLayout} can scroll to, it used to compare with the
   * {@link #downY}, determine whether it can slide by the gesture.
   */
  private int movedMaxDis;
  /**
   * ChildView of the {@link SlideBottomLayout}, you can set a Layout such as the {@link LinearLayout}、
   * {@link android.widget.RelativeLayout} ect.
   * We set the rules that {@link SlideBottomLayout} just can have one child-view, or else get a
   * {@link RuntimeException} at {@link #onFinishInflate()}
   */
  private View childView;
  /**
   * The control {@link SlideBottomLayout} automatically switches the threshold of the state. if
   * this ViewGroup moved distance more than {@link #movedMaxDis} * it, switch the state of
   * {@link #arriveTop} right now.
   * 

   * See the {@link #touchActionUp(float)}.    */   private float hideWeight = 0.25f;   //3.注意,這個接口用來設(shè)置「需要自定義自動到達(dá)頂部/隱藏的閾值」   public void setHideWeight(float hideWeight) {     if (hideWeight <= 0 || hideWeight > 1)       throw new IllegalArgumentException("hideWeight should belong (0f,1f]");     this.hideWeight = hideWeight;   }   private Scroller mScroller;   /**    * It means the {@link #childView} is arriving the top of parent or else.    */   private boolean arriveTop = false;   /**    * the {@link #childView} Initially visible height    */   private float visibilityHeight;   //1.初始化Handle顯示高度,建議您在xml中設(shè)置對應(yīng)屬性來實(shí)現(xiàn)該效果   public void setVisibilityHeight(float visibilityHeight) {     this.visibilityHeight = visibilityHeight;   }   public SlideBottomLayout(@NonNull Context context) {     super(context);   }   public SlideBottomLayout(@NonNull Context context, @Nullable AttributeSet attrs) {     super(context, attrs);     initAttrs(context, attrs);   }   public SlideBottomLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {     super(context, attrs, defStyleAttr);     initAttrs(context, attrs);   }   /**    * Get the config from {@link R.styleable}, then init other configrations{@link #initConfig(Context)}.    *    * @param context the {@link Context}    * @param attrs  the configs in layout attrs.    */   private void initAttrs(Context context, AttributeSet attrs) {     final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlideBottomLayout);     visibilityHeight = ta.getDimension(R.styleable.SlideBottomLayout_handler_height, 0);     ta.recycle();     initConfig(context);   }   private void initConfig(Context context) {     if (mScroller == null)       mScroller = new Scroller(context);     this.setBackgroundColor(Color.TRANSPARENT);   }   /**    * It start a judgement for ensure the child-view be unique in this method,then assgin it    * to {{@link #childView}.    * this method will be called before the {@link #onMeasure(int, int)}    */   @Override   protected void onFinishInflate() {     super.onFinishInflate();     if (getChildCount() == 0 || getChildAt(0) == null) {       throw new RuntimeException("there have no child-View in the SlideBottomLayout!");     }     if (getChildCount() > 1) {       throw new RuntimeException("there just alow one child-View in the SlideBottomLayout!");     }     childView = getChildAt(0);   }   @Override   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {     super.onMeasure(widthMeasureSpec, heightMeasureSpec);     movedMaxDis = (int) (childView.getMeasuredHeight() - visibilityHeight);   }   @Override   protected void onLayout(boolean changed, int l, int t, int r, int b) {     super.onLayout(changed, l, t, r, b);     childView.layout(0, movedMaxDis, childView.getMeasuredWidth(), childView.getMeasuredHeight() + movedMaxDis);   }   @Override   public boolean onTouchEvent(MotionEvent event) {     final float dy = event.getY();     switch (event.getAction()) {       case MotionEvent.ACTION_DOWN:         if (touchActionDown(dy))           return true;         break;       case MotionEvent.ACTION_MOVE:         if (touchActionMove(dy))           return true;         break;       case MotionEvent.ACTION_UP:         if (touchActionUp(dy))           return true;         break;     }     return super.onTouchEvent(event);   }   @Override   public void computeScroll() {     super.computeScroll();     if (mScroller == null)       mScroller = new Scroller(getContext());     if (mScroller.computeScrollOffset()) {       scrollTo(0, mScroller.getCurrY());       postInvalidate();     }   }   /**    * When the touch event is {@link MotionEvent#ACTION_UP},    * then judge the state of view group and control the {@link Scroller} to scroll.    * 

   * In this ViewGroup, we set the rules that is if this scroll gesture's move distance    * more than {@link #movedMaxDis} * {@link #hideWeight}(default hideWeight value is 1/4 heights    * of this ViewGroup), then call {@link #hide()} or {@link #show()} right now. which method will    * be call depends on {@link #arriveTop}.    * 

 movedMaxDis * hideWeight) {       switchVisible();     } else {       if (shortSlideListener != null) {         shortSlideListener.onShortSlide(eventY);       } else {         hide();       }     }     return true;   }   /**    * When the touch event is {@link MotionEvent#ACTION_MOVE},    * then judge the state of view group and control the {@link Scroller} to scroll.    * 

   * In this ViewGroup, we set the rules that is if this scroll gesture's move distance    * more than {@link #movedMaxDis} * {@link #hideWeight}(default hideWeight value is 1/4 heights of this ViewGroup),    * then call {@link #hide()} or {@link #show()} right now.    * 

   *    * @param eventY The location of trigger    * @return Be used to determine consume this event or else.    */   public boolean touchActionMove(float eventY) {     moveY = (int) eventY;     //the dy is sum of the move distance, the value > 0 means scroll up, the value < 0 means scroll down.     final int dy = downY - moveY;     if (dy > 0) {        //scroll up       movedDis += dy;       if (movedDis > movedMaxDis)         movedDis = movedMaxDis;       if (movedDis < movedMaxDis) {         scrollBy(0, dy);         downY = moveY;         return true;       }     } else {        //scroll down       movedDis += dy;       if (movedDis < 0) movedDis = 0;       if (movedDis > 0) {         scrollBy(0, dy);       }       downY = moveY;       return true;     }     return false;   }   /**    * When the touch event is {@link MotionEvent#ACTION_DOWN},    * Record the location of this action.    *    * @param eventY The location of trigger    * @return Be used to determine consume this event or else.    */   public boolean touchActionDown(float eventY) {     downY = (int) eventY;     //Whether custom this gesture.     if (!arriveTop && downY < movedMaxDis) {       return false;     } else       return true;   }   /**    * the extand method for showing {@link SlideBottomLayout}    */   public void show() {     scroll2TopImmediate();   }   /**    * the extand method for hiding {@link SlideBottomLayout}    */   public void hide() {     scroll2BottomImmediate();   }   /**    * @return The ViewGroup is arrive top or else.    */   public boolean switchVisible() {     if (arriveTop())       hide();     else       show();     return arriveTop();   }   public boolean arriveTop() {     return this.arriveTop;   }   public void scroll2TopImmediate() {     mScroller.startScroll(0, getScrollY(), 0, (movedMaxDis - getScrollY()));     invalidate();     movedDis = movedMaxDis;     arriveTop = true;   }   public void scroll2BottomImmediate() {     mScroller.startScroll(0, getScrollY(), 0, -getScrollY());     postInvalidate();     movedDis = 0;     arriveTop = false;   } }

看完上述內(nèi)容,你們掌握Android中怎么自定義一個底部上拉控件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!


網(wǎng)站欄目:Android中怎么自定義一個底部上拉控件
當(dāng)前網(wǎng)址:http://weahome.cn/article/ihoddc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部