Android自定义旋钮效果,Android_Android自定义View实现拖动选择按钮,本文为大家分享了Android实现拖 - phpStudy...

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

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

效果图

View代码

第一步:自定义属性

第二步:自定义圆形

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

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

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

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;

}

}

使用方法

布局文件:

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();

}

});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持phpstudy。相关阅读:

JavaScript中字符串拼接的基本方法

如何在LINUX系统下修改debian wheezy默认配置的方法

Win10安装应用提示错误代码0x80070490的两种解决方法

Mac OS下的命令行强化工具iTerm使用简介

JQuery实现动态适时改变字体颜色的方法

node.js中的fs.mkdirSync方法使用说明

百度地图PC端判断用户是否在配送范围内

Win7禁用USB接口、Win7禁用组策略、win7禁用便携设备的方法

yii2整合百度编辑器umeditor及umeditor图片上传问题的解决办法

正则表达式实现将MM/DD/YYYY格式的日期转换为YYYY-MM-DD格式

js生成随机数的过程解析

JavaScript如何动态创建table表格

深入理解C语言的逻辑控制

SQL SERVER调用存储过程小结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值