点击后退按钮后存储变量

时间:2018-06-11 15:48:22

标签: android sharedpreferences

我需要创建一个登录屏幕和一个简单的第一个屏幕(带有一个注销按钮)。当用户登录时,为方便起见,它不需要再次登录(仅当登出注销按钮时)。为此,我需要存储一个布尔变量,无论用户是否登录。

当我点击主页按钮并再次打开应用程序时,该应用程序会记住我已经登录。但是当我按下后退按钮时,它不会记住它。

以下是登录屏幕的代码:

package com.example.a20172425.login;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;



public class LoginActivity extends AppCompatActivity {
EditText usernameEditText;
EditText passwordEditText;
TextView falseLoginTextView;
SharedPreferences pref;
boolean validCredentials = false;
public static Boolean login = false;


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



    usernameEditText = (EditText)findViewById(R.id.usernameField);
    passwordEditText = (EditText)findViewById(R.id.passwordField);
    falseLoginTextView = (TextView)findViewById(R.id.falseLoginText);
    pref = getPreferences(MODE_PRIVATE);
    login = getLoginStatus();
    if(login) {
        toMainActivity();
    }
}

public void checkCredentials(View v){
    //clear possible previous content
    falseLoginTextView.setText("");

    //retrieve username and password
    String username = usernameEditText.getText().toString();
    String password = passwordEditText.getText().toString();



    if ((username.equals("username")) && (password.equals("password"))) {
        validCredentials = true;
        setLoginStatus(true);
        //setUsername(username);
    } else if ((username.equals("a")) && (password.equals("a"))) {
        validCredentials = true;
        setLoginStatus(true);
        //setUsername(username);
    }

    if (validCredentials){
        toMainActivity();
    }
    else
    {
        falseLoginTextView.setText("Incorrect username and or password");
    }

}

public void toMainActivity(){
    Intent intent = new Intent(LoginActivity.this, MainActivity.class);
    intent.putExtra("Username", usernameEditText.getText().toString());
    this.startActivity(intent);
    //makes sure pressing the back button does not send the app back to the login screen
    this.finish();

}


// gets the logged_in value from persistent memory.
public Boolean getLoginStatus (){

    return pref.getBoolean("Logged_in",false);
}


//sets the logged_in boolean value in persistent memory.
public void setLoginStatus(Boolean loginStatus){
    //editor to change values to be stored in memory
    SharedPreferences.Editor edit = pref.edit();
    edit.putBoolean("Logged_in",loginStatus);
    //save changes
    edit.commit();
}



}

这是我的简单第一个屏幕的代码:

package com.example.a20172425.login;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import static com.example.a20172425.login.LoginActivity.login;


public class MainActivity extends AppCompatActivity {
TextView LoginTextView;
LoginActivity loginActivity;


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

    LoginTextView = (TextView) findViewById(R.id.LoginTV);

    String username = getIntent().getStringExtra("Username");
    LoginTextView.setText("Currently logged in as: " + username);

    loginActivity = new LoginActivity();
}


public void toLoginActivity(View v) {
    Intent intent = new Intent(MainActivity.this, LoginActivity.class);
    this.startActivity(intent);
    login = false;
    //loginActivity.setLogin(false);
    //makes sure pressing the back button does not send the app back to the login screen
    this.finish();
}



}

任何建议都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

