【问题标题】:Need help switching between activities需要帮助在活动之间切换
【发布时间】:2014-10-20 08:00:41
【问题描述】:

我是 Android Studio 的新手,所以我恳请您对初学者级别的解释 :)

我正在创建一个名为 SyncZ 的应用程序并创建了一个登录屏幕,我需要创建它以便当我按下“登录或注册”时它会转到我的 activity_main.xml

我首先创建了一个空白活动,后来添加了一个登录活动,然后我将activity_login.xml 设为主要,以便在启动应用程序时首先出现登录菜单。

所以我真正的问题是,如何使用按钮 email_sign_in_button 从 activity_login 切换到 activity_main

这是我的代码(XML 和 Java)如果文本太多,我很抱歉,希望你能解决:)

AndroidManifest.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<TextView
    android:text="@string/hello_world"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</RelativeLayout>

activity_login.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.administrator.helloworld.LoginActivity"
>

<!-- Login progress -->
<ProgressBar
    android:id="@+id/login_progress"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="470dp"
    android:layout_height="470dp"
    android:layout_marginBottom="8dp"
    android:visibility="gone"/>

<LinearLayout
    android:id="@+id/email_login_form"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:weightSum="1">

    <ImageView
        android:layout_width="300dp"
        android:layout_height="160dp"
        android:id="@+id/imageView"
        android:layout_gravity="center_horizontal"
        android:background="@drawable/syncz"
        android:layout_marginTop="50dp"
        android:layout_marginBottom="75dp" />

    <TextView
        android:layout_width="79dp"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Login:"
        android:id="@+id/textView"
        android:textStyle="bold" />

    <AutoCompleteTextView
        android:id="@+id/email"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/prompt_email"
        android:inputType="textEmailAddress"
        android:maxLines="1"
        android:singleLine="true"
        android:layout_marginTop="16dp"
        android:textStyle="italic"
        android:layout_marginBottom="10dp" />

    <EditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Password"
        android:imeActionId="@+id/login"
        android:imeActionLabel="@string/action_sign_in_short"
        android:imeOptions="actionUnspecified"
        android:inputType="textPassword"
        android:maxLines="1"
        android:singleLine="true"
        android:textStyle="italic" />

    <Button
        android:id="@+id/email_sign_in_button"
        style="?android:textAppearanceSmall"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="15dp"
        android:text="@string/action_sign_in"
        android:layout_weight="0.11"
        android:textSize="25dp"
        android:onClick="sendMessage" />/>
</LinearLayout>

</LinearLayout>

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">

<TextView
    android:text="@string/hello_world"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</RelativeLayout>

LoginActivity.java

package com.example.administrator.helloworld;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build.VERSION;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
 * A login screen that offers login via email/password.
*/
public class LoginActivity extends Activity implements LoaderCallbacks<Cursor>{
/**
 * A dummy authentication store containing known user names and passwords.
 * TODO: remove after connecting to a real authentication system.
 */
private static final String[] DUMMY_CREDENTIALS = new String[]{
        "foo@example.com:hello", "bar@example.com:world"
};
/**
 * Keep track of the login task to ensure we can cancel it if requested.
 */
private UserLoginTask mAuthTask = null;

// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);

    // Set up the login form.
    mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
    populateAutoComplete();

    mPasswordView = (EditText) findViewById(R.id.password);
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        }
    });

    Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
    mEmailSignInButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            attemptLogin();
            Intent intent= new Intent(LoginActivity.this,MainActivity.class);
            startActivity(intent);
        }
    });

    mLoginFormView = findViewById(R.id.login);
    mProgressView = findViewById(R.id.login_progress);
}

private void populateAutoComplete() {
    if (VERSION.SDK_INT >= 14) {
        // Use ContactsContract.Profile (API 14+)
        getLoaderManager().initLoader(0, null, this);
    } else if (VERSION.SDK_INT >= 9) {
        // Use AccountManager (API 8+)
        new SetupEmailAutoCompleteTask().execute(null, null);
    }
}



