2012-11-01 38 views
0

任何人都可以請告訴我如何創建一個圓形的seekbar。如何在android中創建一個圓形的seekbar

在此先感謝。

+0

請發佈提問之前使用搜索功能 - 這個問題已經被問了幾次已經:) – ajacian81

+1

是的,我做到了。但我無法找到我想要的最接近的答案。如果您對我的問題有解決方案,請提供給我解決方案。 :) 謝謝 。 –

+0

你知道嗎,你可能是對的。對不起,現在是凌晨5點30分,我誤解了你的問題 - 我以爲你說過進度條,其中有很多這個問題。如果你編輯你的問題,我會upvote這個問題。 – ajacian81

回答

1

這裏是改變圓上搜索欄正在進行。此碼半徑的代碼在我的應用程序

private class test extends View { 
    private int radius; 

    public test(Context context) { 
     super(context); 
     // TODO Auto-generated constructor stub 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     // TODO Auto-generated method stub 
     super.onDraw(canvas); 
     Paint paint = new Paint(); 
     paint.setAntiAlias(false); 
     paint.setStyle(Paint.Style.FILL); 
     paint.setColor(Color.RED); 

     // RectF rect = new RectF(100, 100, 200, 200); 
     // canvas.drawRect(rect, paint); 
     canvas.drawCircle(50, 50, getRadius(), paint); 
     canvas.drawLine(10, 10, 10, 10 + 15, paint); 

    } 

    /** 
    * @param radius the radius to set 
    */ 
    public void setRadius(int radius) { 
     this.radius = radius; 
    } 

    /** 
    * @return the radius 
    */ 
    public int getRadius() { 
     return radius; 
    } 
} 

在活動

LinearLayout layout = new LinearLayout(this); 
    layout.setLayoutParams(new LayoutParams(320, 420)); 
    layout.setOrientation(LinearLayout.VERTICAL); 
    tt = new test(this); 
    tt.setLayoutParams(new LayoutParams(100, 200)); 
    layout.addView(tt); 

    SeekBar bar = new SeekBar(this); 
    bar.setMax(40); 
    bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 

     @Override 
     public void onStopTrackingTouch(SeekBar seekBar) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onStartTrackingTouch(SeekBar seekBar) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void onProgressChanged(SeekBar seekBar, int progress, 
       boolean fromUser) { 
      // TODO Auto-generated method stub 
      tt.setRadius(progress); 
      tt.invalidate(); 
     } 
    }); 

    layout.addView(bar); 

    setContentView(layout); 

希望對你有用成功運行。

+0

嘿,謝謝你。但它不能解決我的目的。我想創建一個圓形的seekbar。在這裏,由於seekbar的進度,它會創建一個不是我想要的圈子。我再次想要創建一個圓形的seekbar。請問你有什麼解決辦法嗎?再次感謝。 –

0

使用圖像自定義循環查找條。

public class ClockSlider extends View implements DialModel.Listener { 
     /* Display modes */ 
     public static final int CLOCK_SLIDER = 1; 
     public static final int VOLUME_SLIDER = 2; 
     public static final int VIBRATE_PICKER = 3; 

     public static final boolean ENABLE_VIBRATE = false; 
     private static final int INSETS = 6; 
     private static final int MINUTES_PER_HALF_DAY = 100; 

     private int width; 
     private int height; 
     private int centerX; 
     private int centerY; 
     private int diameter; 
     private RectF innerCircle; 
     private int displayMode = CLOCK_SLIDER; 

     private Calendar start = new GregorianCalendar(); 
     private int startAngle = 90; 
     private Calendar end = new GregorianCalendar(); 

     /** minutes to shush. */ 
     private int minutes = 0; 

     private Bitmap bgBitmap; 
     private Bitmap fgBitmap; 
     private Path clipPath = new Path(); 

     private DialModel model; 
     private float luftRotation = 0.0f; 
     private int totalNicks = 100; 
     private int currentNick = 0; 

