Disabling all touches when loading indicator is shown - android

I have a simple main layout, and then I add a fragment layout that only shows an indicator loading on top of that main layout. Problem is that I can still press the buttons behind the loading indicator.
Is there anyway to disable touches so it doesn't pass through to the back? I don't want to have to disable each button on the main screen one by one.

You could set the "clickable" attribute to "true" in the layout that contains your ProgressBar:
<FrameLayout
android:id="#+id/progressBarContainer"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:clickable="true" >
<ProgressBar
android:id="#+id/progressBar"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
Then while the ProgressBar is visible, its container (which fills the entire screen although it's invisible) will intercept any click events so they won't fall through to the underlying layout while your ProgressBar is showing.
To use this, do this when you want to show the ProgressBar:
findViewById(R.id.progressBarContainer).setVisibility(View.VISIBLE);
and then do this when you're done with it:
findViewById(R.id.progressBarContainer).setVisibility(View.INVISIBLE);
For instance, if you're using this in an AsyncTask, you could make it visible in onPreExecute(), then make it invisible in onPostExecute().

Return true while you wanna block user touches. Override this method in your Activity.
#Override
public boolean onTouchEvent( MotionEvent event ) {
return true;
}

Related

How to make recyclerView_items unclickable, while one of them is clicked and working?

Premise
Each of my RecyclerView_items displays an image, and changes its image_resource when tapped.
One of them is the right answer which has additional function: navigation to another fragment 5-second after changing its image.
Basically, the function of clickListener of RecyclerView_items is
wrong item
click -> change image_resource
right item
click -> change image_resource -> delay(5000) -> navigate to another fragment
Problem
Then, my problem is that after the right_item is tapped, other items are clickable during delay(5000).
I don't want them to change their images during delay(5000).
How to do it?! Thanks in advance.
You can achieve this by adding a flag at time when user click right image then make that variable false. As such after the delay before moving to the next fragment make it true again.
boolean flag = true;
then in your item click method
view.setOnClickListner {
if (flag) {
if (rightimageclicked) {
flag = false;
delay {
flag = true;
// Move to other fragment
}
} else {
// change the image for wrong click
}
}
}
The simple trick you can use is make a FrameLayout or View that overlaps on the RecyclerView. Set ists visibility to GONE. Then inside activity or fragment where you can access this FrameLayout or View which is overlapping, add an empty OnClickListener on this view.
*viewId*.setOnClickListener { }
Now set its visibility to VISIBLE when you call delay. When delay finished again set its visibility to GONE
This is what I understood, you want to lock the entire screen (make all items or buttons unclickable) when you are in delay(5000).
This is what I would do, give a CLICKABLE overlay view on top of recycler view and toggle its visibility. I used the same for locking the entire screen while making an API call.
view_overlay.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rl_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:clickable="true"
android:focusable="true"
android:elevation="5dp"
android:visibility="invisible">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#android:color/transparent"
android:indeterminateTint="#android:color/transparent" />
</RelativeLayout>
Obviously you can replace ProgressBar with just View to get a transaprent view.
To include it in your main view, give this at the bottom of your parent layout or below recycler view. Whichever you choose make sure you have the overlay view on top of recycler view.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
...
...
<include layout="#layout/view_overlay" />
</RelativeLayout>

How do I get SwipeRefreshLayout to not trigger before I lift finger, and show a "swipe to refresh text"

I have implemented a SwipeRefreshLayout on my ListView, and it is working, but not how I want it to.
First of all, the refresh triggers before I lift my finger, which doesn't feel right because it moves the content back to the top even though my finger is still sitting in swiped down position. Also the distance to trigger is really short and setDistanceToTriggerSync from the docs is not available to me for some reason.
second, I'd like some sort of view the be displayed in the gap when my list view is pulled down, like a text that tells the user "swipe down to refresh" or a an animation (like the dancing ghost in snap chat). How do I set this View
Here's what I have
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dashboardRootLayout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/lvDashboard"
android:background="#ffffff"
/>
Why isn't the setDistanceToTriggerSync available?
Anyway the default behavior of the SwipeRefreshLayout does not have that extra view, it just has a special progress bar and a listener for refreshing and showing or not the progress of refresh. Also it can change the look of the actionbar with the refresh message.
Possible solution:
If you want that special view, of the top of my head I can think of having the list being moved down with animation and creating or putting VISIBLE the view you want to show on the top of the SwipeRefreshLayout.
SwipeRefreshLayout swipeRefreshLayout=(SwipeRefreshLayout)findViewById(R.id.dashboardRootLayout);
swipeRefreshLayout.setOnRefreshListener(new OnRefreshListener()
{
#Override
public void onRefresh()
{
// do animation
// set the view you want to show VISIBLE
}
});
You could actually implement all of this by yourself without the SwipeRefreshLayout since you don't want the default behavior.
}

How to disable click listener of button if there is overlay