/**
 * 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() {
    if (mAuthTask != null) {
        return;
    }

    // Reset errors.
    mEmailView.setError(null);
    mPasswordView.setError(null);

    // Store values at the time of the login attempt.
    String email = mEmailView.getText().toString();
    String password = mPasswordView.getText().toString();

    boolean cancel = false;
    View focusView = null;


    // Check for a valid password, if the user entered one.
    if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
        mPasswordView.setError(getString(R.string.error_invalid_password));
        focusView = mPasswordView;
        cancel = true;
    }

    // Check for a valid email address.
    if (TextUtils.isEmpty(email)) {
        mEmailView.setError(getString(R.string.error_field_required));
        focusView = mEmailView;
        cancel = true;
    } else if (!isEmailValid(email)) {
        mEmailView.setError(getString(R.string.error_invalid_email));
        focusView = mEmailView;
        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.
        showProgress(true);
        mAuthTask = new UserLoginTask(email, password);
        mAuthTask.execute((Void) null);
    }
}
private boolean isEmailValid(String email) {
    //TODO: Replace this with your own logic
    return email.contains("@");
}

private boolean isPasswordValid(String password) {
    //TODO: Replace this with your own logic
    return password.length() > 4;
}

/**
 * Shows the progress UI and hides the login form.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void showProgress(final boolean show) {
    // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
    // for very easy animations. If available, use these APIs to fade-in
    // the progress spinner.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
        int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);

        mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
        mLoginFormView.animate().setDuration(shortAnimTime).alpha(
                show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
            }
        });

        mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
        mProgressView.animate().setDuration(shortAnimTime).alpha(
                show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
            }
        });
    } else {
        // The ViewPropertyAnimator APIs are not available, so simply show
        // and hide the relevant UI components.
        mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
        mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
    }
}

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    return new CursorLoader(this,
            // Retrieve data rows for the device user's 'profile' contact.
            Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
                    ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,

            // Select only email addresses.
            ContactsContract.Contacts.Data.MIMETYPE +
                    " = ?", new String[]{ContactsContract.CommonDataKinds.Email
                                                                 .CONTENT_ITEM_TYPE},

            // Show primary email addresses first. Note that there won't be
            // a primary email address if the user hasn't specified one.
            ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
    List<String> emails = new ArrayList<String>();
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
        emails.add(cursor.getString(ProfileQuery.ADDRESS));
        cursor.moveToNext();
    }

    addEmailsToAutoComplete(emails);
}

@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {

}

private interface ProfileQuery {
    String[] PROJECTION = {
            ContactsContract.CommonDataKinds.Email.ADDRESS,
            ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
    };

    int ADDRESS = 0;
    int IS_PRIMARY = 1;
}

/**
 * Use an AsyncTask to fetch the user's email addresses on a background thread, and update
 * the email text field with results on the main UI thread.
 */
class SetupEmailAutoCompleteTask extends AsyncTask<Void, Void, List<String>> {

    @Override
    protected List<String> doInBackground(Void... voids) {
        ArrayList<String> emailAddressCollection = new ArrayList<String>();

        // Get all emails from the user's contacts and copy them to a list.
        ContentResolver cr = getContentResolver();
        Cursor emailCur = cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
                null, null, null);
        while (emailCur.moveToNext()) {
            String email = emailCur.getString(emailCur.getColumnIndex(ContactsContract
                    .CommonDataKinds.Email.DATA));
            emailAddressCollection.add(email);
        }
        emailCur.close();

        return emailAddressCollection;
    }

    @Override
    protected void onPostExecute(List<String> emailAddressCollection) {
       addEmailsToAutoComplete(emailAddressCollection);
    }
}

private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
    //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
    ArrayAdapter<String> adapter =
            new ArrayAdapter<String>(LoginActivity.this,
                    android.R.layout.simple_dropdown_item_1line, emailAddressCollection);

    mEmailView.setAdapter(adapter);
}

/**
 * Represents an asynchronous login/registration task used to authenticate
 * the user.
 */
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {

    private final String mEmail;
    private final String mPassword;

    UserLoginTask(String email, String password) {
        mEmail = email;
        mPassword = password;
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        // TODO: attempt authentication against a network service.

        try {
            // Simulate network access.
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            return false;
        }

        for (String credential : DUMMY_CREDENTIALS) {
            String[] pieces = credential.split(":");
            if (pieces[0].equals(mEmail)) {
                // Account exists, return true if the password matches.
                return pieces[1].equals(mPassword);
            }
        }

        // TODO: register the new account here.

        return true;
    }

    @Override
    protected void onPostExecute(final Boolean success) {
        mAuthTask = null;
        showProgress(false);

        if (success) {
            finish();
        } else {
            mPasswordView.setError(getString(R.string.error_incorrect_password));
            mPasswordView.requestFocus();
        }
    }

    @Override
    protected void onCancelled() {
        mAuthTask = null;
        showProgress(false);
    }
}
}

MainActivity.java

package com.example.administrator.helloworld;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}
  • 编辑 - 添加了 Logcat Dropbox
  • 编辑 - 更新了所有代码。通过 Logcat 在 LoginActivity.java 中发现的错误(第 177、151 和 82 行)

第 82 行错误:

78 Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
79   mEmailSignInButton.setOnClickListener(new OnClickListener() {
80      @Override
81      public void onClick(View view) {
82          attemptLogin();
83          Intent intent= new Intent(LoginActivity.this,MainActivity.class);
84          startActivity(intent);
85      }
86 });

