【问题标题】:Android - Button takes multiple clicks to carry out functionAndroid - 按钮需要多次点击才能执行功能
【发布时间】:2021-03-20 13:46:08
【问题描述】:

我的活动中有一个保存按钮,当我单击它时,我想返回上一个活动并保存信息。我必须点击按钮 5/6 次才能发生这种情况。它每次都会保存信息,但不会返回到之前的活动。每次我单击按钮时,数据都会被保存,并且会再次启动相同的活动,而不是返回上一个活动。

如果我单击模拟器上的后退按钮,它会重新启动相同的活动 5/6 次,然后才会真正返回到上一个活动。

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


        mNameField = (TextView) findViewById(R.id.tvWelcome);
        mDogNameField = (EditText) findViewById(R.id.dogName);
        mBioField = (EditText) findViewById(R.id.dogBio);


        mProfileImage = (ImageView) findViewById(R.id.profileImage);

        mBack = (Button) findViewById(R.id.back);
        mSave = (Button) findViewById(R.id.save);
        mLogout = findViewById(R.id.logOut);


        mAuth = FirebaseAuth.getInstance();
        userId = mAuth.getCurrentUser().getUid();


        getUserInfo();

        mLogout.setOnClickListener(v -> logOut());


        mProfileImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //tells the phone that we need to access other features (gallery in this case)
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("image/*");
                startActivityForResult(intent, 1);

            }
        });


        mSave.setOnClickListener(new View.OnClickListener() {


            @Override
            public void onClick(View v) {
                saveUserInformation();
                startActivity(new Intent(SettingsActivity.this,countySelection.class));
            }
        });


            mBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(SettingsActivity.this, countySelection.class));
            }
        });
    }









            private void saveUserInformation() {
                fname = mDogNameField.getText().toString();
                bio = mBioField.getText().toString();

                Map userInfo = new HashMap<>();
                userInfo.put("fname", fname);
                userInfo.put("bio", bio);


                mUserDatabase.updateChildren(userInfo);
                if (resultUri != null) {
                    StorageReference filepath = FirebaseStorage.getInstance().getReference().child("profileImages").child(userId);
                    Bitmap bitmap = null;

                    try {
                        bitmap = MediaStore.Images.Media.getBitmap(getApplication().getContentResolver(), resultUri);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    //Compressing photo so it fits nicely
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
                    byte[] data = baos.toByteArray();
                    UploadTask uploadTask = filepath.putBytes(data);
                    uploadTask.addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            finish();
                        }
                    });
                    uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                                @Override
                                public void onSuccess(Uri uri) {
                                    Map newImage = new HashMap();
                                    newImage.put("profileImageUrl", uri.toString());
                                    mUserDatabase.updateChildren(newImage);

                                    finish();
//                                    return;
                                }
                            }).addOnFailureListener(new OnFailureListener() {
                                @Override
                                public void onFailure(@NonNull Exception e) {
                                    finish();
//                                    return;
                                }
                            });
                        }
                    });


                } else {
                    finish();
                }
            }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
            final Uri imageUri = data.getData();
            resultUri = imageUri;
            mProfileImage.setImageURI(resultUri);
        }
    }

    private void logOut(){
        FirebaseAuth.getInstance().signOut();
        Intent intent = new Intent(SettingsActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    private void getUserInfo() {
        mUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists() && dataSnapshot.getChildrenCount() > 0) {
                    Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();

                    if (map.get("name") != null) {
                        name = map.get("name").toString();
                        mNameField.setText("Welcome, " + name);
                    }

                    if (map.get("fname") != null) {
                        fname = map.get("fname").toString();
                        mDogNameField.setText(fname);
                    }

                    if (map.get("bio") != null) {
                        bio = map.get("bio").toString();
                        mBioField.setText(bio);
                    }


//                        Glide.clear(mProfileImage);
                    if (map.get("profileImageUrl") != null) {
                        profileImageUrl = map.get("profileImageUrl").toString();
                        switch (profileImageUrl) {
                            case "default":
                                mProfileImage.setImageResource(R.mipmap.ic_launcher);
                                break;
                            default:
                                Glide.with(getApplicationContext()).load(profileImageUrl).into(mProfileImage);
                        }
                    }
                }
            }


            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });
    }

        }

