Shows up fine in the graphical layout and then when I launch in the emulator it does this
I'm thinking it may be an issue with inflating the view or something I'm not sure I'm new to android. Please help I've been trying to solve this stupid layout problem for hours. Thanks
package com.keyconsultant.parse.logintutorial;
import java.util.Locale;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import com.keyconsultant.parse.logintutorial.error.UnknownErrorDialogFactory;
import com.keyconsultant.parse.logintutorial.fragment.BaseFragment;
import com.keyconsultant.parse.logintutorial.model.user.UserManager;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.AuthenticateUserErrorEvent;
import com.parse.ParseException;
import com.squareup.otto.Subscribe;
/**
* Fragment for logging in. Includes button for loading the Create account view.
*
* @author Trey Robinson
*
*/
public class LoginFragment extends BaseFragment {
public static final String EXTRA_USERNAME = "com.keyconsultant.parse.logintutorial.activity.extra.USERNAME";
public static final String EXTRA_PASSWORD = "com.keyconsultant.parse.logintutorial.activity.extra.PASSWORD";
// UI references.
private EditText mUserNameEditText;
private EditText mPasswordEditText;
/**
* Factory method for creating new fragments
* @return
*/
public static LoginFragment newInstance(){
return new LoginFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login, container, false);
mUserNameEditText = (EditText) view.findViewById(R.id.username);
mPasswordEditText = (EditText) view.findViewById(R.id.password);
mPasswordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
view.findViewById(R.id.sign_in_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
view.findViewById(R.id.register_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
createAccount();
}
});
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null){
mUserNameEditText.setText(savedInstanceState.getString(EXTRA_USERNAME));
mPasswordEditText.setText(savedInstanceState.getString(EXTRA_PASSWORD));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_USERNAME, mUserNameEditText.getText().toString());
outState.putString(EXTRA_PASSWORD, mPasswordEditText.getText().toString());
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin() {
clearErrors();
// Store values at the time of the login attempt.
String username = mUserNameEditText.getText().toString();
String password = mPasswordEditText.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password.
if (TextUtils.isEmpty(password)) {
mPasswordEditText.setError(getString(R.string.error_field_required));
focusView = mPasswordEditText;
cancel = true;
} else if (password.length() < 4) {
mPasswordEditText.setError(getString(R.string.error_invalid_password));
focusView =mPasswordEditText;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(username)) {
mUserNameEditText.setError(getString(R.string.error_field_required));
focusView = mUserNameEditText;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// perform the user login attempt.
UserManager.getInstance().authenticate(username.toLowerCase(Locale.getDefault()), password);
}
}
/**
* Load the create account view.
*/
private void createAccount(){
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.replace(((ViewGroup)getView().getParent()).getId(), CreateAccountFragment.newInstance());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
/**
* Remove all edit text errors
*/
private void clearErrors(){
mUserNameEditText.setError(null);
mPasswordEditText.setError(null);
}
@Subscribe
public void onSignInError(AuthenticateUserErrorEvent event){
clearErrors();
switch (event.getErrorCode()) {
case ParseException.OBJECT_NOT_FOUND:
mPasswordEditText.setError(getString(R.string.error_incorrect_password));
mPasswordEditText.requestFocus();
break;
default:
UnknownErrorDialogFactory.createUnknownErrorDialog(this.getActivity()).show();
break;
}
}
}
HERE IS THE XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/LoginFormContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f1c40f"
android:orientation="vertical" >
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/usernameHint"
android:maxLines="1"
android:singleLine="true" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="@+id/login"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
<Button
android:id="@+id/sign_in_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in_short" />
<TextView
android:id="@+id/orTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:text="@string/orText" />
<Button
android:id="@+id/register_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="16dp"
android:text="@string/action_register" />
</LinearLayout>
Here is the basefragment class
package com.keyconsultant.parse.logintutorial.fragment;
import com.squareup.otto.BusProvider;
import android.support.v4.app.Fragment;
/**
* Fragment class that resolves basic service bus requirement (Register, deregister, Event Posting)
*
* @author Trey Robinson
*
*/
public class BaseFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
BusProvider.getInstance().register(this);
}
@Override
public void onPause() {
/**fragment must be removed from the service bus in onPause or an error will occur
when the bus attempts to dispatch an event to the paused activity. **/
BusProvider.getInstance().unregister(this);
super.onPause();
}
/**
* Post the event to the service bus
* @param event
* The event to dispatch on the service bus
*/
protected void postEvent(Object event) {
BusProvider.getInstance().post(event);
}
}
HERE IS THE CODE WHERE I ADD THE LOGINFRAGMENT CLASS
package com.keyconsultant.parse.logintutorial;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.keyconsultant.parse.logintutorial.activity.BaseActivity;
import com.keyconsultant.parse.logintutorial.forgotpassword.ForgotPasswordDialogFragment;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.AuthenticateUserErrorEvent;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.AuthenticateUserStartEvent;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.AuthenticateUserSuccessEvent;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.UserForgotPasswordErrorEvent;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.UserForgotPasswordStartEvent;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.UserForgotPasswordSuccessEvent;
import com.parse.Parse;
import com.squareup.otto.Subscribe;
/**
* Activity which displays a login screen to the user, offering registration as
* well. Based loosley on the default Login template.
*
* @author Trey Robinson
*/
public class LoginActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Parse.initialize(this, "Your App Id", "Your Client ID");
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.main_view, LoginFragment.newInstance());
fragmentTransaction.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_login, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_forgot_password:
forgotPassword();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Open the forgotPassword dialog
*/
private void forgotPassword(){
FragmentManager fm = getSupportFragmentManager();
ForgotPasswordDialogFragment forgotPasswordDialog = new ForgotPasswordDialogFragment();
forgotPasswordDialog.show(fm, null);
}
@Subscribe
public void onSignInStart(AuthenticateUserStartEvent event){
showProgress(true, getString(R.string.login_progress_signing_in));
}
@Subscribe
public void onSignInSuccess(AuthenticateUserSuccessEvent event){
showProgress(false, getString(R.string.login_progress_signing_in));
Intent loginSuccess = new Intent(this, MainActivity.class);
startActivity(loginSuccess);
finish();
}
@Subscribe
public void onSignInError(AuthenticateUserErrorEvent event){
showProgress(false, getString(R.string.login_progress_signing_in));
}
@Subscribe
public void onForgotPasswordStart(UserForgotPasswordStartEvent event){
showProgress(true, getString(R.string.login_progress_signing_in));
}
@Subscribe
public void onForgotPasswordSuccess(UserForgotPasswordSuccessEvent event){
showProgress(false,getString(R.string.login_progress_signing_in));
Toast toast =Toast.makeText(this, "A password reset email has been sent.", Toast.LENGTH_LONG);
toast.show();
}
@Subscribe
public void onForgotPasswordError(UserForgotPasswordErrorEvent event){
showProgress(false, getString(R.string.login_progress_signing_in));
Toast toast =Toast.makeText(this, "An error has occured. Please try again.", Toast.LENGTH_LONG);
toast.show();
}
}
fragment_create_account
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/LoginFormContainer" >
<EditText
android:id="@+id/etUsername"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:hint="@string/usernameHint"
android:inputType="text"
android:maxLength="15" />
<EditText
android:id="@+id/etEmail"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_below="@id/etUsername"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:hint="@string/emailHint"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/etPassword"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_below="@id/etEmail"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:hint="@string/passwordHint"
android:inputType="textPassword"
android:maxLength="10" />
<EditText
android:id="@+id/etPasswordConfirm"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_below="@id/etPassword"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:hint="@string/confirmPasswordHint"
android:inputType="textPassword" />
<Button
android:id="@+id/btnCreateAccount"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_alignRight="@id/etPassword"
android:layout_below="@id/etPasswordConfirm"
android:layout_marginTop="25dp"
android:text="@string/createAccount" />
</RelativeLayout>
CreateAccountFragment CLASS
package com.keyconsultant.parse.logintutorial;
import java.util.Locale;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import com.keyconsultant.parse.logintutorial.error.UnknownErrorDialogFactory;
import com.keyconsultant.parse.logintutorial.fragment.BaseFragment;
import com.keyconsultant.parse.logintutorial.model.user.UserManager;
import com.keyconsultant.parse.logintutorial.model.user.authenticate.AuthenticateUserErrorEvent;
import com.parse.ParseException;
import com.squareup.otto.Subscribe;
/**
* Create an Account. Username is the primary method of login. Email is used for forgotten password recovery.
*
* @author Trey Robinson
*
*/
public class CreateAccountFragment extends BaseFragment implements OnClickListener {
protected static final String EXTRA_EMAIL = "com.keyconsultant.parse.logintutorial.fragment.extra.EMAIL";
protected static final String EXTRA_USERNAME = "com.keyconsultant.parse.logintutorial.fragment.extra.USERNAME";
protected static final String EXTRA_PASSWORD = "com.keyconsultant.parse.logintutorial.fragment.extra.PASSWORD";
protected static final String EXTRA_CONFIRM = "com.keyconsultant.parse.logintutorial.fragment.extra.CONFIRMPASSWORD";
private EditText mUserNameEditText;
private EditText mEmailEditText;
private EditText mPasswordEditText;
private EditText mConfirmPasswordEditText;
private Button mCreateAccountButton;
private String mEmail;
private String mUsername;
private String mPassword;
private String mConfirmPassword;
/**
* Factory method for creating fragment instances.
* @return
*/
public static CreateAccountFragment newInstance(){
return new CreateAccountFragment();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_create_account, container, false);
mUserNameEditText = (EditText)view.findViewById(R.id.etUsername);
mEmailEditText = (EditText)view.findViewById(R.id.etEmail);
mPasswordEditText = (EditText)view.findViewById(R.id.etPassword);
mConfirmPasswordEditText = (EditText)view.findViewById(R.id.etPasswordConfirm);
mCreateAccountButton = (Button)view.findViewById(R.id.btnCreateAccount);
mCreateAccountButton.setOnClickListener(this);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null){
mEmailEditText.setText(savedInstanceState.getString(EXTRA_EMAIL));
mUserNameEditText.setText(savedInstanceState.getString(EXTRA_USERNAME));
mPasswordEditText.setText(savedInstanceState.getString(EXTRA_PASSWORD));
mConfirmPasswordEditText.setText(savedInstanceState.getString(EXTRA_CONFIRM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(EXTRA_EMAIL, mEmailEditText.getText().toString());
outState.putString(EXTRA_USERNAME, mUserNameEditText.getText().toString());
outState.putString(EXTRA_PASSWORD, mPasswordEditText.getText().toString());
outState.putString(EXTRA_CONFIRM, mConfirmPasswordEditText.getText().toString());
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnCreateAccount:
createAccount();
break;
default:
break;
}
}
/**
* Some front end validation is done that is not monitored by the service.
* If the form is complete then the information is passed to the service.
*/
private void createAccount(){
clearErrors();
boolean cancel = false;
View focusView = null;
// Store values at the time of the login attempt.
mEmail = mEmailEditText.getText().toString();
mUsername = mUserNameEditText.getText().toString();
mPassword = mPasswordEditText.getText().toString();
mConfirmPassword = mConfirmPasswordEditText.getText().toString();
// Check for a valid confirm password.
if (TextUtils.isEmpty(mConfirmPassword)) {
mConfirmPasswordEditText.setError(getString(R.string.error_field_required));
focusView = mConfirmPasswordEditText;
cancel = true;
} else if (mPassword != null && !mConfirmPassword.equals(mPassword)) {
mPasswordEditText.setError(getString(R.string.error_invalid_confirm_password));
focusView = mPasswordEditText;
cancel = true;
}
// Check for a valid password.
if (TextUtils.isEmpty(mPassword)) {
mPasswordEditText.setError(getString(R.string.error_field_required));
focusView = mPasswordEditText;
cancel = true;
} else if (mPassword.length() < 4) {
mPasswordEditText.setError(getString(R.string.error_invalid_password));
focusView = mPasswordEditText;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mEmail)) {
mEmailEditText.setError(getString(R.string.error_field_required));
focusView = mEmailEditText;
cancel = true;
} else if (!mEmail.contains("@")) {
mEmailEditText.setError(getString(R.string.error_invalid_email));
focusView = mEmailEditText;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
UserManager.getInstance().signUp(mUsername.toLowerCase(Locale.getDefault()), mEmail, mPassword);
}
}
/**
* Remove error messages from all fields.
*/
private void clearErrors(){ mEmailEditText.setError(null);
mUserNameEditText.setError(null);
mPasswordEditText.setError(null);
mConfirmPasswordEditText.setError(null);
}
@Subscribe
public void onSignInError(AuthenticateUserErrorEvent event){
clearErrors();
switch (event.getErrorCode()) {
case ParseException.INVALID_EMAIL_ADDRESS:
mEmailEditText.setError(getString(R.string.error_invalid_email));
mEmailEditText.requestFocus();
break;
case ParseException.EMAIL_TAKEN:
mEmailEditText.setError(getString(R.string.error_duplicate_email));
mEmailEditText.requestFocus();
break;
case ParseException.USERNAME_TAKEN:
mUserNameEditText.setError(getString(R.string.error_duplicate_username));
mUserNameEditText.requestFocus();
break;
default:
UnknownErrorDialogFactory.createUnknownErrorDialog(this.getActivity()).show();
break;
}
}
}
Add another empty view as the very last child (right after last button with id register_button
) like following.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
It will stretch out parent LinearLayout
view to the whole height.