Saya mencoba mencegah aktivitas memuat dua kali jika saya menekan tombol dua kali secara instan setelah klik pertama.
Saya memiliki aktivitas yang memuat dengan mengklik tombol, misalnya
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//Load another activity
}
});
Sekarang karena aktivitas yang akan dimuat memiliki panggilan jaringan, dibutuhkan sedikit waktu untuk memuat (MVC). Saya memang menunjukkan tampilan pemuatan untuk ini, tetapi jika saya menekan tombol dua kali sebelumnya, saya dapat melihat aktivitas dimuat dua kali.
Apakah ada yang tahu bagaimana mencegahnya?
Jawaban:
Di pemroses acara tombol, nonaktifkan tombol dan tampilkan aktivitas lain.
Button b = (Button) view; b.setEnabled(false); Intent i = new Intent(this, AnotherActitivty.class); startActivity(i);
Ganti
onResume()
untuk mengaktifkan kembali tombol.@Override protected void onResume() { super.onResume(); Button button1 = (Button) findViewById(R.id.button1); button1.setEnabled(true); }
sumber
Tambahkan ini ke
Activity
definisi Anda diAndroidManifest.xml
...android:launchMode = "singleTop"
Sebagai contoh:
<activity android:name=".MainActivity" android:theme="@style/AppTheme.NoActionBar" android:launchMode = "singleTop"/>
sumber
android:launchMode = "singleTop"
, yang mencapai efek tanpa merusak multitasking Android. Dokumentasi menyatakan bahwa sebagian besar aplikasi tidak boleh menggunakansingleInstance
opsi ini.Anda bisa menggunakan flag maksud seperti ini.
Intent intent = new Intent(Class.class); intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); activity.startActivity(intent);
Ini akan membuat hanya satu aktivitas yang terbuka di bagian atas tumpukan riwayat.
sumber
android:launchMode = "singleTop"
dengan cara ini diselesaikan tanpa harus menambahkan tanda ke setiap Intent.Karena SO tidak mengizinkan saya mengomentari jawaban lain, saya harus mencemari utas ini dengan jawaban baru.
Jawaban umum untuk masalah "aktivitas membuka dua kali" dan pengalaman saya dengan solusi ini (Android 7.1.1):
EDIT: Ini untuk memulai aktivitas dengan startActivity (). Saat menggunakan startActivityForResult () saya perlu menyetel FLAG_ACTIVITY_SINGLE_TOP dan FLAG_ACTIVITY_CLEAR_TOP.
sumber
Itu hanya bekerja untuk saya ketika
startActivity(intent)
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
sumber
android:launchMode = "singleInstance"
dalam file Manifest dari tag aktivitas Anda?Gunakan singleInstance untuk menghindari aktivitas memanggil dua kali.
<activity android:name=".MainActivity" android:label="@string/activity" android:launchMode = "singleInstance" />
sumber
Katakanlah @wannik benar tetapi jika kita memiliki lebih dari 1 tombol yang memanggil pendengar tindakan yang sama dan saya mengklik dua tombol sekali pada waktu yang hampir bersamaan sebelum memulai aktivitas berikutnya ...
Jadi alangkah baiknya jika Anda memiliki field
private boolean mIsClicked = false;
dan di listener:if(!mIsClicked) { mIsClicked = true; Intent i = new Intent(this, AnotherActitivty.class); startActivity(i); }
Dan
onResume()
kita perlu mengembalikan keadaan:@Override protected void onResume() { super.onResume(); mIsClicked = false; }
Apa perbedaan antara jawaban saya dan @ wannik?
Jika Anda menyetel diaktifkan ke false di pemrosesnya memanggil lihat, tombol lain yang menggunakan pemroses yang sama akan tetap diaktifkan. Jadi untuk memastikan bahwa tindakan listener tidak dipanggil dua kali, Anda harus memiliki sesuatu yang global yang menonaktifkan semua pemanggilan listener (tidak masalah apakah itu instance baru atau tidak)
Apa perbedaan antara jawaban saya dan orang lain?
Mereka berpikir dengan cara yang benar tetapi mereka tidak berpikir untuk masa depan kembali ke contoh yang sama dari aktivitas panggilan :)
sumber
synchronized(mIsClicked) {...}
sumur agar 100% aman.Untuk situasi ini, saya akan memilih salah satu dari dua pendekatan,
singleTask
di manifest.xml ATAU sebuah tanda di AktivitasonResume()
&onDestroy()
masing-masing metode .Untuk solusi pertama : Saya lebih suka menggunakan
singleTask
untuk aktivitas dalam manifes daripadasingleInstance
, sesuai penggunaan,singleInstance
saya menemukan bahwa dalam beberapa kesempatan aktivitas membuat instance terpisah baru untuk dirinya sendiri yang menghasilkan dua jendela aplikasi terpisah di aplikasi yang sedang berjalan di bcakground dan di samping alokasi memori tambahan yang akan menghasilkan Pengalaman Pengguna yang sangat buruk saat pengguna membuka tampilan aplikasi untuk memilih beberapa aplikasi untuk dilanjutkan. Jadi, cara yang lebih baik adalah dengan menetapkan aktivitas di manifest.xml seperti berikut:<activity android:name=".MainActivity" android:launchMode="singleTask"</activity>
Anda dapat memeriksa mode peluncuran aktivitas di sini .
Untuk solusi kedua , Anda hanya perlu menentukan variabel statis atau variabel preferensi, misalnya:
public class MainActivity extends Activity{ public static boolean isRunning = false; @Override public void onResume() { super.onResume(); // now the activity is running isRunning = true; } @Override public void onDestroy() { super.onDestroy(); // now the activity will be available again isRunning = false; } }
dan dari sisi lain ketika Anda ingin meluncurkan aktivitas ini, cukup centang:
private void launchMainActivity(){ if(MainActivity.isRunning) return; Intent intent = new Intent(ThisActivity.this, MainActivity.class); startActivity(intent); }
sumber
Saya pikir Anda akan menyelesaikan masalah dengan cara yang salah. Umumnya itu adalah ide yang buruk bagi suatu kegiatan untuk membuat permintaan web lama berjalan di salah metode startup siklus hidup (
onCreate()
,onResume()
, dll). Sungguh, metode ini hanya boleh digunakan untuk membuat instance dan menginisialisasi objek yang akan digunakan aktivitas Anda dan karenanya harus relatif cepat.Jika Anda perlu melakukan permintaan web, lakukan ini di thread latar belakang dari aktivitas yang baru Anda luncurkan (dan tampilkan dialog pemuatan di aktivitas baru). Setelah thread permintaan latar belakang selesai, thread tersebut dapat memperbarui aktivitas dan menyembunyikan dialog.
Ini berarti aktivitas baru Anda harus segera diluncurkan dan mencegah kemungkinan klik dua kali.
sumber
Semoga ini membantu:
protected static final int DELAY_TIME = 100; // to prevent double click issue, disable button after click and enable it after 100ms protected Handler mClickHandler = new Handler() { public void handleMessage(Message msg) { findViewById(msg.what).setClickable(true); super.handleMessage(msg); } }; @Override public void onClick(View v) { int id = v.getId(); v.setClickable(false); mClickHandler.sendEmptyMessageDelayed(id, DELAY_TIME); // startActivity() }`
sumber
Solusi lain yang sangat sederhana jika Anda tidak ingin menggunakan
onActivityResult()
adalah menonaktifkan tombol selama 2 detik (atau waktu yang Anda inginkan), tidak ideal, tetapi dapat menyelesaikan sebagian masalah adalah beberapa kasus dan kodenya sederhana:final Button btn = ... btn.setOnClickListener(new OnClickListener() { public void onClick(View v) { //start activity here... btn.setEnabled(false); //disable button //post a message to run in UI Thread after a delay in milliseconds btn.postDelayed(new Runnable() { public void run() { btn.setEnabled(true); //enable button again } },1000); //1 second in this case... } });
sumber
// variabel untuk melacak waktu acara
private long mLastClickTime = 0;
2. Di onClick periksa bahwa jika waktu saat ini dan waktu klik terakhir perbedaan kurang dari i detik maka jangan lakukan apa-apa (kembali) lagi pergi untuk acara klik
@Override public void onClick(View v) { // Preventing multiple clicks, using threshold of 1 second if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { return; } mLastClickTime = SystemClock.elapsedRealtime(); // Handle button clicks if (v == R.id.imageView2) { // Do ur stuff. } else if (v == R.id.imageView2) { // Do ur stuff. } } }
sumber
Cukup pertahankan satu tanda dalam metode onClick tombol sebagai:
public boolean oneTimeLoadActivity = false;
myButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if(!oneTimeLoadActivity){ //start your new activity. oneTimeLoadActivity = true; } } });
sumber
tambahkan Mode Peluncuran sebagai tugas tunggal dalam manifes untuk menghindari aktivitas dibuka dua kali saat mengklik
<activity android:name=".MainActivity" android:label="@string/activity" android:launchMode = "singleTask" />
sumber
Jika Anda menggunakan onActivityResult, Anda dapat menggunakan variabel untuk menyimpan status.
private Boolean activityOpenInProgress = false; myButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if( activityOpenInProgress ) return; activityOpenInProgress = true; //Load another activity with startActivityForResult with required request code } }); protected void onActivityResult(int requestCode, int resultCode, Intent data) { if( requestCode == thatYouSentToOpenActivity ){ activityOpenInProgress = false; } }
Bekerja pada tombol kembali yang ditekan juga karena kode permintaan dikembalikan pada acara.
sumber
myButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { myButton.setOnClickListener(null); } });
sumber
Gunakan
flag
variabel set ituto true
, Periksa apakah benar hanyareturn
melakukan Panggilan Aktivitas.Anda juga bisa menggunakan setClickable (false) satu yang menjalankan Panggilan Aktivitas
flg=false public void onClick(View view) { if(flg==true) return; else { flg=true; // perform click} }
sumber
perform click; wait; flg = false;
untuk saat kita kembaliAnda bisa mengganti startActivityForResult dan menggunakan variabel instance:
boolean couldStartActivity = false; @Override protected void onResume() { super.onResume(); couldStartActivity = true; } @Override public void startActivityForResult(Intent intent, int requestCode, Bundle options) { if (couldStartActivity) { couldStartActivity = false; intent.putExtra(RequestCodeKey, requestCode); super.startActivityForResult(intent, requestCode, options); } }
sumber
Anda juga bisa mencobanya
Button game = (Button) findViewById(R.id.games); game.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Intent myIntent = new Intent(view.getContext(), Games.class); startActivityForResult(myIntent, 0); } });
sumber