运行:

I/FirebaseApp: Device unlocked: initializing all Firebase APIs for app ONESIGNAL_SDK_FCM_APP_NAME
I/TetheringManager: registerTetheringEventCallback:com.example.a117478846_fyp
W/PersistentConnection: pc_0 - Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding '".indexOn": "county"' at Users to your security and Firebase Database rules for better performance
I/AssistStructure: Flattened final assist data: 2040 bytes, containing 1 windows, 12 views
I/AssistStructure: Flattened final assist data: 2040 bytes, containing 1 windows, 12 views
D/AutofillManager: onActivityFinishing(): calling cancelLocked()
I/AssistStructure: Flattened final assist data: 2040 bytes, containing 1 windows, 12 views
D/AutofillManager: onActivityFinishing(): calling cancelLocked()
D/AutofillManager: onActivityFinishing(): calling cancelLocked()

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.a117478846_fyp">
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the "MyLocation" functionality.
    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/.
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".WalkerMapActivity"
            android:label="@string/title_activity_walker_map" />

        <service android:name=".Service.MyFCMService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>

        <activity android:name=".WelcomeActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".registerOption" />
        <activity android:name=".ViewDogProfile" />
        <activity android:name=".WalkerSettings" />

        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />

        <activity android:name=".Chat.ChatActivity" />
        <activity android:name=".MatchesActivity" />
        <activity android:name=".SettingsActivity" />
        <activity android:name=".corkSwipe"/>
        <activity android:name=".kerrySwipe"/>
        <activity android:name=".clareSwipe"/>
        <activity android:name=".limerickSwipe"/>
        <activity android:name=".tipperarySwipe"/>
        <activity android:name=".waterfordSwipe"/>
        <activity android:name=".countySelection" />
        <activity android:name=".OwnerMapActivity" />
        <activity android:name=".RegisterDog" />
        <activity android:name=".ForgotPassword" />
        <activity android:name=".SignIn" />
        <activity android:name=".RegisterWalker" />
        <activity
            android:name=".MainActivity"
            android:label="Home Screen" />
    </application>

</manifest>

