2013-05-27 66 views
1

我开始使用Intellij Idea开发Android应用程序,因为它是去年的首选IDE。 我砸我的脸与两个IDE两个致命错误: IntelliJ IDEA的 1.我创建的自定义视图:Intellij Idea和Eclipse以及JDK 7和Android

public class ImageOverlayView extends View implements View.OnTouchListener { 

private static final String TAG = "ImageOverlayView"; 
private Bitmap image; 

private float x, y, sX, sY; 

private final Paint paint = new Paint(); 
private float scaleFactor; 

private int getScaledWidth() 
{ 
    return (int)(image.getWidth() * scaleFactor); 
} 

private int getScaledHeight() 
{ 
    return (int)(image.getHeight() * scaleFactor); 
} 

public ImageOverlayView(Context context) { 
    super(context); 
} 

public ImageOverlayView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    TypedArray a = context.obtainStyledAttributes(R.styleable.ImageOverlayView); 
    this.setOnTouchListener(this); 
} 

public void setImage(Bitmap bm) { 
    image = bm; 
    invalidate(); 
} 

public void setDrawable(Drawable drawable) { 
    image = BitmapUtils.drawableToBitmap(drawable); 
    invalidate(); 
} 

@Override 
public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    if (canvas != null && image != null) { 
     canvas.drawBitmap(image, null, paint); 
    } else { 
     Log.d(TAG, "Canvas is NULL"); 
    } 
} 

@Override 
public boolean onTouch(View view, MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_MOVE: { 
      sX = event.getX(); 
      sY = event.getY(); 

      break; 
     } 

    } 
    return super.onTouchEvent(event); 
} 

public void loadImageBitmap(String fileName) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inPreferredConfig = Bitmap.Config.ARGB_8888; 

    image = BitmapFactory.decodeFile(fileName, options); 
    if (image == null) { 
     throw new NullPointerException("The image can't be decoded."); 
    } 

    scaleFactor = 1; 

    // center image on the screen 
    int width = getWidth(); 
    int height = getHeight(); 
    if ((width != 0) || (height != 0)) { 
     int scrollX = (image.getWidth() < width ? -(width - image.getWidth())/2 : image.getWidth()/2); 
     int scrollY = (image.getHeight() < height ? -(height - image.getHeight())/2 : image.getHeight()/2); 
     scrollTo(scrollX, scrollY); 
    } 
    invalidate(); 
} 

public void loadImageDrawable(int resourceId) { 
    Resources resources = getResources(); 
    Drawable drawable = resources.getDrawable(resourceId); 
    image = BitmapUtils.drawableToBitmap(drawable); 
    invalidate(); 
} 
} 

以后,我想看看导致理念UI设计师:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android"> 

<ru.lookmyway.customview.ImageOverlayView 
    android:id="@+id/imageOverlayView1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" /> 

</LinearLayout> 

与理念给了我NPE:

java.lang.NullPointerException 
at ru.lookmyway.customview.ImageOverlayView.onDraw(ImageOverlayView.java:65) 
at android.view.View.draw(View.java:13712) 
at android.view.View.draw(View.java:13596) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13594) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13594) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13715) 
at android.view.View.draw(View.java:13596) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13715) 
at com.android.layoutlib.bridge.impl.RenderSessionImpl.render(RenderSessionImpl.java:570) 
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:334) 
at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:325) 
at org.jetbrains.android.uipreview.RenderService.createRenderSession(RenderService.java:127) 
at org.jetbrains.android.uipreview.RenderUtil.renderLayout(RenderUtil.java:154) 
at com.intellij.android.designer.designSurface.AndroidDesignerEditorPanel$8.run(AndroidDesignerEditorPanel.java:346) 
at com.intellij.util.ui.update.MergingUpdateQueue.execute(MergingUpdateQueue.java:320) 
at com.intellij.util.ui.update.MergingUpdateQueue.execute(MergingUpdateQueue.java:310) 
at com.intellij.util.ui.update.MergingUpdateQueue$2.run(MergingUpdateQueue.java:254) 
at com.intellij.util.ui.update.MergingUpdateQueue.flush(MergingUpdateQueue.java:269) 
at com.intellij.util.ui.update.MergingUpdateQueue.flush(MergingUpdateQueue.java:227) 
at com.intellij.util.ui.update.MergingUpdateQueue.run(MergingUpdateQueue.java:217) 
at com.intellij.util.Alarm$Request$1.run(Alarm.java:289) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:722) 

