I am trying to create a WearableListView similar to the one in the default Settings app. I have a WearableListView that scrolls, and animates each element. All I need now is a header on top of the list that scrolls up when the list scrolls. This is the same behavior that the title 'Settings' has in the Settings app.
The only method I have found to do this, used here: How to Set the Layout for topEmptyRegion, implements a WearableListView.OnScrollListener(). Then uses the onAbsoluteScrollChange() method to set the displacement of the TextView used as a header. But, according to the Android Developer References, this method is deprecated. The documentation even states: BE ADVISED DO NOT USE THIS This might provide wrong values when the contents of a RecyclerView change.
I would like to know if anyone else has found a way to implement a header that behaves this way, one that is not deprecated. Possibly something that I missed in the Android Wear documentation?
EDIT:
I tried to implement this method anyway. As it turns out, WearableListView.setOnScrollListener() would not take a new WearableListView.OnScrollListener(). Instead it asked for its parent RecyclerView.OnScrollListener, which does not have a onAbsoluteScrollChange() method. It does have an onScrolled() method, which I tried to implement. As it turns out, this completely overrides the default scroll listener for WearableListView and makes it so the centered item can be off-center. Definitely not the effect I was looking for.
Since onScroll() is not deprecated, you may be able to accomplish the same by implementing that in your listener:
#Override
public void onScroll(int scroll) {
header.setY(header.getY() - scroll);
}
where header is the header component.
EDIT: Make sure you use WearableListView.addOnScrollListener not WearableListView.setOnScrollListener()
Related
According to this commit, it is possible to rewrite drawer's RecyclerView with a custom one but I can't figure out how to do it.
Can anyone explain to me how to do it properly?
You can provide any RecyclerView you want with withRecyclerView(). This will then be picked instead of the default implementation. Just provide a RecyclerView object (which you have retrieved via a LayoutInflater or created programmatically) set the LayoutManager the Animator and everything else you need.
If you are interested what happens in the default behavior follow this link:
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1576
As of your issue. It is also possible to just retrieve the default generated RecyclerView after the Drawer was built, via getRecyclerView(), which will also allow you to adjust some things like paddings, and other things.
See here: https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/Drawer.java#L214
As also discussed here:
https://github.com/mikepenz/MaterialDrawer/issues/1290
I need to make bounce effect to my listview in android.ie when I scroll down listview has to scroll beyond its starting point and the come back to its original position
Please help..
as you not posted your code(I think it is also not required as per your question).
So I am giving a Custom Widget
It is custom widget of listview (not that much complicated, just animation is added into it)use the library for your application.
and also from that in PullToRefreshActivity there is
mListItems.addFirst("Added after refresh..."); statement just remove it if you want..
(don't worry about activity name or class name here target is you got your result)
i.e bounce effect to Listview
If you satisfy..then Please accept the answer..
By the looks of things in the ScrollView API you should be able to override the onOverScrolled() method if you create a custom view that extends the ScrollView class.
I was looking for a ListPreference in which the user can change the order of items from a list. The items would be draggable and can be re-ordered by the user.
I saw this in my custom ROM (and I'm almost sure I saw it in Cyanogenmod) for the QuickPanel. Here's a screenshot to get the idea through:
I know how I can make custom ListView items and set the icon to indicate that the items are draggable, but I don't know how to make them draggable, and change the order accordingly. As for saving them in the preferences, I found this which could be implemented easily.
PS: I know Cyanogenmod is open-source, but I couldn't find the source for this particular thing :( The closest I could get was this, which should be somewhere near the other screen...
Thanks in advance for any tip about this.
UPDATE: I ended up using the files from the accepted answer, with additions and modifications. I am listing them here for further reference.
Use a custom Adapter (ArrayAdapter in my case), to implement the visual feedback that this item is draggable, which is an ImageView near the TextView. This is optional.
Set a DragListener and RemoveListener to update the list accordingly. The ListView does not do that automatically. And it depends on the Adapter you are using.
There was a line that casted a View to a ViewGroup, it made some errors, so I removed the cast without any issue, it was not needed. (in the onInterceptTouchEvent method).
Change mRemoveMode = 1; in the constructor of TouchInterceptor, or one of: FLING = 0; SLIDE = 1; TRASH = 2;. I think for TRASH, a resource should be available too.
I actually took the file not from the answer's link but from the Cyanogenmod one, which I already had, but I guess these files were the same.
These are the actual files in the project (at r12, at the time of writing):
The Preference using this ListView
The ListActivity with the listeners and the Adapter
The actual ListView
I hope it helps somebody else :)
There is no built-in widget to do this, but you may want take a look at the custom implementation used by the AOSP music player to allow for re-ordering of songs in playlists.
TouchInterceptor.java
That's the class which is extending ListView and is responsible for handling all of the MotionEvents and re-ordering its items, as well as detecting swipes for deleting items. You can see it implemented into an activity here in the TrackBrowserActivity.java class.
It has three interfaces you should also be aware of: DragListener, DropListener, and RemoveListener. You can use these interfaces to provide it callbacks to fire for those events, so that you can update changes made to the list order to your SavedPreferences (since the ListView will not handle that for you).
You can easily extend or modify the TouchInterceptor class to add additional functionality since the low-level stuff is all there for you.
I have a ListView with custom rows. When any of these rows is
clicked, the ListView's data is regenerated. I'd like the list to
scroll back to the top when this happens.
I initially tried using setSelection(0) in each row's OnClickListener
to achieve this but was unsuccessful (I believe because the ListView
loses its scroll position when its data is invalidated - so my call to
setSelection is undone. I still don't understand how the ListView
decides where to scroll to after invalidation, though).
The only working solution I know of was given by Romain Guy here:
http://groups.google.com/group/android-developers/browse_thread/thread/127ca57414035301
It involves (View.post)ing the call to _listView.setSelection(0). I
found this to perform quite poorly.
The newly generated list shows up with its scroll location unchanged
and there is a considerable delay before it scrolls back to the top.
Is there any better way to achieve this functionality?
Any help would be much appreciated.
Thanks!
call listView.setSelectionAfterHeaderView(); to scroll to top
I have tried lot but this one worked for me
list.smoothScrollToPosition(0);
I simply use listview.setSelection(0);
Works fine for me.
If you need instant scroll just after ListView adapter's data was changed, pay attention that it might not be yet populated. In this case you should post() your setSelection() or setSelectionAfterHeaderView() via Handler so it will be called later in the queue.
listView.Handler.post(new Runnable() {
#Override
public void run() {
listView.setSelectionAfterHeaderView();
}
});
This worked for me.
Personally, I recommend you find a different UI pattern. It is possible that users will find your current "click, and the list changes in situ" approach intuitive, but I am skeptical.
You could try subclassing ListView and overriding layoutChildren() to chain to the superclass, then call setSelection(0) in the case where that is needed. If the "considerable delay" is due to just the post() call, this should clear it up.
as a workaround, you can create a new adapter containing the new regenerated data, then call ListView.setAdapter. after that call ListView.setSelection(n).
btw, the solution provided by commonsware is worked.
On some different requirement.
If you want to scroll up just like while chatting.
mListView.smoothScrollToPosition(mAdapter.getCount());
This one worked fine when you want to focus the edittext from listview header
listview.setSelectionFromTop(0,0);
If you want to select the particular index view from listview then
listview.setSelection(index); // o for top
Is it possible to apply an expand or collapse animation for expandableListView?
It can be done using a simple ListView that contains an initially hidden view and a custom class that extends Animation.
The basic idea is to start with View.GONE then gradually re-size the margin from a negative value to the required size while setting visibility to View.VISIBLE.
See:
https://github.com/tjerkw/Android-SlideExpandableListView
Android Animation: Hide/Show Menu
How do I animate View.setVisibility(GONE)
..and finally
Cool toolbar for ListView items + source
The last example contains all the code you need. It looks a bit hackish to me, especially the fact that you must initially set view.bottomMargin = -50 or more, otherwise the animation does not work properly the first time, but so far I did not find any viable alternative (apart from using a ScrollView with your own container items instead of a ListView).
And finally, this app includes the above example, among lots of other useful examples with links to sources:
https://market.android.com/details?id=com.groidify.uipatterns
Update: Google removed the app from play store allegedly for intellectual property violation (although it only contained demos and links to open source projects), the author now made the apk available for direct download from http://goo.gl/ihcgs
For more details see https://plus.google.com/108176685096570584154/posts. NB: I'm not affiliated with the author.
I have done a similar job for a simple list view.For doing that I overrode the getView method and applied translate up( or down) animation on each list item.The degree of translation was decided by the position of the list item.
I've found a possible (partial) workaround for this problem.
first you need to store the scroll state of the ExpnadableListView :
#Override
public void onScrollStateChanged(final AbsListView view, final int scrollState) {
this.mScrollState = scrollState;
}
public int getScrollState() {
return this.mScrollState;
}
for the listView itself, you need to store which group was clicked, so that only its children will get animated:
mListView.setOnGroupClickListener(...
#Override
public boolean onGroupClick(...){
mGroupPosition=groupPosition;
now, in the getChildView() method, you check the state of the scrolling , and if it's idle, you start the animation, for example:
public View getChildView(...) {
// <=prepare rootView and return it later
if (groupPosition==mGroupPosition&&getScrollState() == OnScrollListener.SCROLL_STATE_IDLE)
rootView.setAnimation(...)
this will set an animation for the child views each time you expand the group.
the drawback of this are:
only for the expanded child views. you will need to think of extra logic to animate them when collapsing the group.
all animations start at once . you will need to add multiple animations one after another if you wish that it would work otherwise.