0

помогите мне выйти из этой проблемы. Колесо View (CircleView) отлично работает в основных устройствах, но эта ошибка возникает из устройств s4 и примечания 3.android: canvas Touch не работает в s4

Прикосновение становится вычитаемым, но не подпадает под зону weidgetregion.

ложь - 1 должен быть правдой - 1

Регион Вход в enter image description here Мой круг Просмотр кода

public class CircleView extends View implements OnTouchListener{ 
boolean firstTime = false; 
private List<CircleViewBean> mMenuEntries = new ArrayList<CircleViewBean>(); 
private OnCellTouchListener mOnCellTouchListener = null; 
public interface OnCellTouchListener { 
    public void onTouch(Wedge cell); 
} 
private Shader mShader; 

private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); 

private float screen_density = getContext().getResources().getDisplayMetrics().density; 

//Radius of inner ring size 
private int mMinSize = scalePX(60); 
//Radius of outer ring size 
private int mMaxSize = scalePX(170); 
private int mWedgeQty = 6; 
//Center X location of Radial Menu 
private int xPosition = scalePX(120); 
//Center Y location of Radial Menu 
private int yPosition = scalePX(120); 
int touchIndex = -1; 
private Wedge[] mWedges; 

private RectF mViewRect = new RectF(); 

private int scalePX(int dp_size) 
{ 
    return (int) (dp_size * screen_density + 0.5f); 
} 

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

public CircleView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    HashMap<String, String> device = Constants.getDeviceDetails(getResources().getDisplayMetrics().heightPixels, getResources().getDisplayMetrics().widthPixels); 
    mMinSize = Integer.parseInt(device.get("in_arc")); 
    mMaxSize = Integer.parseInt(device.get("out_arc")); 
    setBackgroundResource(R.drawable.centre_wheel); 
} 
private void determineWedges() { 
    int entriesQty = mMenuEntries.size(); 
    if (entriesQty > 0) { 
     mWedgeQty = entriesQty; 

     float degSlice = 360/mWedgeQty; 
     float start_degSlice = 270 - (degSlice/2); 
     //calculates where to put the images 

     this.mWedges = new Wedge[mWedgeQty]; 

     double mid = 0, min = 0, max = 0; 
     for(int i = 0; i < this.mWedges.length; i++) { 
      this.mWedges[i] = new Wedge(xPosition, yPosition, mMinSize, mMaxSize, (i 
        * degSlice)+start_degSlice, degSlice, mMenuEntries.get(i).getIndex()); 

      mid = this.mWedges[i].midValue = normalizeAngle(((i * degSlice) + start_degSlice + degSlice)/2); 
      min = normalizeAngle((i * degSlice) + start_degSlice); 
      max = normalizeAngle((i * degSlice) + start_degSlice + degSlice); 

      this.mWedges[i].minValue = min; 
      this.mWedges[i].midValue = mid; 
      this.mWedges[i].maxValue = max; 

      mViewRect.union(new RectF(mWedges[i].getWedgeRegion().getBounds())); 
     } 

     mShader = new RadialGradient(xPosition, yPosition, mMaxSize, new int[] { 0xff595756, 0xffCCC5C3, 0xf878280}, null, Shader.TileMode.MIRROR); 
     invalidate(); 
    } 
} 

@Override 
public void onDraw(Canvas canvas) { 
    if(!firstTime){ 
     firstTime = true; 
     this.xPosition = (int) (getWidth()/2f); 
     this.yPosition = (int) (getHeight()/2f); 
     determineWedges(); 
    } 
    canvas.scale(getWidth()/mViewRect.width(), getHeight()/mViewRect.width(), xPosition, yPosition); 
    //Saving the canvas and later restoring it so only this image will be rotated. 
    canvas.save(Canvas.MATRIX_SAVE_FLAG); 

    canvas.restore(); 
    canvas.save(); 
    canvas.restore(); 

    mPaint.setShader(mShader); 
} 

private double normalizeAngle(double angle) { 
    if(angle >= 0) { 
     while(angle > 360) { 
      angle -= 360; 
     } 
    } 
    else { 
     while(angle < -360) { 
      angle += 360; 
     } 
    } 
    return angle; 
} 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    // TODO Auto-generated method stub 
    int wmode = MeasureSpec.getMode(widthMeasureSpec); 
    int hmode = MeasureSpec.getMode(heightMeasureSpec); 
    int wsize = MeasureSpec.getSize(widthMeasureSpec); 
    int hsize = MeasureSpec.getSize(heightMeasureSpec); 

    int width = (int)mViewRect.width(); 
    int height = (int) mViewRect.height(); 

    if (wmode == MeasureSpec.EXACTLY) { 
     width = wsize; 
    } 
    if (hmode == MeasureSpec.EXACTLY) { 
     height = hsize; 
    } 
    this.setMeasuredDimension(width, height); 
    invalidate(); 

} 