但在Eclipse中的同一时间(JUNO)一切OK!

比我决定用Eclipse开发。我安装了它并尝试构建我的项目。但是Eclipse说我说我使用java 1.7,而Android想要5.0或​​6.0。 一些谷歌搜索说,我不能使用JDK 1.7的原因有没有在Android的支持,但理念工作正常与Android和JDK的1.7!

一些问题:

  1. 为什么我在Eclipse中工作正常的自定义视图,但想法给我NPE?
  2. 为什么Eclipse无法使用jdk 1.7,但Idea与 jdk 1.7可以正常工作?
  3. 我该怎么办? :D
  4. 我必须选择哪个IDE?

修订答: 因为我有小的声誉,我不能回答我自己,所以在问题答案: 我的自定义视图是包com.example.customview.ImageCustomView。 当我尝试在其他项目中使用它,我把它放在com.example和它的工作,比我重构这个视图名为ImageCustomView,移动它的com.example并再次工作正常。 我试图重复我的错误 - 但在所有包中都不成功,但它的工作方式不同。 谢谢!


更新更新: 我重复我的错误。 我添加Geasture监听器,删除AttributeSet的构造函数,我又得到了NPE。但是当我放弃所有的改变 - NPE不会消失。所以我现在不知道什么是错的,所以我需要一些版本或答案。我再次修复它:我在其他包中移动我的自定义视图类。


更多信息:

public ImageCustomView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    TypedArray a = context.obtainStyledAttributes(R.styleable.ImageCustomView); 
    a.recycle(); 

    } 

而且它即使我添加回来 - NPE不会消失,但在此之后类的重构名:当我在构造函数中删除 NPE出现- 有用。所以,我的这个版本是在重构Idea之后刷新预编译的类,因此它是Intellij Idea的一个特性。

一些expirements后,我已经有了新的NPE:

java.lang.NullPointerException 
at android.graphics.Canvas.throwIfRecycled(Canvas.java:1025) 
at android.graphics.Canvas.drawBitmap(Canvas.java:1065) 
at ru.lookmyway.ImageCustomView.onDraw(ImageCustomView.java:63) 
at android.view.View.draw(View.java:13712) 
at android.view.View.draw(View.java:13596) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13594) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13594) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13715) 
at android.view.View.draw(View.java:13596) 
at android.view.ViewGroup.drawChild(ViewGroup.java:2928) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797) 
at android.view.View.draw(View.java:13715) 
at com.android.layoutlib.bridge.impl.RenderSessionImpl.render(RenderSessionImpl.java:570) 
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:334) 
at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:325) 
at org.jetbrains.android.uipreview.RenderService.createRenderSession(RenderService.java:127) 
at org.jetbrains.android.uipreview.RenderUtil.renderLayout(RenderUtil.java:154) 
at com.intellij.android.designer.designSurface.AndroidDesignerEditorPanel$8.run(AndroidDesignerEditorPanel.java:346) 
at com.intellij.util.ui.update.MergingUpdateQueue.execute(MergingUpdateQueue.java:320) 
at com.intellij.util.ui.update.MergingUpdateQueue.execute(MergingUpdateQueue.java:310) 
at com.intellij.util.ui.update.MergingUpdateQueue$2.run(MergingUpdateQueue.java:254) 
at com.intellij.util.ui.update.MergingUpdateQueue.flush(MergingUpdateQueue.java:269) 
at com.intellij.util.ui.update.MergingUpdateQueue.flush(MergingUpdateQueue.java:227) 
at com.intellij.util.ui.update.MergingUpdateQueue.run(MergingUpdateQueue.java:217) 
at com.intellij.util.Alarm$Request$1.run(Alarm.java:289) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:722) 

更新自定义视图:

public class ImageCustomView extends View implements View.OnTouchListener { 

private static final String TAG = "ImageCustomView"; 
private Bitmap image; 

private float x, y, sX, sY; 

private final Paint paint = new Paint(); 
private float scaleFactor; 
private GestureDetector gestureDetector; 

private int getScaledWidth() 
{ 
    return (int)(image.getWidth() * scaleFactor); 
} 

private int getScaledHeight() 
{ 
    return (int)(image.getHeight() * scaleFactor); 
} 

public ImageCustomView(Context context) { 
    super(context); 
    this.setOnTouchListener(this); 
    paint.setFilterBitmap(true); 
    paint.setDither(false); 
    gestureDetector = new GestureDetector(context, new MyGestureListener()); 
} 

public void setImage(Bitmap bm) { 
    image = bm; 
    invalidate(); 
} 

public void setDrawable(Drawable drawable) { 
    image = BitmapUtils.drawableToBitmap(drawable); 
    invalidate(); 
} 

@Override 
public void onDraw(Canvas canvas) { 
    canvas.drawBitmap(image, 0, 0, paint); 
} 

@Override 
public boolean onTouch(View view, MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_MOVE: { 
      sX = event.getX(); 
      sY = event.getY(); 
      Log.d(TAG, "x: " + sX + " y: " + sY); 
      break; 
     } 

    } 
    return super.onTouchEvent(event); 
} 

