Issue
I have a lot of buttons on every activity of my app, clicking a button will lead to open new activity. My problem is while the activity has not showed up yet, and the user click again on the same button or other button, the there will be another activity to be showed up.
How do I prevent this? Is there any quick and clean way like setting option in the layout?
Solution
I will try to give a more general and reliable solution here. Although the answer Bhavik Parmar suggested is quite close but uses ProgressDialog
, which is already deprecated. You can also use this approach to show loading while data is being downloading from your server or some API is hit and you are waiting for it's response.
Firstly, you will have to create a class for example BaseActivity
which extends AppCompatActivity
and second a layout for ProgressBar
.
Below is the layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent_black_10"
android:id="@+id/relative_layout_progress_bar"
android:visibility="gone"
android:clickable="true"
android:focusable="true"
android:elevation="8dp">
<android.support.v4.widget.ContentLoadingProgressBar
android:id="@+id/loadingProgressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:indeterminateTint="@color/colorPrimary"
android:progressBackgroundTint="@color/colorPrimary"
android:visibility="visible" />
</RelativeLayout>
Now in the BaseActivity you need to add code below
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
public class BaseActivity extends AppCompatActivity {
private View progressBarView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (progressBarView == null) {
ViewGroup parent = (ViewGroup) findViewById(android.R.id.content).getRootView();
progressBarView = getLayoutInflater().inflate(R.layout.layout_progress_bar, null);
parent.addView(progressBarView);
}
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
if(isLoading()) {
hideLoading();
}
super.onStop();
}
@Override
protected void onResume() {
if(isLoading()) {
hideLoading();
}
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public void showLoading() {
if(this.isFinishing()) {
return;
}
if (progressBarView != null) {
progressBarView.bringToFront();
progressBarView.setVisibility(View.VISIBLE);
}
}
public void hideLoading() {
if(!this.isFinishing()) {
if(progressBarView != null) {
progressBarView.setVisibility(View.GONE);
}
}
}
public boolean isLoading() {
return (progressBarView != null && progressBarView.getVisibility() == View.VISIBLE);
}
}
Now wherever you need to implement this functionality, extend this BaseActivity
, for example if you need it in your HomeActivity
then make the HomeActivity
extend BaseActivity
.
public class HomeActivity extends BaseActivity {...}
Now all you have to do is call this showLoading
function in your onClick()
of the button
showLoading();
And you will get a clean loading effect and all the other buttons will not be able to be clicked. The other benefit of this approach is that the user gets to know that something is loading now and he/she has to wait and clicking anywhere won't do much right now.
Now you might ask that when will this loading be closed, so in the code of BaseActivity
you can see that onResume()
and onStop()
check loading and hide it according to android life cycle. So that will be handled automatically. Although you can change the implementation the way you like.
Answered By - Rathore
Answer Checked By - Pedro (JavaFixing Volunteer)