Question

Shows up fine in the graphical layout and then when I launch in the emulator it does this http://imgur.com/zR0xncU

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;
        }
    }

}
Was it helpful?

Solution

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.

OTHER TIPS

Set your linearlayout with android:layout_height="fill_parent"

It will work i think.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top