Image View inside CollapsingToolbarLayout , but click event is not triggering.
How to to solve this issue.
Just make sure you don't have any view above the layout. In my case I had a toolbar and it was eating the clicks.
<android.support.design.widget.CollapsingToolbarLayout
>
<include...
/>
<android.support.v7.widget.Toolbar...
/>
<android.support.design.widget.TabLayout...
/>
</android.support.design.widget.CollapsingToolbarLayout>
I had to create a new Class extending toolbar that let clicks go through it(How to click views behind a Toolbar?)
public class NonClickableToolbar extends Toolbar {
#Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}
Question is not elaborate enough, but looks like ImageView is consuming your click event.
try using
ImageView.setOnClickListener(null);
CollapsingToolbarLayout should get the click events. if this doesn't work, you know on what line to Google for.
Try to add this XML attribute
android:descendantFocusability="blocksDescendants"
to your CollapsingToolbarLayout
I happened to drop by this problem too. It seems clicks in the area of the toolbar/appbar do not trigger.
If your UI/UX allows, try placing the ImageView outside the area of the toolbar. For example, try placing it aligned to parent bottom. The click should hopefully be triggered. Worked for me (I was working with an ImageButton though, but pretty sure ImageView should also work).
You can put the ImageView outside collapsing toolbar. I was facing the same issue. Solved it by placing the view outside collapsing toolbar and anchoring it accordingly.
Related
Im searching for a specific Layout which I couldnt find in the internet. It somehow looks like a CoordinatorTabLayout but without collapsing while scrolling down/up. I founded this View in the App "BlackMusicPlayer" which looks like this:
When youre going to tap on the Picture the View is expanding. Should I create a new Layout from scratch or is there anything out there I could youse? Thank you
CoordinatorTabLayout is a custom composite control that quickly implements the combination of TabLayout and CoordinatorLayout.
may this github sample helps you
you can get reference of appBarLayout and try this
AppBarLayout.LayoutParams p = (AppBarLayout.LayoutParams) toolbar.getLayoutParams();
p.setScrollFlags(0);
toolbar.setLayoutParams(p);
Use coordinator layout with collapsing toolbar , and this will keep the collapsing toolbar always expanded
I was using Collapsible Toolbar in my app. On activity launch Collapsible Toolbar is expanded state with scrolling enabled and its working well normally. But now I have a requirement to show a full screen error layout in case my API fails. In that case I have to collapsed toolbar with scrolling effect blocked.
Error Layout shows a Retry Button. On Retry I make API call again and if API gives success I have to again expand Toolbar and enable scrolling effect.
I was able to collapse toolbar with setExpanded(flag, animate) but in that case I am not able to block scrolling effect of Collapsible Toolbar while error layout is shown.
I need to provide a way to block as well as unblock scroll effect + Expand/Collapse Toolbar. Any help would be really appreciated.. !!!
Make your error layout such that it will overlap Collapsible Toolbar. Also set android:clickable="true" to your error layout.
When you set visibility to your error layout, set Toolbar scrolling accordingly.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f3f3f3"
android:orientation="vertical"
>
<!-- Add your other layout including Collapsible Toolbar here.-->
<RelativeLayout
android:id="#+id/errorLayout"
android:clickable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
I created a library AppBarrr to lock the screen in expanded mode, based on my previous answer.
As I said, the height of the Toolbar is the key: the CollapsingToolbarLayout will collapse until the Toolbar's height and will expand until the AppBarLayout's height.
With this library, you must set two layouts as the Toolbar and your Expanded Layout (used to lock the screen and the scroll), it will create a CollapsingToolbarLayout and inflate these layouts inside.
You can declare the animations duration, the color of the inner CollapsingToolbarLayout, the collapsed/expanded title's style, even the height of the locked layout... You could also hide the Expanded Layout if you click outside it. It can support NestedScrollView and ScrollView inside the Expanded Layout. The documentation and a sample app are available on Github.
For those who don't want to use the library, my previous answer shows the way to do it. Here's the output of the previous answer:
Basically, this is the same concept, but no need to write a full class, with the lib you just need to have a simple widget in xml and that's it!
Feel free to use, fork or test. Hope it will be useful ;)
If you use AlertDialog to communicate the error and a ProgressDialog (spinner) to show you are doing stuff, you can block user input while your app is doing it's thing.
A simple solution that you can apply is just use the property
android:visibility="gone"
for the content that you don't want to show and just make your error layout visible by using property android:visibility="visible"
place the error layout at the bottom of your parent layout
once the contents are not visible on screen and error layout is just visible you will achieve the desired result that you want. Hope this helps you.
You can implement the interface and call its methods when to enable or disable the collapsing effect.
public interface AppbarRequestListener {
void unlockAppBarOpen();
void lockAppBarClosed();
}
#Override
public void unlockAppBarOpen() {
appBarLayout.setExpanded(true, false);
appBarLayout.setActivated(true);
setAppBarDragging(false);
}
#Override
public void lockAppBarClosed() {
appBarLayout.setExpanded(false, false);
appBarLayout.setActivated(false);
setAppBarDragging(false);
}
private void setAppBarDragging(final boolean isEnabled) {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
#Override
public boolean canDrag(AppBarLayout appBarLayout) {
return isEnabled;
}
});
params.setBehavior(behavior);
}
We've all been advised against nesting views that contain a scrolling mechanism. However, in the latest Android release (5.0), the Phone app caught my attention with what seems to be a ListView inside of a ScrollView.
What really intrigued me was that the scrolling mechanism switched from the ScrollView to the ListView seamlessly.
Notice the content above the tabs is pushed out of view before the actual ListView begins scrolling.
I've tried duplicating this myself, but ended up unsuccessful. Here is the basic approach I was taking...
With a single, continuous touch event (no lifting of the finger) ...
As user scrolls, the ListView slowly covers up the ImageView. Once the ImageView is 100% covered and the ListView takes up the entire screen, the ListView begins to scroll.
I'm currently listening to touch events on the ListView and if the top has been reached, call requestDisallowInterceptTouchEvent on the ListView, i.e.
#Override
public boolean onTouch(View v, MotionEvent event) {
if (listViewAtTop) {
v.requestDisallowInterceptTouchEvent(true);
} else {
v.requestDisallowInterceptTouchEvent(false);
}
return false;
}
The switching scrolling context works, only if you lift your finger and continue scrolling.
Is there a different approach that will achieve the desired effect?
Android 5.0 Lollipop (API 21) added nested scrolling support.
From what I can tell, both ListView (AbsListView) and ScrollView support this now (if running on API 21), but it must be enabled on the scrolling views.
There are two ways, by calling
setNestedScrollingEnabled(true) or with the layout attribute android:nestedScrollingEnabled="true" (which is undocumented)
To learn about how it works, or to support this for a custom widget, the key methods are these:
onStartNestedScroll
onNestedScrollAccepted
onNestedPreScroll
onNestedScroll
onStopNestedScroll
Unfortunately, there is no guide or training which explains how this works other than the JavaDoc itself which is rather light and there are no examples other than ScrollView.
Add latest support package 'com.android.support:support-v4:22.1.1' to your project. And try this:
<android.support.v4.widget.NestedScrollView
android:id="#+id/nScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<FrameLayout ...>
<ListView ... />
</FrameLayout >
</android.support.v4.widget.NestedScrollView>
By default nested scrolling is Enabled.
While trying to figure out how to solve this issue myself, I found this question first; however, the answer didn't really go into too much detail. I did find a lot of good resources, so if anyone else finds themselves looking for this, I'll link them below. A term for this effect is "Sticky Scrolling".
An article talking about "Synchronized Scrolling".
http://www.pushing-pixels.org/2011/07/18/android-tips-and-tricks-synchronized-scrolling.html
A good video showcasing some Android scrolling tricks, "Quick Return" and "Sticky Scrolling".
https://www.youtube.com/watch?v=PL9s0IJ9oiI
Code:
https://code.google.com/p/romannurik-code/source/browse/misc/scrolltricks
And lastly, here is another one showcasing the same effect using a listView instead of a ScrollView.
https://www.youtube.com/watch?v=rk-tLisxSgM
Code:
https://github.com/jatago/list_sticky_scroll_trick
I found an alternative 'trick' which is quite simple... Use only a ListView with an added transparent header.
I have been wanting to achieve the same effect as well. I came up finding a relevant library called ObservableScrollView in GitHub and it requires more work on the back-end via a TouchInterceptFramework but at least it did the job even for pre-lollipop devices. It also supports not only child scrollviews and listviews but also recyclerviews. Here's the link:
https://github.com/ksoichiro/Android-ObservableScrollView
I hope they consider nested scrolling for both lollipop and pre-lollipop devices as a part of their design standard soon. This is a good sign.
This is classic example of dummy layouts. Something not entirely obvious at first look. Basically the scenario is something like this.
Grey Area->FrameLayout
Followed by a listview that fills up the entire framelayout and followed by a imageview that overlaps the top half of a listview. The listview's first item is a dummy item and has a height identical to that of the imageview.
(Note: The actual data starts from the second element)
Next Step is easy
Translate the Imageview as per the scroll of the listview.
I suppose this is the best way to do that whilst avoiding nested scrolling
You can use the following combination of attributes on your ListView to achieve this:
<ImageView ... /> <!-- must be before ListView -->
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="..." <!-- height of imageView -->
android:clipToPadding="false"
...
/>
You don't have to manage any scrolling in your code at all, and it requires no header/dummy views in your list adapter.
I am using something like this and it works ok I think
scrollView.onScroll { x, y ->
Timber.d("ScrollView offset: ($x, $y)")
val height = dashboardChart.measuredHeight
val recyclerView = viewPager.findViewById<RecyclerView>(R.id.recyclerView)
if(y >= height) {
Timber.d("ScrollView enable nested scrolling!")
recyclerView.isNestedScrollingEnabled = true
} else {
Timber.d("ScrollView disable nested scrolling!")
recyclerView.isNestedScrollingEnabled = false
}
}
Where scrollView is parent I am listening onScroll event (it is extension underneath it is viewTreeObserver.addOnScrollListener). Then depending whether I've scrolled initial offset or not I am enabling/disabling child recyclerView (similary ListView or other scrollView) scrolling.
I have two rows of imageViews in a ScrollView. The imageViews all have onClickListener and when i want to scroll in this area it doesn't work. So i guess the Click listeners intercept the scrolling of the ScrollView. What's the best way to change this behaviour ?
My View hierarchy is like this:
<ScrollView>
<RelativeLayout>
<FrameLayout>
</FrameLayout>
<RelativeLayout>
</ScrollView>
in the FrameLayout i put a Fragment which has a LinearLayout in which i inflate other LinearLayouts like this:
productHolder.productLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
}
});
Maybe you could use an OnTouchListener instead of an OnClickListener.
In the OnTouchListener you can check if the action of the motion event was a click and consume the event (return true). Otherwise you can leave the event for other listeners (return false) to consume.
Note, that you might need to add some additional implementation for figuring out which image view was clicked, however without seeing your layout, it's hard to give you a hint how to do it.
I would like to make Android ListView non clickable for sometime, until my AysncTask finished.
So I Used
lv.setClickable(false);
But its not working. ListView still takes clicks. Need help.
What has worked for me is setting two attributes in the XML for my list items. I set clickable="false" and focusable="true". So each of my list items is inflating an XML file similar to this one:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="true" >
<!-- Children here -->
</LinearLayout>
I'm not sure exactly why this works, although this is my guess:
Using just the clickable attribute doesn't work because although the LinearLayout isn't clickable, the children inside it still are. Then the children get the click event but don't use it and forward it up to the LinearLayout.
By making the LinearLayout focusable, it will now take the click event, and then drop it because it isn't clickable.
Hope this helps. If anyone knows for sure why this approach works, please chime in.
Try this instead:
lv.setEnabled(false);
EDIT: ok sorry my fault.
I think the problem is that its not the ListView you are clicking but the View representing each item in your ListView. So try this:
View itemView = lv.findViewTraversal(id_of_your_view);
itemView.setClickable(false);
I hope this works.
did you try setFocusable / setEnabled methods ?
You can in your onItemClick method :
if(!mWorking){
mWorking = true;
//do the job...
}
You can try to implement a SimpleOnGestureDetector and override the onSingleTapConfirmed method. There is a lot of tuts on google.
I hope this will help you