第 151 行错误:

144 if (cancel) {
145     // There was an error; don't attempt login and focus the first
146     // form field with an error.
147     focusView.requestFocus();
148 } else {
149     // Show a progress spinner, and kick off a background task to
150     // perform the user login attempt.
151     showProgress(true);
152     mAuthTask = new UserLoginTask(email, password);
153     mAuthTask.execute((Void) null);
154 }

第 177 行错误:

177 mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
178     mLoginFormView.animate().setDuration(shortAnimTime).alpha(
179             show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
180         @Override
181         public void onAnimationEnd(Animator animation) {
182             mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
183         }
184 });

【问题讨论】:

  • 为什么要更改布局,您可以调用其他活动,或者您可以将所有这些内容放在一个 xml 中并使用可见性。

标签: java android xml android-activity


【解决方案1】:

在您的登录活动中编写此代码:这将从 LoginActivity 切换到 MainActivity

startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();

【讨论】:

  • 应用程序崩溃:(
  • 什么是 logcat?显示你的 logcat。
  • 你能告诉我如何“打印”它吗? :)
  • 打开 logcat: Window->show view->Logcat 和 andriod 运行应用程序。当应用程序崩溃时,它会自动打印 logcat。
  • 我无法正确格式化它,所以我已将它作为 .txt 链接上传到 Dropbox,位于帖子底部。
【解决方案2】:

在 Android 中,您可以使用 Intent 在活动之间切换。您定义了一个 Intent,当它被激活时,它会将您的应用程序的用户带到另一个活动(称为显式 Intent)。您可以使用 Intent 在您的应用程序的活动之间传递信息(例如对象)。

简而言之,如何使用 Intent:

  1. 实例化一个新的 Intent,为其提供一个 Context(通常是您当前的 Activity this)和目标 Activity 的类 Object (MainActivity.class)
  2. 如果您希望 Intent 将数据传输到您的新 Activity,请使用其 putExtra() 方法将数据附加到您的 Intent 实例。这基本上像地图一样工作。您可以使用最初存储内容的相同密钥访问目标 Activity 中的附加数据。
  3. 在旧的 Activity 中调用 startActivity()
  4. 在您的新 Activity (MainActivity) 中,通过 getStringExtra() 从 Intent 中提取数据

一开始我发现有一点误导,那就是 android 的 Activity 生命周期和导航设施之间的联系。例如,您必须考虑是否要在用户按下按钮时启动活动的新实例,或者是否要保留和重用实例等。

除了显式 Intent 的基本导航功能之外,您还可以使用所谓的隐式 Intent 来提供对 App 独立 Android 功能的访问,例如写一封电子邮件,...

在这里可以找到更深入的教程: http://developer.android.com/training/basics/firstapp/starting-activity.html

如果您想了解这一切,请查看指向 Google API Doc for Intents 的链接: http://developer.android.com/reference/android/content/Intent.html

希望对您有所帮助。 马库斯

【讨论】:

    【解决方案3】:

    在活动之间移动的最佳方式通常是使用 Intent(不确定您是否见过这些)。有很多关于它们的资源,比如这个:http://www.vogella.com/tutorials/AndroidIntent/article.html。这家伙为初学者提供了一些非常酷的教程。基本上会发生的是在您的 onClickListener 方法中将传递一个意图并以该意图启动一个活动。意图有助于跨活动获取信息,尽管它们可以用于各种很酷的内置任务,例如照片选择。我希望这会有所帮助。

    【讨论】:

      【解决方案4】:
       Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
      mEmailSignInButton.setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View view) {
              Intent intent= new Intent(LoginActivity.this,MainActivity.class);
              startActivity(intent);
          }
      });
      

      【讨论】:

      • 在LoginActivity.java 中添加这个并创建 Intent 的导入?
      • yes @DeliciousCake 如果你想检查验证更具体。在 if 语句和 else 语句中你可以使用它来切换到另一个活动
      • 我已经使用它并正确设置了它,不幸的是应用程序在按下Sign in or register后崩溃了
      • 请您发布 logcat
      • 我已将它作为帖子底部的 .txt 链接上传到 Dropbox。
      【解决方案5】:

      以下代码启动活动:

      Intent intent = new Intent(LoginActivity.this, MainActivity.class);
      startaActivity(intent);
      

      但是,如果你要向 MainActivity 传递数据,你可以使用putExtra();

      Intent intent = new Intent(LoginActivity.this, MainActivity.class);
      intent.putExtra("myData", the data here);
      startActivity(intent);
      

      【讨论】:

      • 不幸的是应用程序崩溃:(
      猜你喜欢
      • 1970-01-01
      • 2017-11-15
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多