广告
返回顶部
首页 > 资讯 > 移动开发 >Android自定义View实现拖动选择按钮
  • 346
分享到

Android自定义View实现拖动选择按钮

view选择按钮Android 2022-06-06 08:06:13 346人浏览 八月长安
摘要

本文为大家分享了Android实现拖动选择按钮的具体代码,供大家参考,具体内容如下 效果图 View代码 第一步:自定义属性 <declare-styleable

本文为大家分享了Android实现拖动选择按钮的具体代码,供大家参考,具体内容如下

效果图

View代码

第一步:自定义属性


 <declare-styleable name="DragView">
  <attr name="icon_drag" fORMat="reference"/>
  <attr name="color_circle" format="color"/>
  <attr name="dot_num" format="integer"/>
 </declare-styleable>

第二步:自定义圆形


public class CircleView extends View {
 
 private final int DEFAULT_COLOR = Color.LTGRAY;
 
 private final float DEFAULT_RADIUS = 32;
 private int mColor;
 private Paint mCirclePaint;
 private float mRadius;
 private float mCenterX;
 private float mCenterY;
 public CircleView(Context context)
 {
  this(context, null);
 }
 public CircleView(Context context, AttributeSet attrs)
 {
  this(context, attrs, 0);
 }
 public CircleView(Context context, AttributeSet attrs, int defStyleAttr)
 {
  super(context, attrs, defStyleAttr);
  TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.DragView);
  mColor = array.getColor(R.styleable.DragView_color_circle,DEFAULT_COLOR);
  mCirclePaint = new Paint();
  mCirclePaint.setColor(mColor);
  mCenterY = mCenterX = mRadius = getMeasuredWidth() == 0?DEFAULT_RADIUS:getMeasuredWidth()/2;
  array.recycle();
 }
 public float getRadius(){
  return mRadius;
 }
 public int getColor()
 {
  return mColor;
 }
 @Override
 protected void onDraw(canvas canvas)
 {
  canvas.drawCircle(mCenterX,mCenterY,mRadius,mCirclePaint);
 }
}

第三步:自定义拖动按钮


public class DragView extends RelativeLayout implements View.OnTouchListener {
 private Drawable mDragIcon;//拖动图标
 private ImageView mDragView;//拖动图标ImageView
 private int mCircleColor;//圆的颜色
 private Context mContext;//上下文
 private int mDotNum;//节点数量
 private int mWidth;//组件的宽度
 private int mHight;//组件的高度
 private int mCircleRadius;//园的半径
 private int mDragWidth;//拖动图标的宽度
 private int mLineWidth,mLineHeight;//中间线的长宽
 private float mStartX;//开始拖动的屏幕坐标
 private float mCurX;//开始拖动的触点坐标
 private float mMinX;//拖动范围的最小值
 private float mMaxX;//拖动范围的最大值
 private OnnodeSelect mOnNodeSelect;//回调接口
 public DragView(Context context) {
  this(context,null);
 }
 public DragView(Context context, AttributeSet attrs) {
  this(context, attrs,0);
 }
 public DragView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.DragView);
  mDragIcon=array.getDrawable(R.styleable.DragView_icon_drag);
  mCircleColor=array.getColor(R.styleable.DragView_color_circle,Color.WHITE);
  mDotNum=array.getInt(R.styleable.DragView_dot_num,2);
  array.recycle();
  mContext=context;
  initView();
 }
 
 public void initView(){
  for (int i=0;i<mDotNum;i++){
   CircleView circleView=new CircleView(mContext);
   circleView.setOnTouchListener(this);
   addView(circleView);
  }
  View view=new View(mContext);
  view.setBackgroundColor(mCircleColor);
  addView(view);
  // TODO: 2016/4/21 top not right
  mDragView=new ImageView(mContext);
  mDragView.setImageDrawable(mDragIcon);
  mDragView.setOnTouchListener(this);
  addView(mDragView);
 }
 
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  mWidth=getMeasuredWidth();
  mHight=getMeasuredHeight();
  mCircleRadius=dp2px(mContext,32);
  mDragWidth=dp2px(mContext,50);
  mLineWidth=mWidth-mDragWidth;
  mLineHeight=mCircleRadius/2;
  int count=getChildCount();
  for (int i=0;i<count;i++){
   View view=getChildAt(i);
   LinearLayout.LayoutParams params;
   if (view instanceof CircleView){
    params=new LinearLayout.LayoutParams(mCircleRadius,mCircleRadius);
    view.setLayoutParams(params);
   }else if (view instanceof ImageView){
    params=new LinearLayout.LayoutParams(mDragWidth,mDragWidth);
    view.setLayoutParams(params);
   }else {
    params=new LinearLayout.LayoutParams(mLineWidth,mLineHeight);
    view.setLayoutParams(params);
   }
  }
 }
 
 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