编辑:我在日常工作中写Kotlin,我实际上没有编译下面的Java示例,因此可能存在一些语法错误。但是,使用基本的Java工作知识解决这些问题应该是相当简单的。本答案中的概念适用于绝大多数OO语言(Kotlin,Java,C#等)。

我更新了这个答案,以更详细地介绍界面是什么,它们有用的原因,回调如何工作以及它们是如何在幕后实现的。

在面向对象编程(OO)中,在本例中是Java;有一个允许多态的类型系统。多态性在被分解时意味着(多 - >多)和(态射 - >表现得像),或者换句话说,许多类似行为的不同类型。

这些在更具体的编码术语中意味着您可以拥有许多不同类型的符合常见行为(或接口)的类型。类型的行为应该被认为是它可以向外观察的行为,而不是内部实现。关于类型系统将其概念化是有用的。例如,行为被定义为从一种类型到另一种类型的转换(例如,获取字符串集合并返回字符串的函数)。有许多函数可以执行此转换,但所有这些函数的向外可观察行为是相同的(换句话说,转换集合 - >字符串)。

因此,只要保持向外可观察的行为,这种类型系统就可以允许任意交换实现。

接口是实现此目的的流行语言构造。接口仅定义类型之间的转换并为它们命名。其他类型可能依赖于此接口并调用此接口的方法而不关心方法的实际实现(唯一的约束是所述接口的实现者必须符合类型转换 - 这在编译时强制执行爪哇)。

这是一个非常简单的界面:

public interface Car {
    public Int accelerate(Int force);
    public Int steer(Int direction);
}

我使用汽车示例,因为它非常直观。在这里,我们可以看到两个类型转换,Int -> Int名称为accelerateInt -> Int名称为steer

所有汽车都可以acceleratesteer。但并非所有汽车acceleratesteer都采用相同的方式。但是,所有汽车steeraccelerate行为都遵循共同模式(或类型转换)。它们获取一些输入值并产生一些输出值。

所以,我们可以提供几种类似汽车的实现(请记住这是一个非常人为的例子,所以不要判断):

public class Ford implements Car {
    @Override
    public Int accelerate(Int force) {
        return force * 1;
    }
    @Override
    public Int steer(Int direction) {
        return direction * 1;
    }
}

public class Ferrari implements Car {
    @Override
    public Int accelerate(Int force) {
        return force * 10;
    }
    @Override
    public Int steer(Int direction) {
        return direction * 10;
    }
}

正如你所看到的,福特和法拉利都在引导和加速。但是法拉利的表现不同(但它仍然符合福特所做的类型转换)。

现在,我们在这里介绍多态,这是一个非常强大的工具。想象一下,我们有以下课程:

public class Person {
    private Car car;

    public Person(Car car) {
        this.car = car
    }
}

因此,一个人可以通过将汽车作为一种依赖来构建。由于多态性,我们可以传递实现(或符合)Car接口的对象的任何实例。例如,我们可以执行以下操作:

public class Main {
    public void main([String] args) {
        Person poorPerson = new Person(new Ford());
        Person richPerson = new Person(new Ferrari());
    }
}

非常漂亮!现在我们可以创造数百种不同类型的汽车,但我们的人员班级永远不会改变!我们的班级人员可以在他们各自拥有的汽车上调用方法,而不必担心任何破坏(因为所有汽车都可以加速和操纵)。

那么,这与原始问题有何关系?让我们考虑这个非常人为的Android View类和Callback接口示例:

public interface ContrivedCallback {
    public void onClick();
}

public class ContrivedView {
    private ContrivedCallback callback;

    public void setOnClickListener(ContrivedCallback: callback) {
        this.callback = callback;
    }

    private void onClick() {
        this.callback.invoke();
    }
}

让我们假设当点击视图时,Android操作系统会神奇地调用onClick类中的ContrivedView方法。现在,单击视图时,将调用回调(如果已设置)。但是,正如我们现在所知,回调只是一个接口,因此将调用为setCallback方法提供的任何实现。

因此,回调单一定义的方法仅仅是来自Void的转换 - > Void(换句话说,它不接受任何参数并且不返回任何值)。它只是运行一些代码。实现可能会启动火箭,保存到数据库,打印字符串或完全没有任何内容,这取决于提供实现的编码器。

我希望这有道理吗?现在,就原来的问题而言:

您可以使用onClickListener回调。在这个回调实现中,你可以编写一些代码来更新Activity或Fragment的某些状态(或者写入首选项或本地数据库,或者发射导弹......你得到了图片)。

您创建一个实现,然后将此实现分配给相关按钮上的回调侦听器,如此(在您的onCreate方法中):

logoutButton = (Button)findViewById(R.id.logoutButton);
logoutButton.addOnClickListener(class callback extends DialogInterface.OnClickListener {
    @Override
    public void onClick() {
        // Do stuff here...
    }
});