关山初度尘未洗,策马扬鞭再奋蹄!这篇文章主要讲述android:canvas触摸不在s4中工作相关的知识,希望能为你提供帮助。
【android(canvas触摸不在s4中工作)】帮我解决这个问题。轮视图(CircleView)在主要设备中运行良好,但此错误来自s4和note 3设备。
触摸被扣除,但不属于weidgetregion。
假 -1必须是真的 -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 imagesthis.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 = https://www.songbingjia.com/android/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;
}
}
答案首先,看看第307行。了解如何阅读崩溃日志,因为它确切地说明崩溃是在什么线上,然后它也不应该太难确定什么是错误的。
不知道它是什么线,我猜
mWedges
可能是null。在onTouch中你做for(Wedge day : mWedges)
但不保证那里不是null。如果它为空,您应该在执行此操作之前进行检查。你把它放在
determineWedges
中的非空值,但只有当至少有1个mMenuEntries
时。因此,当你执行onTouch时没有条目时它会崩溃。另一答案最后我发现我在这段代码中的错误是它在mdpi和htpi中工作而不是在xxhdpi中,原因是
mWedgeRegion.setPath( this, new Region(0,0,480,800) );
绑定超过圆的大小,我的意思是xxhdpi绘制一个1000x1000值的圆,所以我也这样做(最大值)
mWedgeRegion.setPath( this, new Region(0,0,720,1200) )
推荐阅读
- Android NullPointerException(println需要一条消息)
- 如何在Symfony 1.4中为表单禁用CSRF保护/验证
- 如何从Symfony 1.4中的任务(控制台命令)访问数据库(Doctrine连接)
- 低代码与自定义软件(哪个是更好的选择(什么时候?))
- 如何使用CLI从Subversion存储库中列出目录
- 如何使用Dompdf在Symfony 4中从HTML创建PDF
- 中间人攻击的详细指南
- 如何解决TCPDF错误(setPage()函数上的页码错误:0)
- 如何确定是否使用WinForms中的C#启用Windows更新