public class Wedge extends Path { 
    private int x, y; 
    private int InnerSize, OuterSize; 
    private float StartArc; 
    private float ArcWidth; 
    private Region mWedgeRegion; 
    private int index=0; 
    public double minValue; 
    public double midValue; 
    public double maxValue; 
    private Wedge(int x, int y, int InnerSize, int OuterSize, float StartArc, float ArcWidth, int category) { 
     super(); 
     this.index = category; 
     if (StartArc >= 360) { 
      StartArc = StartArc-360; 
     } 

     minValue = midValue = maxValue = 0; 
     mWedgeRegion = new Region(); 
     this.x = x; this.y = y; 
     this.InnerSize = InnerSize; 
     this.OuterSize = OuterSize; 
     this.StartArc = StartArc; 
     this.ArcWidth = ArcWidth; 
     this.buildPath(); 
    } 
    public int getCategoryIndex(){ 
     return this.index; 
    } 
    public String toString() { 
     return minValue + " " + midValue + " " + maxValue; 
    } 
    /** 
    * 
    * @return the bottom rect that will be used for intersection 
    */ 
    public Region getWedgeRegion() { 
     return mWedgeRegion; 
    } 

    private void buildPath() { 

     final RectF rect = new RectF(); 
     final RectF rect2 = new RectF(); 

     //Rectangles values 
     rect.set(this.x-this.InnerSize, this.y-this.InnerSize, this.x+this.InnerSize, this.y+this.InnerSize); 
     rect2.set(this.x-this.OuterSize, this.y-this.OuterSize, this.x+this.OuterSize, this.y+this.OuterSize); 

     this.reset(); 
     //this.moveTo(100, 100); 
     this.arcTo(rect2, StartArc, ArcWidth); 
     this.arcTo(rect, StartArc+ArcWidth, -ArcWidth); 

     this.close(); 

     mWedgeRegion.setPath(this, new Region(0,0,480,800)); 
    } 
} 

public boolean addMenuEntry(CircleViewBean menuEntry) { 
    mMenuEntries.add(menuEntry); 
    return true; 
} 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if(event.getAction() == MotionEvent.ACTION_UP){ 
     if(mOnCellTouchListener!=null && touchIndex >-1){ 
      int i=0; 
      for(Wedge day : mWedges) { 
       if(day.getWedgeRegion().getBounds().contains((int)event.getX(), (int)event.getY()) && touchIndex==i) { 
        mOnCellTouchListener.onTouch(mWedges[touchIndex]); 
        break; 
       } 
       i++; 
      } 
     } 
    }else if(event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE){ 
     int i=0; 
     for(Wedge day : mWedges) { 
      if(day.getWedgeRegion().getBounds().contains((int)event.getX(), (int)event.getY())) { 
       touchIndex = i; 
       setBackgroundResource(mMenuEntries.get(touchIndex).getIcon()); 
      } 
      i++; 
     } 
    } 
    return true; 
} 
public void setOnCellTouchListener(OnCellTouchListener p) { 
    mOnCellTouchListener = p; 
} 

public boolean onTouch(View v, MotionEvent event) { 
    return false; 
} 

}

+1

который является строкой 307 'CircleView.java'? – Raghunandan

+0

line no 307 is onTouchEvent :: MouseDown :: for (Wedge day: mWedges) { –

ответ

0

В конце концов я нашел мою ошибку в этом коде, что она работает в MDPI и htpi, а не в xxhdpi по причине

mWedgeRegion.setPath(this, new Region(0,0,480,800)); 

Связанное превышает размер круга, я имею в виду xxhdpi рисует круг 1000x1000, поэтому я сделал это тоже так (максимальные значения)

mWedgeRegion.setPath(this, new Region(0,0,720,1200)) 
1

Прежде всего, обратите внимание на линии 307. Подробнее как читать журналы сбоев, потому что он точно говорит о том, в какой строке находится авария, а затем не должно быть слишком сложно определить, что не так.

Не знаю, что это за линия, я думаю, что mWedges может быть пустым. в onTouch вы делаете for(Wedge day : mWedges), но не гарантируется, что это не так. Вы должны проверить, прежде чем это сделать, если оно равно null.

Вы помещаете его в ненулевое значение в determineWedges, но только при наличии не менее 1 mMenuEntries. Поэтому, когда нет записей, когда вы делаете onTouch, он сбой.

+0

Вы точно догадались о проблеме (mWedges). Но это работает на всех устройствах, кроме s4, и обратите внимание на 3 и несколько других устройств, которые имеют больше значений плотности. –

+0

Привет, вы можете перепроверить вопрос, потому что я отредактировал вопрос. bacuse моя фактическая проблема - это вычесть –