private class MyGestureListener extends GestureDetector.SimpleOnGestureListener 
{ 
    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) 
    { 
     scrollBy((int)distanceX, (int)distanceY); 
     return true; 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
    { 
     int fixedScrollX = 0, fixedScrollY = 0; 
     int maxScrollX = getScaledWidth(), maxScrollY = getScaledHeight(); 

     if (getScaledWidth() < getWidth()) 
     { 
      fixedScrollX = -(getWidth() - getScaledWidth())/2; 
      maxScrollX = fixedScrollX + getScaledWidth(); 
     } 

     if (getScaledHeight() < getHeight()) 
     { 
      fixedScrollY = -(getHeight() - getScaledHeight())/2; 
      maxScrollY = fixedScrollY + getScaledHeight(); 
     } 

     boolean scrollBeyondImage = (fixedScrollX < 0) || (fixedScrollX > maxScrollX) || (fixedScrollY < 0) || (fixedScrollY > maxScrollY); 
     return !scrollBeyondImage; 

    } 
} 

public void loadImageBitmap(String fileName) { 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inPreferredConfig = Bitmap.Config.ARGB_8888; 

    image = BitmapFactory.decodeFile(fileName, options); 
    if (image == null) { 
     throw new NullPointerException("The image can't be decoded."); 
    } 

    scaleFactor = 1; 

    // center image on the screen 
    int width = getWidth(); 
    int height = getHeight(); 
    if ((width != 0) || (height != 0)) { 
     int scrollX = (image.getWidth() < width ? -(width - image.getWidth())/2 : image.getWidth()/2); 
     int scrollY = (image.getHeight() < height ? -(height - image.getHeight())/2 : image.getHeight()/2); 
     scrollTo(scrollX, scrollY); 
    } 
    invalidate(); 
} 

public void loadImageDrawable(int resourceId) { 
    Resources resources = getResources(); 
    Drawable drawable = resources.getDrawable(resourceId); 
    image = BitmapUtils.drawableToBitmap(drawable); 
    invalidate(); 
} 

}

我删除第二construcor - 有NPE,类重构的名字 - 得到的作品,添加了一些变化 - 得到NPE(关于画布,第二NPE)重构类的名称(或地点) - 得到的作品...我不知道... 一个更多的细节 - 这种观点没有点击触摸我的图片,断点不会进入方法onTouch ...可能是关键信息。 我的目标是在屏幕上移动图像,并重新绘制图像,我用手指放置图像。

+0

我必须检查项目设置?我使用Google API 2.3.3和Google服务库作为项目模块。就这样。 – dikkini

+0

Android Studio给了我相同的结果 - NPE在设计师的布局。 Intellij Idea之前的版本 - 相同。 – dikkini

+0

我检查了其他项目 - 一切工作正常!它可能是什么? – dikkini

回答

0

Android Studio保存我的屁股。它显示我的错误。所以,关于Eclipse和JDK 1.7我没有答案,但对自定义视图的答案是:

  • 自定义视图需要两个默认构造函数:
public CustomView(Context context) { 
     super(context); 
    } 

    public CustomView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 
  • 的onDraw方法必须包含检查整个数据为空:

    if (bitmap == null) { 
        paint.setStyle(Paint.Style.FILL); 
        paint.setColor(Color.CYAN); 
        canvas.drawRect(mImagePosition, paint); 
        return; 
    } 
    Rect rect = new Rect(0, 0, this.getWidth(), this.getHeight()); 
    canvas.drawBitmap(bitmap, rect, mImagePosition, null); 
    
  • 有没有必要做:

    super.onDraw(canvas); 
    

    在onDraw方法。

1

你的代码对我来说工作得很好(IntelliJ IDEA aka Android Studio)。仔细检查你的项目设置。