自定义圆形seekBar,想监听用户转了几圈,如何实现!

老子很可爱 2016-12-08 06:57:40
这是我的自定义seekbar,我监听用户的时候,监听到的当前进度值是不连贯的:如 2,3,5,22,23;我有个需求就是当我这个seekbar转了一圈,textview的数值就+1,请问要怎么实现;

public class CircleSeekBar extends View {

private float YAxis; /**滑动块的Y值*/
private float XAxis; /**滑动块的Y值*/

private OnSeekBarChangeListener mChangListener;

public CircleSeekBar(Context context) {
this(context, null);
}

public CircleSeekBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public CircleSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

initAttrs(attrs, defStyleAttr);
initPaints();
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = mBgBitmap.getHeight()+mPointBitmap.getHeight();
int width = mBgBitmap.getWidth()+mPointBitmap.getWidth();
int min = Math.min(width, height);
setMeasuredDimension(min, min);

refershPosition();
refershUnreachedWidth();
}

@Override
protected void onDraw(Canvas canvas) {
/**padding = 6 */


float left = mPointBitmap.getWidth()-getPaddingLeft()-getPaddingRight();
float top = mPointBitmap.getHeight()-getPaddingTop()-getPaddingBottom();
float right = mBgBitmap.getWidth()+getPaddingRight()+getPaddingLeft();
float bottom = mBgBitmap.getHeight()+getPaddingBottom()+getPaddingTop()+getPaddingBottom();
float centerX = (left + right) / 2;
float centerY = (top + bottom) / 2;


float wheelRadius = (canvas.getWidth() - getPaddingLeft() - getPaddingRight()) / 2 - mUnreachedWidth / 2;

if (isHasCache) {
if (mCacheCanvas == null) {
buildCache((int)centerX, (int)centerY, wheelRadius);
}
canvas.drawBitmap(mCacheBitmap, 0, 0, null);
} else {
//canvas.drawCircle(centerX, centerY, wheelRadius, mWheelPaint);
//canvas.drawBitmap(mBgBitmap,5,8,null);
canvas.drawBitmap(mBgBitmap,mPointBitmap.getWidth()/2,mPointBitmap.getHeight()/2+getPaddingTop(),null);

}

//画选中区域
canvas.drawArc(new RectF(left, top, right, bottom), -90, (float) mCurAngle, false, mReachedPaint);

//画锚点
canvas.drawBitmap(mPointBitmap,mWheelCurX-mPointBitmap.getHeight()/2,mWheelCurY-mPointBitmap.getHeight(),null);
}

private void buildCache(int centerX, int centerY, float wheelRadius) {
mCacheBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mCacheCanvas = new Canvas(mCacheBitmap);

//画环
// mCacheCanvas.drawCircle(centerX, centerY, wheelRadius, mWheelPaint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (isCanTouch && (event.getAction() == MotionEvent.ACTION_MOVE || isTouch(x, y))) {
// 通过当前触摸点搞到cos角度值
float cos = computeCos(x, y);
// 通过反三角函数获得角度值
if (x < getWidth() / 2) { // 滑动超过180度
mCurAngle = Math.PI * RADIAN + Math.acos(cos) * RADIAN;
//Log.e("TAG","超过180度 "+mCurAngle);

} else { // 没有超过180度
mCurAngle = Math.PI * RADIAN - Math.acos(cos) * RADIAN;
//Log.e("TAG","=============没有超过180度 "+mCurAngle);
}

mCurProcess = getSelectedValue();
refershWheelCurPosition(cos);
if (mChangListener != null) {
mChangListener.onChanged(this, mCurProcess, (int) YAxis, (int) XAxis);
}
invalidate();
return true;
} else {
return super.onTouchEvent(event);
}
}




/**刷新滚轮当前进度下标*/
private void refershWheelCurPosition(double cos) {
mWheelCurX = calcXLocationInWheel(mCurAngle, cos);
if (mWheelCurX==0){
mWheelCurX = mBgBitmap.getWidth()/2+mPointBitmap.getWidth()/2;
}
mWheelCurY = calcYLocationInWheel(cos);

}

/**刷新指针
*
* 1、初始话的时候调用
* 2、设置当前进度时候调用
* 3、设置最大进度时候调用
*
* */
private void refershPosition() {
mCurAngle = (double) mCurProcess / mMaxProcess * 360.0;
double cos = -Math.cos(Math.toRadians(mCurAngle));
refershWheelCurPosition(cos);
}

/**计算Wheel滚轮的位置*/
private float calcXLocationInWheel(double angle, double cos) {
if (angle < 180) {
XAxis = (float) (getWidth() / 2 + Math.sqrt(1 - cos * cos) * mUnreachedRadius);
return XAxis;
} else {
XAxis = (float) (getWidth() / 2 - Math.sqrt(1 - cos * cos) * mUnreachedRadius);
return XAxis;
}
}

private float calcYLocationInWheel(double cos) {
YAxis = getMeasuredWidth() / 2+mPointBitmap.getWidth()/2 + mUnreachedRadius * (float) cos;
return YAxis;
}

/**
* 拿到倾斜的cos值
*/
private float computeCos(float x, float y) {
float width = x - getWidth() / 2;
float height = y - getHeight() / 2;
float slope = (float) Math.sqrt(width * width + height * height);
return height / slope;
}

