0

ホイール ビュー (CircleView) はほとんどのデバイスで正常に動作していますが、このエラーは S4 および Note 3 デバイスで発生しています。

タッチは差し引かれていますが、weidgetregion に該当しません。

false - 1 は true でなければなりません - 1

地域ログは次のとおりです。

ここに画像の説明を入力

私のサークルビューコードは

 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;
}
}
4

2 に答える 2

1

まず、307 行を見てください。クラッシュ ログの読み方を学んでください。なぜなら、クラッシュが発生した行が正確に示されているからです。何が問題なのかを判断するのは難しくありません。

それがどの行なのかわからないので、それはmWedgesnullかもしれません。onTouch で行いますがfor(Wedge day : mWedges)、null でないことは保証されません。null であるかどうかを確認する必要があります。

null 以外の値に入れますdetermineWedgesが、少なくとも 1 がある場合に限りmMenuEntriesます。そのため、onTouch を実行するときにエントリがない場合、クラッシュします。

于 2013-11-13T08:10:24.980 に答える
0

最後に、このコードで、xxhdpi ではなく mdpi と htpi で動作しているという間違いを見つけました。理由は次のとおりです。

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

境界が円のサイズを超えています。つまり、xxhdpi は 1000x1000 の値で円を描くので、これもこのようにしました (最大値)

mWedgeRegion.setPath( this, new Region(0,0,720,1200) )
于 2013-11-29T06:34:10.427 に答える