I am using frame layout and linear layout overlay, when click on overlay so button click listener is also invoked, kindly let me know how to handle this.
<LinearLayout
android:id="#+id/logLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/transparentBlack"
android:orientation="vertical" >
<com.valspals.classes.ButtonStyleM700
android:id="#+id/logDone"
android:layout_width="325dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginTop="25sp"
android:background="#drawable/btn_confirm_normal"
android:text="#string/iamdone"
android:textColor="#color/White"
android:textSize="#dimen/normalTextSize" />
<com.valspals.classes.ButtonStyleM700
android:id="#+id/woops"
android:layout_width="325dp"
android:layout_height="35dp"
android:layout_gravity="center"
android:layout_marginTop="15sp"
android:layout_marginBottom="25dp"
android:background="#drawable/btn_confirm_normal"
android:text="#string/woops"
android:textColor="#color/White"
android:textSize="#dimen/normalTextSize" />
</LinearLayout>
above this there is frame layout, basically its a parent layout. behind this layout i have two buttons and problem is that they are click able from this linear layout overlay
There are several options you could use for this. The easiest would be setting a global variable and checking it when onClick is called.
i.e. you have a boolean overlayShowing = false;
In your event listener, just check for !overlayShowing
However, that will still allow the button's click animation to show. If you want to prevent that as well, you could intercept the touch events on the top layout (your FrameLayout) and prevent them from being passed to the below layouts if the overlay is visible.
e.g. In your overridden FrameLayout:
#Override
public boolean onInterceptTouchEvent(MotionEvent e){
return overlayShowing;
}
This will intercept the touch event and prevent it from passing it on the chain when the overlay is showing.
If your overlay is only shown by toggling the View's visibility, you could simplify that even further by checking the FrameLayout's visibility in the onInterceptTouchEvent() method. e.g.
#Override
public boolean onInterceptTouchEvent(MotionEvent e){
return getVisibility() == View.VISIBLE;
}

ProgressBar at the bottom of gridview

I have a GridView which shows a grid of 15 Views for the first time. Then, on click of a button, I add 5 more grid views. So, my question is: How to add a ProgressBar at the bottom of a page, when those 5 Views are loading ? Like a spinner loading and the 5 Views get updated.
Hi i have a tab host tabwidget for tabs and gridview inside framlayout..now if i want the progressbar then should i need to inclue this linearlayout after frame layout or inside frame laoyout?
Add this below your GridView in the XML.
<LinearLayout
android:id="#+id/linlaProgressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<ProgressBar
style="#style/Spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp" />
</LinearLayout>
And in your Activity, where you are loading the data (assuming, it is an AsyncTask), in your onPreExecute() show it:
#Override
protected void onPreExecute() {
// SHOW THE BOTTOM PROGRESS BAR (SPINNER) WHILE LOADING MORE PHOTOS
linlaProgressBar.setVisibility(View.VISIBLE);
}
And in the onPostExecute(), hide it:
#Override
protected void onPostExecute() {
// SHOW THE BOTTOM PROGRESS BAR (SPINNER) WHILE LOADING MORE PHOTOS
linlaProgressBar.setVisibility(View.GONE);
}
If you are not using an AsyncTask, then set the visibility to View.VISIBLE at the start of the method where you start downloading the data and set it to View.GONE either after or just before you set the Adapter.
EDIT: Adding additional info.
Couple of things.
You are downloading data off the Internet for which, I would recommend switching to AsycnTask instead of using a conventional () Method.
Check out my answer a few days ago on a similar question here: https://stackoverflow.com/a/13265776/450534
In that answer, you will find a complete solution that will suit your exact needs. Well, almost entirely anyway. You may have to make a few modifications and adapt to a few things yourself. But by and large, it will answer all your questions. I use it in my apps and they function as you say, the Google Play loading text at the bottom. And it really is complete. :-)
You need to create custom view for that and inflate it and add as bottom view in gridview
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<Button android:text="Load"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<ProgressBar
android:layout_width="25.0dip"
android:layout_height="25.0dip"
android:layout_centerInParent="true"
android:visibility="gone"
/>
</RelativeLayout>
now inflate this view and show the progressbar at bottom of gridview
You can set button as bottom with this when you click just visible the progressbar
Just add a ProgressBar in your layout, set its visibility to VISIBLE or GONE whenever you want to show/hide it.
Add a in the xml of GridView and set its property "alignParentRight = true" and "visibility = invisible" . In your activity , use Async task class and on its preExectue method set set its visibility to visible
pb.setVisibility(View.VISIBLE);
In doInBackground method load your images and finally in onPostExecute method make this progress bar invisible.
pb.setVisibility(View.INVISIBLE);
execute this async task class on click of load button.
This is an easy tutorial for understanding asyncTask
http://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/
Or threads can be used instead of async task.

How to use layout weight when you want to toggle one of 2 visible views

I have a LinearLayout that will have a cancel button and a progress bar, where the progress bar is 70% and the cancel button is 30%, like so:
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ProgressBar
android:id="#+id/uploadProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_weight=".7"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
/>
<Button
android:id="#+id/uploadCancelButton"
style="#style/TitleBarButton"
android:layout_width="0dp"
android:layout_weight=".3"
android:layout_height="wrap_content"
android:text="#string/cancel_btn"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
This works fine, however I realized that actually I either want to show the progress bar or a text view, where the text view could be a small status message (if say the upload failed).
I tried putting a TextView in the the above LinearLayout and having its visibility set to "gone" by default and with the weight set the same as the progress bar. In the code I would only set either the progress bar to visible or the text view, and the other I would set to gone. However the android system appeared to contribute the invisible items weight to the total. I even tried using android:weightSum="1.0" in the LinearLayout xml attributes but that then my button was no longer visible as even though the text was gone, it took space.
ViewFlipper is what you are looking for.
It is very simple to use. You put the views you want to toggle inside the ViewFlipper exactly the same way like you would place them within a Layout inside XML. Then from code you call setDisplayedChild() on the ViewFlipper object containing your views. The parameter of this method is the index of the view that you want to be shown.

Categories

Resources