@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(INATANCE_STATE, super.onSaveInstanceState());
bundle.putInt(INSTANCE_MAX_PROCESS, mMaxProcess);
bundle.putInt(INSTANCE_CUR_PROCESS, mCurProcess);
bundle.putInt(INSTANCE_REACHED_COLOR, mReachedColor);
bundle.putFloat(INSTANCE_REACHED_WIDTH, mReachedWidth);
bundle.putBoolean(INSTANCE_REACHED_CORNER_ROUND, isHasReachedCornerRound);
// bundle.putInt(INSTANCE_UNREACHED_COLOR, mUnreachedColor);
bundle.putFloat(INSTANCE_UNREACHED_WIDTH, mUnreachedWidth);
bundle.putInt(INSTANCE_POINTER_COLOR, mPointerColor);
bundle.putFloat(INSTANCE_POINTER_RADIUS, mPointerRadius);
bundle.putBoolean(INSTANCE_POINTER_SHADOW, isHasPointerShadow);
bundle.putFloat(INSTANCE_POINTER_SHADOW_RADIUS, mPointerShadowRadius);
bundle.putBoolean(INSTANCE_WHEEL_SHADOW, isHasWheelShadow);
bundle.putFloat(INSTANCE_WHEEL_SHADOW_RADIUS, mPointerShadowRadius);
bundle.putBoolean(INSTANCE_WHEEL_HAS_CACHE, isHasCache);
bundle.putBoolean(INSTANCE_WHEEL_CAN_TOUCH, isCanTouch);
return bundle;
}

@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
super.onRestoreInstanceState(bundle.getParcelable(INATANCE_STATE));
mMaxProcess = bundle.getInt(INSTANCE_MAX_PROCESS);
mCurProcess = bundle.getInt(INSTANCE_CUR_PROCESS);
mReachedColor = bundle.getInt(INSTANCE_REACHED_COLOR);
mReachedWidth = bundle.getFloat(INSTANCE_REACHED_WIDTH);
isHasReachedCornerRound = bundle.getBoolean(INSTANCE_REACHED_CORNER_ROUND);
mUnreachedWidth = bundle.getFloat(INSTANCE_UNREACHED_WIDTH);
mPointerColor = bundle.getInt(INSTANCE_POINTER_COLOR);
mPointerRadius = bundle.getFloat(INSTANCE_POINTER_RADIUS);
isHasPointerShadow = bundle.getBoolean(INSTANCE_POINTER_SHADOW);
mPointerShadowRadius = bundle.getFloat(INSTANCE_POINTER_SHADOW_RADIUS);
isHasWheelShadow = bundle.getBoolean(INSTANCE_WHEEL_SHADOW);
mPointerShadowRadius = bundle.getFloat(INSTANCE_WHEEL_SHADOW_RADIUS);
isHasCache = bundle.getBoolean(INSTANCE_WHEEL_HAS_CACHE);
isCanTouch = bundle.getBoolean(INSTANCE_WHEEL_CAN_TOUCH);
initPaints();
} else {
super.onRestoreInstanceState(state);
}

if (mChangListener != null) {
mChangListener.onChanged(this, mCurProcess, (int) YAxis, (int) YAxis);
}
}

/**将角度换算成当前进度*/
private int getSelectedValue() {
return Math.round(mMaxProcess * ((float) mCurAngle / 360));

}





public void setUnreachedWidth(float unreachedWidth) {
this.mUnreachedWidth = unreachedWidth;
mWheelPaint.setStrokeWidth(unreachedWidth);
refershUnreachedWidth();
invalidate();
}


public float getPointerRadius() {
return mPointerRadius;
}

public void setPointerRadius(float pointerRadius) {
this.mPointerRadius = pointerRadius;
mPointerPaint.setStrokeWidth(pointerRadius);
invalidate();
}

/**是否绘制阴影*/
public boolean isHasWheelShadow() {
return isHasWheelShadow;
}

public float getWheelShadowRadius() {
return mWheelShadowRadius;
}

public boolean isHasPointerShadow() {
return isHasPointerShadow;
}

public float getPointerShadowRadius() {
return mPointerShadowRadius;
}


public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
mChangListener = listener;
}

public interface OnSeekBarChangeListener {
void onChanged(CircleSeekBar seekbar, int curValue,int YAxis,int XAxis);
}
}
...全文
218 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
内容概要:本文提出了一种基于粒子群优化算法(PSO)的配电网光伏储能双层优化配置模型,以IEEE33节点系统为研究对象,开展分布式能源的选址定容优化研究。该模型构建了上层规划与下层运行协同的双层优化框架:上层以最小化投资成本、网损成本、购电成本及电压偏差为目标,优化光伏和储能的选址与定容方案;下层则以日运行经济性最优为目标,优化储能充放电策略及网络拓扑结构。通过Matlab编程实现粒子群算法对该双层模型的求解,完成了从模型构建、算法设计到仿真实现的完整流程,实现了对配电网中光伏与储能系统的科学规划与经济运行的联合优化。; 适合人群:具备电力系统分析基础、熟悉Matlab编程工具,从事新能源接入、配电网络优化、智能优化算法应用等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:① 掌握双层优化模型在电力系统规划中的建模方法与求解思路;② 学习粒子群算法在复杂非线性工程问题中的实际应用技巧;③ 实现光伏与储能系统的协同选址定容,提升配电网的运行经济性、电压质量与新能源消纳能力; 阅读建议:建议结合IEEE33节点标准测试系统数据进行代码复现,深入理解上下层模型之间的迭代交互机制,并尝试引入其他智能优化算法(如GWO、WOA等)进行对比分析,以全面评估算法性能与优化效果。

684

社区成员

发帖
与我相关
我的任务
社区描述
智能路由器通常具有独立的操作系统,包括OpenWRT、eCos、VxWorks等,可以由用户自行安装各种应用,实现网络和设备的智能化管理。
linuxpython 技术论坛(原bbs)
社区管理员
  • 智能路由器社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