如何在 Android 的自定义视图中显示 ImageView

Posted

技术标签:

【中文标题】如何在 Android 的自定义视图中显示 ImageView【英文标题】:How to display an ImageView in a custom view in Android 【发布时间】:2010-09-15 04:03:26 【问题描述】:

我有一个在按下按钮时调用自定义视图的活动。自定义视图运行良好,直到我尝试向其添加 ImageView。我已经在我的主要活动中使用 setContentView 调用的 xml 中尝试过这个:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_
android:layout_
>

<com.mypackage.mycustomview android:id="@+id/fbv"
    android:layout_
    android:layout_
    >

        <ImageView android:id="@+id/pistolView"
              android:src="@drawable/pistol"
              android:layout_
              android:layout_/> 

</com.mypackage.mycustomview> 

当我单击主活动中启动此自定义视图的按钮时,我得到了 ClassCastException。我要做的就是在我的自定义视图中制作一个可点击的图像。

如果我把它放在我的主要活动和 main.xml 中,ImageView 显示正常并点击:

<Button android:id="@+id/button"
        android:layout_
        android:layout_
        android:text="Play Vs CPU" />


        <ImageView android:id="@+id/pistolView"
              android:src="@drawable/pistol"
              android:layout_
              android:layout_/> 

我真的不擅长 android 中的 xml 布局,所以我不知道我在这里缺少什么。非常感谢任何帮助。

这是 mycustomview 类:

       package com.mypackage;

    import java.util.ArrayList;

    import android.app.Activity;
    import android.content.Context;
    import android.content.res.Resources;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Point;
    import android.graphics.drawable.Drawable;
    import android.os.Handler;
    import android.os.Message;
    import android.text.format.Time;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.TextView;

    public class mycustomview extends View
            final Paint mPaint = new Paint();
            private Context mContext;
            private Resources res = getResources();
            private GameControls _controls;
            private GameJoystick _joystick;
            private GameJoystick Rjoystick;
            Paint paint = new Paint();
            private long currTime;
            private Time time = new Time();
            private Hero mHero;
            private Gun mGun;
            private Bitmap heroBit;
            private float possibleX;
            private float possibleY;
            private float lazerX;
            private float lazerY;
            public ArrayList<Wall> wallList = new ArrayList<Wall>();
            private Canvas mCanvas;
            private Bitmap splat;
            private Bitmap pistolBit;
            private Bitmap building;
            private ImageView pistol;
            private int i = 0;
            private int w = 0;
            Wall wall;

            private RefreshHandler mRedrawHandler = new RefreshHandler();

        class RefreshHandler extends Handler 

            @Override
            public void handleMessage(Message msg) 
                    //Log.d("3", "here3");
                FanBoyView.this.update();
                FanBoyView.this.invalidate();
            

            public void sleep(long delayMillis) 
                    this.removeMessages(0);
                sendMessageDelayed(obtainMessage(0), delayMillis);
            
        ;


        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) 
            //Log.d("-------------------->code", Integer.toString(keyCode));
            if (keyCode == KeyEvent.KEYCODE_FOCUS) 
                    //Log.d("-------------------->cam", "pressed");
              fireGun();
              return true;
            
            return false;
         

            public mycustomview(Context context, AttributeSet a) 
                    super(context, a);
                    mContext = context;

                    time.setToNow();
                    currTime = time.toMillis(false);
                    this.setFocusable(true);
                    this.setFocusableInTouchMode(true);
                    this.requestFocus();

                    final Paint paint = mPaint;
            paint.setColor(0xffffffff);
            paint.setAntiAlias(true);
            paint.setStrokeWidth(1);
            paint.setStrokeCap(Paint.Cap.ROUND);
            paint.setStyle(Paint.Style.STROKE);

                    setFocusable(true);

                    _joystick = new GameJoystick(mContext.getResources());
                    Rjoystick = new GameJoystick(mContext.getResources());
                    _controls = new GameControls();
                    setOnTouchListener(_controls);

                    Drawable bg = res.getDrawable(R.drawable.street);
                    this.setBackgroundDrawable(bg);
            setWalls();
            

            @Override
            protected void  onFinishInflate()
                    //ImageView img = (ImageView) findViewById(R.id.pistolView);
                    /*img.setOnClickListener(new OnClickListener() 
                        public void onClick(View v) 
                            Log.d("pistol","clicked");
                        
                    );*/
            