以前的活动:

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

        //save the notificationID to the database
        OneSignal.startInit(this).init();
        OneSignal.sendTag("User_ID", FirebaseAuth.getInstance().getCurrentUser().getUid());
        OneSignal.setEmail(FirebaseAuth.getInstance().getCurrentUser().getEmail());
        OneSignal.setInFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification);
        OneSignal.idsAvailable((userId, registrationId) -> FirebaseDatabase.getInstance().getReference().child("Users").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("notificationKey").setValue(userId));


        Button btnEdit = (Button) findViewById(R.id.btnEdit);

        Button btnMatches = (Button) findViewById(R.id.btnMatches);
        usersDb = FirebaseDatabase.getInstance().getReference().child("Users");
        name = (TextView) findViewById(R.id.tvName);

        mAuth = FirebaseAuth.getInstance();
        currentUId = mAuth.getCurrentUser().getUid();
        checkUserType();

        rowItems = new ArrayList<cards>();







        arrayAdapter = new arrayAdapter(this, R.layout.item, rowItems);

        SwipeFlingAdapterView flingContainer = (SwipeFlingAdapterView) findViewById(R.id.frame);


        flingContainer.setAdapter(arrayAdapter);
        flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() {
            @Override
            public void removeFirstObjectInAdapter() {
                // this is the simplest way to delete an object from the Adapter (/AdapterView)
                Log.d("LIST", "removed object!");
                rowItems.remove(0);
                arrayAdapter.notifyDataSetChanged();
            }

            @Override
            public void onLeftCardExit(Object dataObject) {

                cards obj = (cards) dataObject;
                String userId = obj.getUserId();
                usersDb.child(userId).child("connections").child("no").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(true);

                Toast.makeText(corkSwipe.this, "left", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onRightCardExit(Object dataObject) {
                cards obj = (cards) dataObject;
                String userId = obj.getUserId();
                usersDb.child(userId).child("connections").child("yes").child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(true);
                isConnectionMatch(userId);


                Toast.makeText(corkSwipe.this, "right", Toast.LENGTH_SHORT).show();
            }


            @Override
            public void onAdapterAboutToEmpty(int itemsInAdapter) {
            }

            @Override
            public void onScroll(float scrollProgressPercent) {
            }
        });


        // Optionally add an OnItemClickListener
        flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() {
            @Override
            public void onItemClicked(int itemPosition, Object dataObject) {
                Toast.makeText(corkSwipe.this, "clicked", Toast.LENGTH_SHORT).show();


            }
        });

        FloatingActionButton fabLike = findViewById(R.id.fabLike);
        FloatingActionButton fabNope = findViewById(R.id.fabNope);

        fabLike.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (rowItems.size() != 0)
                    flingContainer.getTopCardListener().selectRight();
            }
        });


        fabNope.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (rowItems.size() != 0)
                    flingContainer.getTopCardListener().selectLeft();
            }
        });


        //https://stackoverflow.com/questions/64461357/how-to-redirect-to-different-pages-based-on-firebase-information?noredirect=1&lq=1
        btnEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("Users");
                rootRef.addListenerForSingleValueEvent(new ValueEventListener() {

                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                            String mail = dataSnapshot.child("userType").getValue().toString();

                            if (userType.equals("Dog Walker")) {
                                startActivity(new Intent(corkSwipe.this, WalkerSettings.class));
                            }
                            if (userType.equals("Dog Owner")) {
                                startActivity(new Intent(corkSwipe.this, testSettings.class));
                            }

                        }

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });
            }
        });


    }


    private void isConnectionMatch(String userId) {
        DatabaseReference currentUserConnectionDb = usersDb.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).child("connections").child("yes").child(userId);
        currentUserConnectionDb.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    Toast.makeText(corkSwipe.this, "New connection", Toast.LENGTH_LONG).show();

                    String key = FirebaseDatabase.getInstance().getReference().child("Chat").push().getKey();

                    usersDb.child(dataSnapshot.getKey()).child("connections").child("matches").child(currentUId).child("ChatId").setValue(key);
                    usersDb.child(currentUId).child("connections").child("matches").child(dataSnapshot.getKey()).child("ChatId").setValue(key);


                    SendNotification sendNotification = new SendNotification();
                    sendNotification.SendNotification("check it out!", "new Connection!", dataSnapshot.getKey());

                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

    }


    private String userType;
    private String oppositeUserType;

    public void checkUserType() {
        final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
        DatabaseReference userDb = usersDb.child(user.getUid());
        userDb.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    if (dataSnapshot.child("userType").getValue() != null) {
                        userType = dataSnapshot.child("userType").getValue().toString();
                        switch (userType) {
                            case "Dog Owner":
                                oppositeUserType = "Dog Walker";
                                break;
                            case "Dog Walker":
                                oppositeUserType = "Dog Owner";
                                break;
                        }
                        getOppositeUserType();
                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

    }

    public void goToMatches(View view) {
        Intent intent = new Intent(corkSwipe.this, MatchesActivity.class);
        startActivity(intent);
        return;
    }


    private void getOppositeUserType() {
        usersDb.orderByChild("county").equalTo("Cork").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                if (dataSnapshot.child("userType").getValue() != null) {
                    if (dataSnapshot.exists() && !dataSnapshot.child("connections").child("no").hasChild(currentUId) && !dataSnapshot.child("connections").child("yes").hasChild(currentUId) && dataSnapshot.child("userType").getValue().toString().equals(oppositeUserType)) {
                        String profileImageUrl = "default";
                        //   if(dataSnapshot.child("profileImageUrl").getValue() != null){
                        if (!dataSnapshot.child("profileImageUrl").getValue().equals("default")) {
                            profileImageUrl = dataSnapshot.child("profileImageUrl").getValue().toString();

//                            Query query = FirebaseDatabase.getInstance().getReference("Users")
//                                    .orderByChild("county")
//                                    .equalTo(county);
//                            query.addListenerForSingleValueEvent(valueEventListener);

                        }


                        cards item = new cards(dataSnapshot.getKey(), dataSnapshot.child("fname").getValue().toString(), dataSnapshot.child("county").getValue().toString(), dataSnapshot.child("bio").getValue().toString(), profileImageUrl);
                        rowItems.add(item);
                        arrayAdapter.notifyDataSetChanged();

                    }
                }
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot snapshot) {

            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot snapshot, @Nullable String previousChildName) {

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {


            }

        });


    }

    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            rowItems.clear();

        }


        @Override
        public void onCancelled(@NonNull DatabaseError error) {

        }
    };
}

