我开始使用Intellij Idea开发Android应用程序,因为它是去年的首选IDE。 我用两个IDE的两个致命错误粉碎了我的脸: Intellij Idea 1.我创建了自定义视图:
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();
}
}
然后,我试图在Idea中看到UI Designer中的结果:
<?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)的同时,一切都还可以!
然后,我决定使用Eclipse进行开发。我安装它并尝试构建我的项目。 但Eclipse告诉我,我使用的是java 1.7,Android需要5.0或6.0。 一些谷歌搜索说,我不能使用jdk 1.7,因为在Android中还没有支持它,但是想法与android和jdk 1.7一起使用!!
有些问题:
更新的答案: 因为我声名狼借,我无法回答自己,所以回答问题: 我的自定义视图位于com.example.customview.ImageCustomView包中。 当我尝试在其他项目中使用它时,我将它放在com.example中并且它工作,而不是重构此视图以命名ImageCustomView,将它移动到com.example并再次工作正常。 我试图重复我的错误 - 但是在所有包中都没有成功,它有不同的名称。 谢谢!
更新更新: 我重复我的错误。 我添加Geasture监听器,使用AttributeSet删除构造函数,然后我再次获得NPE。但是当我放弃所有的变化时 - NPE不会消失。所以我现在不知道什么是错的,所以我需要一些版本或答案。我再次修复它:我将自定义视图类移动到其他包中。
更多信息: 当我删除构造函数时出现NPE:
public ImageCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(R.styleable.ImageCustomView);
a.recycle();
}
即使我把它添加回来 - NPE也不会消失,但是在这个类的重构名称之后 - 它有效。所以,我的版本是在重构之后刷新预编译类,因为预编译文件是Intellij Idea的功能之一。
经过一些过期后,我有了新的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 :(得分:1)
您的代码对我来说很好(IntelliJ IDEA又称Android Studio)。仔细检查您的项目设置。
答案 1 :(得分:0)
Android Studio保存我的屁股。它告诉我错误。所以,关于Eclipse和JDK 1.7我没有答案,但关于Custom视图的答案是:
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
onDraw方法必须包含检查null的整个数据:
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方法中。