Nick Robertson
Nick Robertson

Reputation: 1047

ClassCastExcptionAndroid

MainActivity

   public class MainActivity extends Activity {
// Declare our Views, so we can access them later
private CheckUsernameEditText etUsername;
private EditText etPassword;
private EditText etPassword2;
private Button btnRegister;
private Button btnCancel;
private TextView lblUserStatus;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Set Activity Layout
    setContentView(R.layout.activity_main);

    // Get the EditText and Button References
    etUsername = (CheckUsernameEditText) findViewById(R.id.username);
    etPassword = (EditText) findViewById(R.id.password);
    etPassword2 = (EditText) findViewById(R.id.password2);
    btnRegister = (Button) findViewById(R.id.register_button);
    btnCancel = (Button) findViewById(R.id.cancel_button);
    lblUserStatus = (TextView) findViewById(R.id.userstatus);

    // Set our new Listener to the Username EditText view
    etUsername.setOnUsernameAvailableListener(new OnUsernameAvailableListener() {
                @Override
                public void onAvailableChecked(String username,
                        boolean available) {
                    // Handle the event here
                    if (!available) {
                        etUsername.setTextColor(Color.RED);
                        lblUserStatus
                                .setText(username
                                        + " is already taken. Please choose another login name.");
                    } else {
                        etUsername.setTextColor(Color.GREEN);
                        lblUserStatus.setText(username + " is available.");
                    }
                }
            });

    // Set Click Listener
    btnRegister.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // create Account
        }
    });
    btnCancel.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // Close the application
            finish();
        }
    });
}

The corresponding XML

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

           *
           *
<EditText
    android:id="@+id/username"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:singleLine="true" />

           *
           *
</LinearLayout>

CheckUsernameEditText

   public class CheckUsernameEditText extends EditText implements OnKeyListener {

OnUsernameAvailableListener onUsernameAvailableListener = null;
final private static String[] registeredUsers = new String[] {
        // This is just a fixed List for tutorial purposes
        // in a real application you'd check this server sided or inside the
        // database
        "tseng", "admin", "root", "joedoe", "john" };

   public CheckUsernameEditText(Context context) {
    super(context);
    // Set KeyListener to ourself
    this.setOnKeyListener(this);
}

public CheckUsernameEditText(Context context, AttributeSet attrs,
        int defStyle) {
    super(context, attrs, defStyle);
    // Set KeyListener to ourself
    this.setOnKeyListener(this);
}

public CheckUsernameEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
    // Set KeyListener to ourself
    this.setOnKeyListener(this);
}

// Allows the user to set an Listener and react to the event
public void setOnUsernameAvailableListener(
        OnUsernameAvailableListener listener) {
    onUsernameAvailableListener = listener;
}

// This function is called after the check was complete
private void OnUserChecked(String username, boolean available) {
    // Check if the Listener was set, otherwise we'll get an Exception when
    // we try to call it
    if (onUsernameAvailableListener != null) {
        // Only trigger the event, when we have a username
        if (!TextUtils.isEmpty(username)) {
            onUsernameAvailableListener.onAvailableChecked(username,
                    available);
        }
    }
}

@Override
public boolean onKey(View v, int keycode, KeyEvent keyevent) {
    // We only want to handle ACTION_UP events, when user releases a key
    if (keyevent.getAction() == KeyEvent.ACTION_DOWN)
        return false;

    boolean available = true;

    // Whenever a user press a key, check if the username is available
    String username = getText().toString().toLowerCase();
    if (!TextUtils.isEmpty(username)) {
        // Only perform check, if we have anything inside the EditText box
        for (int i = 0; i < registeredUsers.length; i++) {
            if (registeredUsers[i].equals(username)) {
                available = false;
                // Finish the loop, as the name is already taken
                break;
            }
        }
        // Trigger the Event and notify the user of our widget
        OnUserChecked(username, available);
        return false;
    }
    return false;
}

// Define our custom Listener interface
public interface OnUsernameAvailableListener {
    public abstract void onAvailableChecked(String username,
            boolean available);
}
   }

The problem is that I take a classclastexception. Because I declare on the xml the username as edittext and in the main code i declare it as CheckUsernameEditText. How I can solve this problem?Why the casting isn't working, especially now that the CheckUsernameEditText extends the EditText class?

Upvotes: 0

Views: 72

Answers (2)

Yevgeny Simkin
Yevgeny Simkin

Reputation: 28349

I believe if you have a custom View (in your case CheckUsernameEditText) you have to declare it as such in the XML... Remember that as @Sam points out you can't cast downward into a derived class, you can only cast upward into a parent class, so you can always cast your CheckUsernameEditText View up to an EditText (or just View) but you can't go the other way.

Upvotes: 2

Sam
Sam

Reputation: 86948

All CheckUsernameEditText objects are EditText objects,
but not all EditText objects are CheckUsernameEditText objects.

You should use your custom class in the XML:

<your.package.name.CheckUsernameEditText
    android:id="@+id/username"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:singleLine="true" />

Upvotes: 5

Related Questions