     public ClockSlider(Context context, AttributeSet attrs) { 
      super(context, attrs); 

      bgBitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.black_circle); 
      fgBitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.blue_circle); 
      setModel(new DialModel()); 
     } 

     public final void setModel(DialModel model) { 
      if (this.model != null) { 
       this.model.removeListener(this); 
      } 
      this.model = model; 
      this.model.addListener(this); 

      invalidate(); 
     } 

     public final DialModel getModel() { 
      return model; 
     } 



     public Date getStart() { 
      return start.getTime(); 
     } 



     public int getMinutes() { 
      return minutes; 
     } 

     public void setMinutes(int minutes) { 
      if (minutes == this.minutes) { 
       return; // avoid unnecessary repaints 
      } 
      this.minutes = minutes; 
      end.setTimeInMillis(start.getTimeInMillis() + (this.minutes * 60 * 1000L)); 
      postInvalidate(); 
     } 

    // public final float getRotationInDegrees() { 
    //  return (360.0f/totalNicks) * currentNick; 
    // } 

     public Date getEnd() { 
      return end.getTime(); 
     } 

     @Override 
     protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 
      if (getWidth() != width || getHeight() != height) { 
       width = bgBitmap.getWidth(); 
       height = bgBitmap.getHeight(); 
    //   width = getWidth(); 
    //   height = getHeight(); 
       centerX = width/2; 
       centerY = height/2; 

       diameter = Math.min(width, height) - (2 * INSETS); 
       int thickness = diameter/15; 

       int left = (width - diameter)/2; 
       int top = (height - diameter)/2; 
       int bottom = top + diameter; 
       int right = left + diameter; 
    //   outerCircle = new RectF(left, top, right, bottom); 
       int innerDiameter = diameter - thickness * 2; 
    //   innerCircle = new RectF(left + thickness, top + thickness, left 
    //   + thickness + innerDiameter, top + thickness + innerDiameter); 

       innerCircle = new RectF(0, 0,width,height); 
       canvas.drawBitmap(bgBitmap, null, innerCircle, null); 
      } 

      if (displayMode == CLOCK_SLIDER) { 
       drawClock(canvas); 
      } else { 
       throw new AssertionError(); 
      } 
     } 
     /** 
     * Draw a circle and an arc of the selected duration from start thru end. 
     */ 
     private void drawClock(Canvas canvas) { 
      int sweepDegrees = (minutes/2) - 1; 

      canvas.drawBitmap(bgBitmap, null, innerCircle, null); 
      // the colored "filled" part of the circle 
      drawArc(canvas, startAngle, sweepDegrees); 

     } 

     @Override 
     public void onDialPositionChanged(DialModel sender, int nicksChanged) { 
      luftRotation = (float) (Math.random() * 1.0f - 0.5f); 
      invalidate(); 
     } 

     private void drawArc(Canvas canvas, int startAngle, int sweepDegrees) { 
      if (sweepDegrees <= 0) { 
       return; 
      } 
      clipPath.reset(); 
      clipPath.moveTo(innerCircle.centerX(), innerCircle.centerY()); 
      clipPath.arcTo(innerCircle, startAngle + sweepDegrees, -sweepDegrees); 
    //  clipPath.lineTo(getWidth()/2, getHeight()/2); 
      canvas.clipPath(clipPath); 

      canvas.drawBitmap(fgBitmap, null, innerCircle, null); 

      invalidate(); 
     } 

     /** 
     * Accept a touches near the circle's edge, translate it to an angle, and 
     * update the sweep angle. 
     */ 
     @Override 
     public boolean onTouchEvent(MotionEvent event) { 
      int touchX = (int) event.getX(); 
      int touchY = (int) event.getY(); 
      int newDisplayMode = displayMode; 

      if (event.getAction() == MotionEvent.ACTION_UP) { 
       newDisplayMode = CLOCK_SLIDER; 
      } 

      int distanceFromCenterX = centerX - touchX; 
      int distanceFromCenterY = centerY - touchY; 
      int distanceFromCenterSquared = distanceFromCenterX * distanceFromCenterX + distanceFromCenterY * distanceFromCenterY; 
      float maxSlider = (diameter * 1.3f)/2; 
      float maxUpDown = (diameter * 0.8f)/2; 

      /* 
      * Convert the angle into a sweep angle. The sweep angle is a positive 
      * angle between the start angle and the touched angle. 
      */ 
    //  if (distanceFromCenterSquared < (maxSlider * maxSlider)) { 
      float x1 = bgBitmap.getWidth(), x2 = bgBitmap.getHeight(), y1 = bgBitmap 
        .getWidth(), y2 = bgBitmap.getHeight(); 
      if ((touchX <= x1 && touchX <= x2) && (touchY <= y1 && touchY <= y2)) { 
       int angle = pointToAngle(touchX, touchY); 
       angle = 360 + angle - startAngle; 
       int angleX2 = angle * 2; 
       angleX2 = roundToNearest15(angleX2); 
       if (angleX2 > 720) { 
        angleX2 = angleX2 - 720; // avoid mod because we prefer 720 over 
       } 
       if (angle <= 364) { 
        angleX2 = 0; 
       } 
    //   if (angleX2 > 720 || angleX2 < 400) { 
    //    return false; 
    //   } 
       setMinutes(angleX2); 
       model.rotate(Integer.valueOf("" + Math.round((angleX2/5.4)))); 
       return true; 
      } else { 

       return false; 
      } 
     } 


     public int getProgress(){ 
      return minutes; 
     } 
     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      int width = MeasureSpec.getSize(widthMeasureSpec); 
      int height = MeasureSpec.getSize(heightMeasureSpec); 

      // Don't use the full screen width on tablets! 
      DisplayMetrics metrics = new DisplayMetrics(); 
      WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 
      windowManager.getDefaultDisplay().getMetrics(metrics); 
      float maxWidthInches = 2.3f; 

      width = Math.min(width, (int) (maxWidthInches * metrics.densityDpi)); 
      height = Math.min(height, (int) (width * 0.7f)); 

      setMeasuredDimension(width, height); 
     } 

     /** 
     * Returns the number of degrees (0-359) for the given point, such that 3pm 
     * is 0 and 9pm is 180. 
     */ 
     private int pointToAngle(int x, int y) { 

      if (x >= centerX && y < centerY) { 
       double opp = x - centerX; 
       double adj = centerY - y; 
       return 270 + (int) Math.toDegrees(Math.atan(opp/adj)); 
      } else if (x > centerX && y >= centerY) { 
       double opp = y - centerY; 
       double adj = x - centerX; 
       return (int) Math.toDegrees(Math.atan(opp/adj)); 
      } else if (x <= centerX && y > centerY) { 
       double opp = centerX - x; 
       double adj = y - centerY; 
       return 90 + (int) Math.toDegrees(Math.atan(opp/adj)); 
      } else if (x < centerX && y <= centerY) { 
       double opp = centerY - y; 
       double adj = centerX - x; 
       return 180 + (int) Math.toDegrees(Math.atan(opp/adj)); 
      } 

      throw new IllegalArgumentException(); 
     } 

     /** 
     * Rounds the angle to the nearest 7.5 degrees, which equals 15 minutes on a 
     * clock. Not strictly necessary, but it discourages fat-fingered users from 
     * being frustrated when trying to select a fine-grained period. 
     */ 
     private int roundToNearest15(int angleX2) { 
      return ((angleX2 + 8)/15) * 15; 
     } 

    }