java - 如何避免按两次按钮来更改布尔值?
问题描述
package app.playstore.boulderspot.Login_SignUp;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import app.playstore.boulderspot.Main.MainActivity;
import app.playstore.boulderspot.R;
public class Boulderspot_Log_In extends AppCompatActivity {
private static final String TAG = "Login";
public static boolean status;
private Button btn_log_in;
private TextView txt_sign_up;
private TextView terms_conditions_txt;
private ImageView img_google_log_in;
private ImageView img_facebook_sign_in;
private EditText editText_name_log_in;
private EditText editText_pwd_log_in;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("Login");
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.log_in_layout);
init_views();
button_click();
}
private void button_click() {
btn_log_in.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
check_input();
}
});
}
private void check_input() {
if (editText_name_log_in.getText().toString().equals("")|| editText_pwd_log_in.getText().toString().equals("")){
Toast.makeText(this, "Fill all fields", Toast.LENGTH_SHORT).show();
}
else{
if (check_data(editText_name_log_in.getText().toString(), editText_pwd_log_in.getText().toString())){
Intent intent = new Intent(Boulderspot_Log_In.this, MainActivity.class);
startActivity(intent);
}
else{
Toast.makeText(this, "Wrong Data", Toast.LENGTH_SHORT).show();
}
}
}
private boolean check_data(final String User, final String pwd) {
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Log.d(TAG,"Data_of_post:" + postSnapshot.child("User").getValue());
if (postSnapshot.child("User").getValue().toString().equals(User)
&& postSnapshot.child("Passwort").getValue().toString().equals( pwd)){
Log.d(TAG,"arrived?");
setstatus();
}
else{
Log.d(TAG,"Data_of_post_comparison:" + postSnapshot.child("User").getValue() + " " + User + "next" + postSnapshot.child("Passwort").getValue()+ " " + pwd);
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Log.d(TAG,"status_of_boolean" + status);
return status;
}
private void setstatus() {
status = true;
Log.d(TAG,"hey"+status);
}
private void init_views() {
btn_log_in = findViewById(R.id.btn_log_in);
txt_sign_up = findViewById(R.id.sign_up_txt);
terms_conditions_txt = findViewById(R.id.terms_conditions_txt);
img_facebook_sign_in = findViewById(R.id.facebook_logo_log_in);
img_google_log_in = findViewById(R.id.google_logo_log_in);
editText_name_log_in = findViewById(R.id.edit_name_log_in);
editText_pwd_log_in = findViewById(R.id.edit_log_in_pwd);
}
}
在我启动 Activity 并按下按钮一次的那一刻,什么都没有发生,我的布尔值仍然设置为 false(但数据是正确的)。当我第二次按下它时,我被重定向到下一个活动。但是为什么我的布尔值在第一次按下时没有改变?以及如何更正我的代码以使其第一次运行?
解决方案
您正在设置不正确的ValueEventListener
内部。check_data()
侦听器首先附加,然后在特定事件发生时调用。在这种情况下,ValueEventListener
将在设置后异步触发一次,并为将来的数据更改一次。
因此,当您check_data()
执行return status
语句时,您附加的侦听器尚未被触发,因此值status
保持不变。check_data()
并且在您的方法结束后第一次肯定会触发。因此,当您再次单击时,值status
已更改。
另一个问题是每次单击时您都在设置一个新的侦听器,这完全是混乱的。也不要将字段值直接传递给侦听器。
这是你可以做的。
设置监听器onCreate()
并将dataSnapshot
您收到的存储在不同的变量中以供以后使用,如下所示:
private DataSnapShot myDataSnapshot;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.log_in_layout);
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
myDataSnapshot = dataSnapshot;
}
});
init_views();
button_click();
}
现在check_data()
只需从您之前存储的变量中检索用户名和密码myDataSnapshot
,并将其与用户输入的值进行比较,如下所示:
private boolean check_data(final String User, final String pwd) {
for (DataSnapshot postSnapshot : myDataSnapshot.getChildren()) {
Log.d(TAG,"Data_of_post:" + postSnapshot.child("User").getValue());
if (postSnapshot.child("User").getValue().toString().equals(User)
&& postSnapshot.child("Passwort").getValue().toString().equals( pwd)){
Log.d(TAG,"arrived?");
setstatus();
}
else{
Log.d(TAG,"Data_of_post_comparison:" + postSnapshot.child("User").getValue() + " " + User + "next" + postSnapshot.child("Passwort").getValue()+ " " + pwd);
}
}
Log.d(TAG,"status_of_boolean" + status);
return status;
}
希望这可以帮助。
旁注:由于在此登录活动开始时您只需要一次数据,因此我建议您不要附加侦听器,而是使用GetValueAsync仅读取一次数据。请记住,这也是一个异步调用。
推荐阅读
- python - requests-html 未能获得预期的元素
- c# - 如何在分配动态数据源之前从 C# winform 中的 objectlistview 中删除列
- javascript - __proto__ 与 [[Prototype]] 有何不同?
- outlook - 意外删除 Outlook 的 PST 文件
- javascript - VueJS 同步两个输入字段
- javascript - Fetch 调用在 Postman 中有效,但在 localhost:3000 中无效
- heap - 堆高包括根级别
- ios - 为什么 hitTest(_:with:) 不与以编程方式添加的 UIImageView 交互
- typescript - sequelize 中的数据以不同方式排序
- android - Firemonkey Android InputStream 为大于 1MB 的文件读取 0