2013-05-27 60 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)。仔細檢查你的項目設置。