//  super.onLayout(changed, l, t, r, b);
  if (changed){
   int count =getChildCount();
   int dLeft=0;
   int dTop=mHight/2-mDragWidth/2;
   int cLeft=mDragWidth/2-mCircleRadius/2;
   int cTop=dTop+mDragWidth/2-mCircleRadius/2;
   int lLeft=mDragWidth/2;
   int lTop=dTop+mDragWidth/2-mLineHeight/2;
   mMinX=dLeft;
   mMaxX=dLeft+mLineWidth;
   int cIndex=0;
   int cSpace=0;
   for (int i=0;i<count;i++){
    View view=getChildAt(i);
    if (view instanceof CircleView){
     cLeft=cLeft+cSpace;
     view.layout(cLeft,cTop,cLeft+mCircleRadius,cTop+mCircleRadius);
     cIndex++;
     cSpace=cIndex*mLineWidth;
    }else if (view instanceof ImageView){
     view.layout(dLeft,dTop,dLeft+mDragWidth,dTop+mDragWidth);
    }else {
     view.layout(lLeft,lTop,lLeft+mLineWidth,lTop+mLineHeight);
    }
   }
  }
 }
 
 @Override
 public boolean onTouch(View v, MotionEvent event) {
  if (v instanceof ImageView){
   switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
     mStartX = (int) event.getRawX();
     mCurX = v.getTranslationX();//获取view的偏移量
     v.setPressed(true);
     break;
    case MotionEvent.ACTION_MOVE:
     float x = mCurX + event.getRawX() - mStartX;
     if (x >= 0 && x <= mMaxX - mMinX) {
      v.setTranslationX(mCurX + event.getRawX() - mStartX);
     }
     break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_CANCEL:
     int distance=(int) (event.getRawX()-mStartX);
     if (distance>0){
      if (Math.abs(distance)>mLineWidth/2){
       v.setTranslationX(mCurX + event.getRawX() - mStartX);
       setAnim(mLineWidth,1);
      }else {
       v.setTranslationX(mCurX + event.getRawX() - mStartX);
       setAnim(0,0);
      }
     }else if (distance<0){
      if (Math.abs(distance)>mLineWidth/2){
       v.setTranslationX(mCurX + event.getRawX() - mStartX);
       setAnim(0,0);
      }else {
       v.setTranslationX(mCurX + event.getRawX() - mStartX);
       setAnim(mLineWidth,1);
      }
     }
     break;
   }
  }else if (v instanceof CircleView){
   switch (event.getAction()) {
    case MotionEvent.ACTION_UP:
     if (event.getRawX()>getDisplayWidth()/2){
      setAnim(mLineWidth,1);
     }else {
      setAnim(0,0);
     }
     break;
   }
  }
  return true;
 }
 //设置平移动画
 private void setAnim(float moveX, final int scrollPosition) {
  ObjectAnimator animator = ObjectAnimator.ofFloat(mDragView, "translationX", mDragView.getTranslationX(), moveX);
  animator.setDuration(300);
  animator.start();
  if (mOnNodeSelect != null) {
   mOnNodeSelect.onNodeSelect(scrollPosition);
  }
 }
 public void setNodeSelectListener(OnNodeSelect onNodeSelect) {
  mOnNodeSelect = onNodeSelect;
 }
 //事件回调接口
 public interface OnNodeSelect {
  void onNodeSelect(int position);
 }
 //dp转px
 public int dp2px(Context context, float dpValue)
 {
  final float scale = context.getResources().getDisplayMetrics().density;
  return (int) (dpValue * scale + 0.5f);
 }
 //获取屏幕宽度
 public int getDisplayWidth(){
  DisplayMetrics metrics=new DisplayMetrics();
  ((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);
  return metrics.widthPixels;
 }
}

使用方法

布局文件:


 <com.pengkv.apple.weight.DragView
  android:id="@+id/view_drag"
  android:layout_width="200dp"
  app:icon_drag="@drawable/ic_drag"
  app:color_circle="#CCCCCC"
  app:dot_num="2"
  android:layout_height="60dp"/>

页面代码:


 dragView=(DragView)view.findViewById(R.id.view_drag);
 dragView.setNodeSelectListener(new DragView.OnNodeSelect() {
  @Override
  public void onNodeSelect(int position) {
   Toast.makeText(getActivity(),"我选择了"+position,Toast.LENGTH_SHORT).show();
  }
 });
您可能感兴趣的文章:android为ListView每个Item上面的按钮添加事件android中在Activity中响应ListView内部按钮的点击事件的两种方法Android自定义View制作动态炫酷按钮实例解析Android ListView实现仿iPhone实现左滑删除按钮的简单实例Android ListView ImageView实现单选按钮实例Android自定义View之圆形进度条式按钮Android自定义View实现开关按钮Android基于ImageView绘制的开关按钮效果示例自定义滑动按钮为例图文剖析Android自定义View绘制Android自定义View实现可展开、会呼吸的按钮


--结束END--

本文标题: Android自定义View实现拖动选择按钮

本文链接: https://www.lsjlt.com/news/24972.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作