我一直在使用this site
中的自定义Seekbar(带有两个拇指)我已经对代码做了一些修改,以使其适应我的需要,并且更加模块化(拇指定位,绘图等)。我注意到创建活动时有点小问题。以下是我的问题的症状。
有什么想法吗?
感谢您的帮助!
这是完整的课程:
public class SeekBarWithTwoThumb extends View {
// ***************
// Members
// ***************
// Drawing resources
private Bitmap thumb = BitmapFactory.decodeResource(getResources(),R.drawable.seek_thumb_normal);
private Bitmap thumb_pressed = BitmapFactory.decodeResource(getResources(),R.drawable.seek_thumb_pressed);
private Bitmap thumb_dissabled = BitmapFactory.decodeResource(getResources(),R.drawable.seek_thumb_dissabled);
// Thumb's X coordinates and Y common coordinate
private int thumb1X, thumb2X;
private int thumbY;
// Thumb's return values
private int thumb1Value, thumb2Value;
// Thumb's dimensions
private int thumbHalfWidth;
private int thumbWidth;
// Selected thumb
private int selectedThumb;
private int lastSelectedThumb = 1;
// Paint object and listener
private Paint paint = new Paint();
private SeekBarChangeListener scl;
// Max value returned to listener
private int maxValue = 100;
// Thumb's enabled status
private boolean thumb1Enabled = true;
private boolean thumb2Enabled = false;
// Before init happens (not drawn in UI)
private boolean initDone = false;
private int thumb1Xpreset = 0, thumb2Xpreset = 50;
// ****************
// Constructors
// ****************
public SeekBarWithTwoThumb(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public SeekBarWithTwoThumb(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SeekBarWithTwoThumb(Context context) {
super(context);
}
// ***************
// Overrides
// ***************
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if ((widthMeasureSpec != 0) && (heightMeasureSpec != 0)) {
init();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Print the gray line in the back
paint.setStrokeWidth(1);
paint.setColor(Color.GRAY);
canvas.drawLine(thumbHalfWidth, getHeight() / 2, getWidth() - thumbHalfWidth, getHeight() / 2, paint);
// Print the progress line according seekbar settings
paint.setStrokeWidth(3);
paint.setColor(0xFF33B5E5); // Hollow blue
int drawThumbFirst = 0; // Variable used declare which thumb will be drawn first
if(thumb1Enabled && !thumb2Enabled) {
canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb1X, getHeight() / 2, paint);
drawThumbFirst = 2;
} else if (!thumb1Enabled && thumb2Enabled){
canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb2X, getHeight() / 2, paint);
drawThumbFirst = 1;
} else if (!thumb1Enabled && !thumb2Enabled) {
// Do not draw, both are disabled
} else if (selectedThumb == 1){
canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb1X, getHeight() / 2, paint);
} else if (selectedThumb == 2){
canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb2X, getHeight() / 2, paint);
} else if (lastSelectedThumb == 1){
canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb1X, getHeight() / 2, paint);
} else if (lastSelectedThumb == 2){
canvas.drawLine(thumbHalfWidth, getHeight() / 2, thumb2X, getHeight() / 2, paint);
}
if (drawThumbFirst == 2){
if (!thumb2Enabled) {
canvas.drawBitmap(thumb_dissabled, thumb2X - thumbHalfWidth, thumbY,paint);
} else if(selectedThumb == 2){
canvas.drawBitmap(thumb_pressed, thumb2X - thumbHalfWidth, thumbY,paint);
} else {
canvas.drawBitmap(thumb, thumb2X - thumbHalfWidth, thumbY,paint);
}
if (!thumb1Enabled) {
canvas.drawBitmap(thumb_dissabled, thumb1X - thumbHalfWidth, thumbY,paint);
} else if(selectedThumb == 1){
canvas.drawBitmap(thumb_pressed, thumb1X - thumbHalfWidth, thumbY,paint);
} else {
canvas.drawBitmap(thumb, thumb1X - thumbHalfWidth, thumbY,paint);
}
} else { // drawThumbFirst == 1 or 0 (0 has no importance since both thumbs either enabled or disabled)
if (!thumb1Enabled) {
canvas.drawBitmap(thumb_dissabled, thumb1X - thumbHalfWidth, thumbY,paint);
} else if(selectedThumb == 1){
canvas.drawBitmap(thumb_pressed, thumb1X - thumbHalfWidth, thumbY,paint);
} else {
canvas.drawBitmap(thumb, thumb1X - thumbHalfWidth, thumbY,paint);
}
if (!thumb2Enabled) {
canvas.drawBitmap(thumb_dissabled, thumb2X - thumbHalfWidth, thumbY,paint);
} else if(selectedThumb == 2){
canvas.drawBitmap(thumb_pressed, thumb2X - thumbHalfWidth, thumbY,paint);
} else {
canvas.drawBitmap(thumb, thumb2X - thumbHalfWidth, thumbY,paint);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Get X coordinate of event
int mx = (int) event.getX();
switch (event.getAction()) {
// Check if one of the thumbs are selected
case MotionEvent.ACTION_DOWN:
if (mx >= thumb1X - thumbHalfWidth &&
mx <= thumb1X + thumbHalfWidth &&
thumb1Enabled) {
selectedThumb = 1;
} else if (mx >= thumb2X - thumbHalfWidth &&
mx <= thumb2X + thumbHalfWidth &&
thumb2Enabled) {
selectedThumb = 2;
}
break;
// If one of the thumbs are selected, move it
case MotionEvent.ACTION_MOVE:
// Prevent thumb to get out of frame
if(mx < thumbHalfWidth){
mx = thumbHalfWidth;
} else if(mx > (getWidth() - thumbHalfWidth)) {
mx = getWidth() - thumbHalfWidth;
}
// Move the selected thumb to location
if (selectedThumb == 1) {
thumb1X = mx;
} else if (selectedThumb == 2) {
thumb2X = mx;
}
break;
// Remove selection, if any
case MotionEvent.ACTION_UP:
lastSelectedThumb = selectedThumb;
selectedThumb = 0;
break;
}
// Refresh
invalidate();
// Call listener if set
if(scl != null){
calculateThumbValue();
scl.SeekBarValueChanged(thumb1Value,thumb2Value);
}
return true;
}
// ***************
// Methods
// ***************
private void init() {
// Fix layout if thumb image is to big
Log.d("Custom Seekbars", "Height: " + thumb.getHeight() + ", " + getHeight());
if (thumb.getHeight() > getHeight()){
getLayoutParams().height = thumb.getHeight();
}
// Set the thumb's dimensions
thumbHalfWidth = thumb.getWidth()/2;
thumbWidth = thumb.getWidth();
// Set the thumb's coordinates
float workingWidth = getWidth() - thumbWidth;
float scale1 = ((float)(thumb1Xpreset))/((float)(maxValue));
float scale2 = ((float)(thumb2Xpreset))/((float)(maxValue));
thumb1X = Math.round((scale1*workingWidth) + thumbHalfWidth);
thumb2X = Math.round((scale2*workingWidth) + thumbHalfWidth);
thumbY = (getHeight() / 2) - (thumb.getHeight() / 2);
initDone = true;
// Refresh
invalidate();
}
public void setSeekBarChangeListener(SeekBarChangeListener scl){
this.scl = scl;
}
private void calculateThumbValue(){
thumb1Value = getThumb1Value();
thumb2Value = getThumb2Value();
}
public interface SeekBarChangeListener{
void SeekBarValueChanged(int Thumb1Value,int Thumb2Value);
}
public void setMax(int maxValue){
if(initDone){
int thumb1val = getThumb1Value();
int thumb2val = getThumb1Value();
this.maxValue = maxValue;
setThumbValues(thumb1val, thumb2val);
} else {
this.maxValue = maxValue;
}
}
// Disable & enable methods
public void setEnable(boolean value){
thumb1Enabled = value;
thumb2Enabled = value;
}
public void setDisable(boolean value){
thumb1Enabled = !value;
thumb2Enabled = !value;
}
public void setEnable(boolean thumb1, boolean thumb2){
thumb1Enabled = thumb1;
thumb2Enabled = thumb2;
}
public void setDisable(boolean thumb1, boolean thumb2){
thumb1Enabled = !thumb1;
thumb2Enabled = !thumb2;
}
// Thumb value setters and getters
public void setThumbValues(int thumb1, int thumb2){
if(initDone){
if(thumb1 >= maxValue){
thumb1X = getWidth() - thumbHalfWidth;
} else if(thumb1 <= 0) {
thumb1X = thumbHalfWidth;
} else {
float workingWidth = getWidth() - thumbWidth;
float scale = ((float)(thumb1))/((float)(maxValue));
thumb1X = Math.round((scale*workingWidth) + thumbHalfWidth);
}
if(thumb2 >= maxValue){
thumb2X = getWidth() - thumbHalfWidth;
} else if(thumb2 <= 0) {
thumb2X = thumbHalfWidth;
} else {
float workingWidth = getWidth() - thumbWidth;
float scale = ((float)(thumb2))/((float)(maxValue));
thumb2X = Math.round((scale*workingWidth) + thumbHalfWidth);
}
// Refresh
invalidate();
// Call listener if set
if(scl != null){
calculateThumbValue();
scl.SeekBarValueChanged(thumb1Value,thumb2Value);
}
} else {
if(thumb1 >= maxValue){
thumb1Xpreset = maxValue;
} else if(thumb1 <= 0) {
thumb1Xpreset = 0;
} else {
thumb1Xpreset = thumb1;
}
if(thumb2 >= maxValue){
thumb2Xpreset = maxValue;
} else if(thumb2 <= 0) {
thumb2Xpreset = 0;
} else {
thumb2Xpreset = thumb2;
}
}
}
public void setThumb1Value(int value){
if(initDone){
if(value >= maxValue){
thumb1X = getWidth() - thumbHalfWidth;
} else if(value <= 0) {
thumb1X = thumbHalfWidth;
} else {
float workingWidth = getWidth() - thumbWidth;
float scale = ((float)(value))/((float)(maxValue));
thumb1X = Math.round((scale*workingWidth) + thumbHalfWidth);
}
// Refresh
invalidate();
// Call listener if set
if(scl != null){
calculateThumbValue();
scl.SeekBarValueChanged(thumb1Value,thumb2Value);
}
} else {
if(value >= maxValue){
thumb1Xpreset = maxValue;
} else if(value <= 0) {
thumb1Xpreset = 0;
} else {
thumb1Xpreset = value;
}
}
}
public void setThumb2Value(int value){
if(initDone){
if(value >= maxValue){
thumb2X = getWidth() - thumbHalfWidth;
} else if(value <= 0) {
thumb2X = thumbHalfWidth;
} else {
float workingWidth = getWidth() - thumbWidth;
float scale = ((float)(value))/((float)(maxValue));
thumb2X = Math.round((scale*workingWidth) + thumbHalfWidth);
}
// Refresh
invalidate();
// Call listener if set
if(scl != null){
calculateThumbValue();
scl.SeekBarValueChanged(thumb1Value,thumb2Value);
}
} else {
if(value >= maxValue){
thumb2Xpreset = maxValue;
} else if(value <= 0) {
thumb2Xpreset = 0;
} else {
thumb2Xpreset = value;
}
}
}
public int getThumb1Value(){
if(initDone){
float workingWidth = getWidth() - thumbWidth;
return Math.round((float)maxValue * ((float)(thumb1X - thumbHalfWidth)/workingWidth));
} else {
return thumb1Xpreset;
}
}
public int getThumb2Value(){
if(initDone){
float workingWidth = getWidth() - thumbWidth;
return Math.round((float)maxValue * ((float)(thumb2X - thumbHalfWidth)/workingWidth));
} else {
return thumb2Xpreset;
}
}
}