【问题标题】:Android: ClassCastException for Button classAndroid:按钮类的 ClassCastException
【发布时间】:2011-11-27 16:08:43
【问题描述】:

我在使用自定义 Button 类时遇到问题。

我尝试将 xml 布局从 <Button/> 更改为 <gButton/>,但没有成功。

我也尝试过在第 15 行投射 Button page1 = (gButton) findView....,但由于某种原因不起作用(你可以投射子类,对吗?)

我不断从 LogCat 得到的错误是:

Caused by: java.lang.ClassCastException: android.widget.Button
     at flash.tut.ButtonPage.onCreate(ButtonPage.java:15)

非常感谢任何帮助。

这是我的按钮视图:

public class ButtonPage extends Activity{
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.button);

         gButton page1 = (gButton) findViewById(R.id.Button01); //<---LogCat: ClassCastException
         page1.setOnClickListener(new View.OnClickListener() {
              public void onClick(View view) {
                   Intent mI = new Intent(view.getContext(), Page1.class);
                   startActivityForResult(mI, 0);
              }
         });
     }
}

还有我的 gButton 扩展了按钮类:

public class gButton extends Button{
    private static Context con;

    public gButton(){this("Blank");}

    public gButton(String name){
        this(name, R.color.text_color);
    }

    public gButton(String name, int col) {
        this(name, col, con);
    }

    public gButton(String name, int col, Context context) {
        super(context);   //necessary context...dont know why.
        setBackgroundResource(R.drawable.icon);
        setTextColor(col);
        setText(name);
        setTextSize(14);
    }
}

最后是我的 xml 布局:

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

 <Button android:text="Page 1"
        android:id="@+id/Button01"
        android:layout_width="250px"
        android:textSize="18px"
        android:layout_height="55px">
    </Button>

 <Button android:text="Page 2"
        android:id="@+id/Button02"
        android:layout_width="250px"
      android:textSize="18px"
        android:layout_height="55px">
    </Button>

 <Button android:text="Page 3"
        android:id="@+id/Button03"
        android:layout_width="250px"
      android:textSize="18px"
        android:layout_height="55px">
    </Button>

<Button android:text="ListView Page"
        android:id="@+id/ButtonList"
        android:layout_width="250px"
      android:textSize="18px"
        android:layout_height="55px">
    </Button>

</LinearLayout>

【问题讨论】:

    标签: java android classcastexception inheritance


    【解决方案1】:

    要将按钮转换为 gButton,您应该像这样声明按钮:

    <com.example.gButton 
        android:text="Page 3"
        android:id="@+id/Button03"
        android:layout_width="250px"
        android:textSize="18px"
        android:layout_height="55px">
    </com.example.gButton>
    

    但你应该把你的包而不是“com.example”

    你的 gButton 类必须有下一个构造函数:

    package com.example;
    
    public class gButton extends Button{
        ...
    
        public gButton(Context context, AttributeSet attrs) { // this constructor will be called by inflater for creating object instance
            super(context, attrs);
        }
    
        ...
    

    }

    然后,您可以按照您在问题中所写的方式投射您的按钮。但请注意,不会调用您的构造函数

    【讨论】:

    • 谢谢,非常有用和明确的答案。明天我会在确认答案之前试试这个。
    【解决方案2】:

    当您尝试将按钮转换为 gbutton 时,Button01 是一个按钮。您不能将对象转换为派生对象,除非该对象是派​​生对象。例如,您有一个名为 Product 的基类,它由 CartItem 扩展。

    现在,还假设 Product 具有除 CartItem 之外的其他派生类,例如 PhoneItem 和 MailOrderItem。

    你不能这样做: 产品 prod = new Product(); CartItem 购物车 = (CartItem)prod.

    为什么?

    因为“prod”不是一个 CartItem,而是一个 PhoneItem 和一个 MailOrderItem。您将其创建为“产品”项目,无论您如何尝试投射它,它都将始终是产品项目。您可以强制它为 MailItem 或 PhoneItem。

    但是,如果您执行以下操作,它将起作用: CartItem 购物车 = 新 CartItem(); 产品 prod =(产品)购物车; CartItem cart2 = (CartItem)prod;

    或者

    产品 prod = new CartItem(); //(隐式转换为产品) CartItem cart2 = (CartItem)prod;

    为什么会这样?因为 CartItem 也是 Product(尽管并非所有产品都是购物车项目)。即使您将其转换为 Product,它仍然是并且将永远是 CartItem。唯一的区别是 CartItem 的当前句柄恰好是 Product 句柄,使您可以更有限地访问 CartItem 可以具有的所有功能。当您尝试将其从 Product 转换回 CartItem 时,运行时引擎会说:“嘿,我可以将此目标对象转换为他们想要的类型吗?”此时,它会查看目标对象并发现该对象虽然当前被作为产品引用,但实际上是已被向上转换的 CartItem。因此,将它转换回原来的 CartItem 是安全的。再次强调,一旦您将其创建为 CartItem,无论您向上或向下投射多少次,它始终是 CartItem。但是,在您给出的示例中,您的产品项目只不过是一个简单的产品。它一开始就不是 CartItem,也不能被投射。

    【讨论】:

    • 所以你是说我不可能实现我的自定义按钮类,因为完全投射是行不通的?
    • 不,他是说将 Button 转换为 gButton 是不可能的。 ;) 尝试在布局中指定 gButtons 而不是 Buttons。有两种方法可以做到这一点:完全限定 XML 元素中的包名称,例如: 或使用 你将需要标准 View 构造函数,它接受参数 (Context, AttributeSet) 以便在 XML 布局中使用它。
    猜你喜欢
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多