Android: ClassCastException для класса Button - PullRequest
0 голосов
/ 27 ноября 2011

У меня проблема с использованием моего пользовательского класса Button.

Я пытался изменить макет xml с <Button/> на <gButton/>, но это не сработало.

Я также пытался привести Button page1 = (gButton) findView.... в строке 15, но по какой-то причине это не работает (вы можете разыграть дочерний класс, верно?)

Ошибка, которую я получаю от 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>

Ответы [ 2 ]

2 голосов
/ 27 ноября 2011

Чтобы привести кнопку к 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);
    }

    ...

}

Тогда вы можете разыграть свою кнопку, как написали в своем вопросе. Но обратите внимание, что ваши конструкторы не будут называться .

1 голос
/ 27 ноября 2011

Button01 - кнопка, когда вы пытаетесь привести кнопку к кнопке. Вы не можете преобразовать объект в производный объект, если объект не является производным объектом.Например, у вас есть базовый класс с именем Product, и он расширен за счет CartItem.

Теперь представьте, что у Product есть и другие производные классы, помимо CartItem, такие как PhoneItem и MailOrderItem.

Вы не можете сделать это: Product prod = new Product ();CartItem cart = (CartItem) prod.

Почему?

Поскольку «prod» не является элементом CartItem больше, чем PhoneItem и MailOrderItem.Вы создали его как элемент «Продукт», и он ВСЕГДА будет элементом «Продукт», независимо от того, как вы пытаетесь его разыграть.Вы можете заставить его быть MailItem или PhoneItem.

Однако, если вы сделали следующее, это сработало бы: CartItem cart = new CartItem ();Product prod = (Продукт) корзина;CartItem cart2 = (CartItem) prod;

Или

Product prod = new CartItem ();// (неявное приведение к продукту) CartItem cart2 = (CartItem) prod;

Почему это работает?Потому что CartItem также является продуктом (хотя не все продукты являются элементами корзины).Даже если вы добавили его в продукт, он все равно будет и всегда будет элементом CartItem.Единственное отличие состоит в том, что текущий дескриптор CartItem является дескриптором Product, предоставляя вам более ограниченный доступ ко всем функциям, которые может иметь ваш CartItem.Когда вы пытаетесь преобразовать его обратно из Product в CartItem, подсистема выполнения говорит: «Эй, могу ли я привести этот целевой объект к нужному типу?»В этот момент он смотрит на целевой объект и обнаруживает, что этот объект, хотя в настоящее время на него ссылаются как на Продукт, ДЕЙСТВИТЕЛЬНО является CartItem, который был отклонен.Следовательно, безопасно вернуть его обратно в CartItem, каким он был изначально.Еще раз, смысл в том, что после того, как вы создали его как CartItem, он ВСЕГДА является CartItem, независимо от того, сколько раз вы его повышали или понижали.Однако в приведенном вами примере ваш товар никогда не был чем-то большим, чем простой товар.Это никогда не был CartItem с самого начала, и его нельзя было кастовать.

...