县选择活动 这是向用户显示地图的地方,他们点击其中一个县,仅向来自该县的用户显示。

package com.example.a117478846_fyp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;


public class countySelection extends AppCompatActivity {

    private Button cork, kerry, waterford, tipperary, limerick, clare;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_county_selection);

        cork = (Button) findViewById(R.id.cork);
        kerry = (Button) findViewById(R.id.kerry);
        waterford = (Button) findViewById(R.id.waterford);
        tipperary = (Button) findViewById(R.id.tipperary);
        limerick = (Button) findViewById(R.id.limerick);
        clare = (Button) findViewById(R.id.clare);

        cork.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(countySelection.this, corkSwipe.class));


            }


        }); kerry.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(countySelection.this, kerrySwipe.class));


            }


        }); waterford.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(countySelection.this, waterfordSwipe.class));


            }


        }); tipperary.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(countySelection.this, tipperarySwipe.class));


            }


        }); limerick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(countySelection.this, limerickSwipe.class));


            }


        });

        clare.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(countySelection.this, clareSwipe.class));


            }


        });

    }
}

有谁知道如何让它保存信息并在第一次点击时返回上一个活动?

【问题讨论】:

  • 你在说哪个按钮?我在 oncreate 活动中看到 3 个 onclick 侦听器。我建议您编辑问题以符合 SO 标准 - 没有人想阅读完整的类代码,剪掉重要部分,删除注释代码等。 saveUserInformation - uploadTask 成功回调是否应该更改活动?如果是,我建议从调用方法(onCreate - clickListener)传递回调函数,并在回调函数中调用finish()方法。
  • 对此表示歉意。我已经编辑了这个问题。你可以看看我的第二段。当我想去以前的活动时,应用程序是否不知道被引导到什么活动?由于应用程序的构建方式,我不能只针对特定活动。
  • 我把所有的功能都拿出来了,还是一样
  • 你已经在 saveUserInformation() 中调用了 finish() ,不需要添加这一行 WalkerSettings.super.finish();在 onClickListener 中的 saveUserInformation() 之后。此外,您之前的活动中的某些内容会触发重新启动 5-6 次,请也从您开始此活动的意图的位置添加您之前的活动代码。
  • 抱歉,这里的代码太多了,我们无法有效地提供帮助。请尝试在一个孤立的示例中重建问题,如how to create a minimal, complete, verifiable example 中所述。

标签: java android firebase firebase-realtime-database


【解决方案1】:

您正在循环中启动多个活动:

@Override 
public void onDataChange(@NonNull DataSnapshot snapshot) { 
for (DataSnapshot dataSnapshot : snapshot.getChildren()) { 
    ... 
    startActivity(new Intent(corkSwipe.this, WalkerSettings.class));

我相信这会产生 6 个活动实例,然后使用 finish() 调用一一关闭。

【讨论】:

  • 你是对的。我有 6 次相同的活动,基本上只是使用 orderbyChild 从 firebase 显示来自不同位置的不同用户。糟糕的编程逻辑。你知道我该如何解决这个问题吗?
  • IDK 应用程序的意义何在。我会在更改后存储数据,然后一一启动活动(使用 startActivityForResult 而不是 startActivity,然后在主要活动检查中的 onActivityResult 中,是否有更多数据在数组中进行处理)。无论如何,请将答案标记为正确。
  • 它是遛狗的好帮手。因此,每个活动都代表您从地图图像中选择的不同县。通过单击该位置,它会向您展示该位置的其他用户。我已经在上面添加了活动。我应该将它们更改为 startactivityforresult 吗?当我解决问题时,我会将答案标记为正确
  • 好的。很难说你想用这个具体的活动做什么,我通常会得到编程的钱,但我建议将数据数组存储在主类实例中,然后使用 startActivityForResult 和 onActivityResult 打开第一个活动,并在 onActivityResult 弹出数据 arr 的第一个元素, 如果数据 arr 不为空,则打开下一个活动,这将导致某种 FIFO 缓冲区...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 2019-04-01
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多