虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Android编程 > Android自定义View实现拖动选择按钮

Android自定义View实现拖动选择按钮
类别:Android编程   作者:码皇   来源:互联网   点击:

这篇文章主要为大家详细介绍了Android自定义View实现拖动选择按钮的具体代码,感兴趣的小伙伴们可以参考一下

本文为大家分享了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;
    /** * 默认半径dp */ 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();
    }
    /** *视图初始化,这个方法的作用是把所有的视图添加进来,并做一些初始化的配置 * 其实可以用LayoutInflater把xml的布局文件加载进来,这样比较简便 */ 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);
    }
    /** *这一步主要是为了测量、配置每个view的大小,以便于后面触摸事件的处理 */ @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);
    }
    }
    }
    /** *这一步主要是为了放置每个view的位置,如果用LayoutInflater加载布局文件,那这一步就可以省略了 */ @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);
    }
    }
    }
    }
    /** *触碰事件的处理,这是自定义view比较重要的地方 */ @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拖动选择按钮 Android自定义拖动选