...

【问题讨论】:

你能粘贴 mycustomview 类吗? 对不起,这是我第一次在这里发帖,我找不到编辑的地方...这是课程的顶部,我已经更改了课程名称并删除了一些隐藏的代码游戏的性质,但我目前并没有尝试在代码中的任何地方引用 Imageview,您可以看到我在 onFinishInflate() 中注释掉了我尝试引用它的位置: bleh,我无法将课程放入 cmets... 我会弄清楚如何编辑我的帖子 好的,我把它加到帖子底部了。 【参考方案1】:

首先,正如 Lee Chou 所说,您需要让您的类从视图组扩展,例如相对布局、线性布局。

public class CustomView extends RelativeLayout 
Context context;
private ImageView imgView;
private TextView lblView;
LayoutInflater inflater;
/*Do I need all three constructors for an Android custom view?*/

//if you add your View from xml and also spcify the android:style attribute like : <com.mypack.MyView style="@styles/MyCustomStyle" />
//you will also need the first constructor public MyView(Context context, AttributeSet attrs,int defStyle)
public CustomView(Context context, AttributeSet attrs, int defStyle) 
    super(context, attrs, defStyle);
    this.context = context;
    init();

//you will need the constructor public MyView(Context context, AttributeSet attrs), otherwise you will get an Exception when Android tries to inflate your View.
public CustomView(Context context, AttributeSet attrs) 
    super(context, attrs);
    this.context = context;
    init();


//The third constructor is usually used when you extend a style and customize it, and then you would like to set that style to a given View in your layouts
public CustomView(Context context) 
    super(context);
    this.context = context;
    init();




public void init()

    LayoutInflater.from(context).inflate(R.layout.widget_customview_main, this);
    lblView =(TextView) findViewById(R.id.lblView);
    imgView = (ImageView) findViewById(R.id.imgView);

这里是 xml R.layout.widget_customview_main

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
class = "com.ikolmobile.satso."
android:layout_
android:layout_ >

<TextView
    android:id="@+id/lblView"
    android:layout_
    android:layout_
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="60dp"
    android:text="My Custom View" />

<ImageView
    android:id="@+id/imgView"
    android:layout_
    android:layout_
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="31dp"
    android:src="@drawable/abc_ab_bottom_solid_dark_holo" />

</RelativeLayout>

【讨论】:

【参考方案2】:

你得到一个 ClassCastException 因为一个视图不能有子视图,添加子视图是为了 ViewGroups http://developer.android.com/reference/android/view/ViewGroup.html

ImageView 和 TextView 是普通视图,而 LinearLayout 和 ListView 是视图组。因此,后者可以有子视图,而前者不能。

您可以只扩展 ViewGroup 而不是 View 并进行必要的调整,但在我看来您应该使用相对布局,将自定义视图放在底部,并将图像视图放在上面。

【讨论】:

以上是关于如何在 Android 的自定义视图中显示 ImageView的主要内容,如果未能解决你的问题,请参考以下文章

如何在快速关闭第二个视图控制器后启用带有视图的自定义视图控制器

如何将最新数据附加到android中的自定义基本适配器列表视图?

按钮未显示在android的自定义列表视图中

当按下 menuItem 以在 android 中显示用于列表视图的自定义适配器时,应用程序崩溃

如何在android的自定义视图中访问按钮的setOnClickListener?

为啥 Android Studio 设计器显示我的自定义视图嵌套在自身内部,而它不是