PullToRefresh list with pinned section header - android

Does anyone has practice of using Pull to refresh list with Pinned section header?
I use Android-PullToRefresh lib with my list and I want to add ability of showing pinned section header at the top of list. I used PinnedHeaderListView lib in another project for pinned section. But I can't combine these two libraries into one.
Is Android-PullToRefresh can show pinned section header? Perhaps any other Pull to refresh lib can do it?

It's possible to integrate the Actionbar-PullToRefresh library with the StickyListHeaders library, but you need to use a custom Delegate in order to get Actionbar-PullToRefresh to work correctly:
public class StickyListViewDelegate extends AbsListViewDelegate {
#Override public boolean isReadyForPull(View view, final float x, final float y) {
StickyListHeadersListView sticky = (StickyListHeadersListView) view;
return super.isReadyForPull(sticky.getWrappedList(), x, y);
}
Integrated like so:
StickyListViewDelegate delegate = new StickyListViewDelegate();
ActionBarPullToRefresh.from(getActivity()).theseChildrenArePullable(mListView)
.useViewDelegate(StickyListHeadersListView.class, delegate)
.listener(this).setup(mPullToRefreshLayout);
The reason that the two libraries don't work together is because the StickyListHeadersListView class does not actually extend ListView (which is what the Actionbar-PullToRefresh library looks for when assigning a delegate by default).

I did some research and I found 2 alternatives:
StickyListHeaders. This library is contributed by Jake Wharton (reference) so it is promising and could be compatible with other libraries. You should try to use it.
PinnedSectionListView - easy to use ListView with pinned sections for Android.
You can try combining these two libraries with ActionBar-PullToRefresh. I suppose you can implement the solution ;)

You can use a combination of SwipeRefreshLayout of support-library and the PinnedHeaderListview.
In your XML file, use like following:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/pinned_lisview_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<za.co.immedia.pinnedheaderlistview.PinnedHeaderListView
android:id="#+id/event_items_lisview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</za.co.immedia.pinnedheaderlistview.PinnedHeaderListView>
</android.support.v4.widget.SwipeRefreshLayout>
And then in java code, just write codes for your PinnedHeaderListView as usual. Finally just put a Refresh Listener for your SwipeRefreshLayout like below:
pinned_lisview_container
.setOnRefreshListener(new OnRefreshListener() {
#Override
public void onRefresh() {
// do your refresh tasks here
}
});
You are done.

SwipeRefreshLayout + any other suitable library that you would use can do the job.
I would prefer PinnedSectionListView beacuse it uses Listview and it has it its pros in terms of UI/UX.

Related

Why does the Scroll event unnecessarily fire when a ListView is loaded in (Xamarin.)Android?

I am working on a Xamarin.Android app. I have a ListView that has the following code:
OnCreate
{
//other code here
listView.Scroll += ListView_Scroll;
}
private void ListView_Scroll(object sender, AbsListView.ScrollEventArgs e)
{
throw new NotImplementedException();
}
(I simply added the Scroll += ... and the Empty Project to the Custom Row Views project of Xamarin Android.
Immediately when the list is loaded, it throws the NotImplementedException. Even when Adapter is null, it still scrolls!
Why does it scroll when it does not need to? The ScrollState also changes to Fling.
Can someone explain why this happens? I am working on an app that uses this event and this is very annoying to work around.
I don't know if this also happens in Android but I assume it does, that's why I have tagged Android, as well.
ListView in Android doesn't inherit from Scrollview but is very similar to the same
The list-view module is using android.widget.ListView for its Android implementation while behind ScrollView lies android.widget.HorizontalScrolView (or vertical) so basically we have two different native controls with different implementations. Comparing to HorizontalScrollView, the ListView for Android presets much more functionality for listing data and also has specific optimisations so this is the logical choice to implement in nativeScript as well.
Secondly it throws that exception because you have the following line in your scroll event :
throw new NotImplementedException();
Removing this should solve your problem for the most part.
Why does it scroll when it does not need to?
What actually happens here is that the listview Scrolls To the current Position
Goodluck Happy Coding!

Butterknife OnClick with TabLayout

I just got a hold of Butterknife and have been trying my best to standardize all of my 'OnClick's to be bound via Butterknife.
I have found though, that it's difficult to follow Butterknife's standard binding pattern when dynamically populating views (via adapters for example) since the individual views don't have id's
#OnClick(What Do I put here if I have no ID?)
public void OnClickMethod(View view) {
//Body
}
Specifically, I'm having problems adding onClicks to views that are part of a TabLayout. I know I can use the built in
TabLayout.setOnTabSelectedListener()
But ideally I'd like to be consistent in binding all forms of onClick via Butterknife. Is there a clean way of doing this?
Set an id in res/values/ids.xml like :
<item name="my_view" type="id"/>
And then add the id to the view :
myView.setId(R.id.my_view);
#OnClick(R.id.my_view)
public void OnClickMethod(View view) {
//Body
}

Displaying settings internally represented with sections in Android Listview

I'm writing an application for iOS and Android in parallell and I am facing a small problem.
I am displaying a list of settings to the user and the settings data is internally represented in settings for section, like this:
Section
Section object
Section object
Section
Section object
etc.
In iOS, when the user clicks a setting object, or when the system wants to paint the view for it, it calls a method with an NSIndexPath object. For example:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and the sections are handled automatically.
In Android, the listviews are "flattened", lacking better terminology. So that a method is called only with a row index:
public Object getItem(int position);
Now it is actually a quite hard problem to solve trying to represet sections directly in the Adapter (MySettingsAdapter extends BaseAdapter).
Right now this problem is solved by flattening the entire underlaying data structure, but it's a lot of duplicated code for almost nothing. The nicer solution I can think of is to do something like the following in my MySettingsAdapter:
class MySettingsAdapter extends BaseAdapter {
MyInternalDataStructure settingsData;
int sections;
int rowsForSection[sections];
public MySettingsAdapter (MyInternalDataStructure settingsData) {
this.settingsData = settingsData;
this.sections = settingsData.sections;
for (int i = 0; i < sections; i++) {
rowsForSection[i] = settingsData.settingsInSection[i].size();
}
}
#Override
public Object getItem(int position) {
int sectionFromPostion;
int rowFromPosition;
// Calculate section and row here...
return settingsData.getSetting(sectionFromPostion, rowFromPosition);
}
}
And I just can't get the calculations for sectionFromPostion and rowFromPostion right...
Unfortunately Android does not have quite the same ability in regards to sections as you can achieve with the UITableView. However Android does provide a solution, the ExpandableListView. While similar to a ListView it works a bit differently and interacts with a different type of adapter.
Android provides the SimpleExpandableListAdapter that you can use with the ExpandableListView. I'll warn you now. It's clunky and pretty restricting. Additionally, it requires you to organize your data into a List of Maps which in itself can be a pain to do.
Alternatively, you can create your own adapter for the ExpandableListView by implementing the BaseExpandableListAdapter. It's very similar to implementing the BaseAdapter. It just has a few extra bells and whistles to support a tier like structure.
Basically all these Expandable...[foo] classes introduce the idea of having a group (the section) and children (the data under a section). Instead of having an index to the data in your adapter, you'll have a groupPosition and a childPosition. Meanwhile the ExpandableListView has this sorta murky middle notion of positions as it works with group/child positions, packed positions, and flattened positions.
As a side note. Depending on how your data is organized, I'd suggest checking out the Rolodex Adapters found in this 3rd party library. They are meant to make working with ExpandableListViews easier and has plenty of code examples and a demo app to help get you going.

ListViewAnimations library - Animate additions?

I've been having trouble implementing the animate additions functionality of nhaarman's ListViewAnimations library.
As specified in the wiki, I'm using the DynamicListView, and my ArrayAdapter implements Insertable.
However, things aren't working. A couple of questions:
Do I use a normal ArrayAdapter or do I have to use the library's ArrayAdapter? I've tried both. I suspect the correct answer is to use a normal ArrayAdapter and override the following function:
public void add(int i, #NonNull Comment comment)
If that's the case, what do I have to put inside this function? notifyDataSetChanged()?
Do I have to wrap my adapter in of the AnimationAdapters?

Drag and drop sorting of cursor adapter and list adapter

I'm very surprised there is such a small amount of info on drag and drop sorting with a cursor adapter and list adapter.
The closest post I have found on stackoverflow is this one:
https://stackoverflow.com/a/5047618/317889
But, it's not clear to me how to implement what CommonsWare suggests - clarification would be very helpful.
So far I am binding the cursor data to a list adapter and setting this as follows:
mMyCursorAdapter = new MyCursorAdapter(getActivity(), null);
setListAdapter(mMyCursorAdapter);
getLoaderManager().initLoader(0, null, this);
The list is generated but I now wish to add drag and drop functionality to the list items.
I would like to know the best way to go about this from an architectural point of view and any pointers as to how to go about the development of the core functionality would also be useful.
This blog post by Jason McReynolds (including a sample project) helped me a whole lot.
It explains how to use Carl A. Bauer's Library Drag-Sort-ListView with a CursorAdapter and SqLite. It shows how to save the the ListView's newly ordered state in the database as well.
This can definitely be achieved and lucky for you most of the work has already been taken care of, but you will need to modify a class slightly to meet your specifications.
The default Android music app has all of the classes you'll need.
First, you'll need to grab their custom ListView that allows for dragging and dropping.
That can be found here - TouchInterceptor.java.
You'll also need to grab their custom Cursor that's used to actually move the items in your ListView. It's an inner class called NowPlayingCursor.
That can be found here - TrackBrowserActivity.java
NowPlayingCursor extends AbstractCursor and its used to return the queue. The method makeNowPlayingCursor() is specifcally where you'll write most of your own code. Instead of returning the queue, you'll need to return the items you interested in moving, whatever they may be.
In order to use the TouchInterceptor, you'll need to implement TouchInterceptor.DropListener.
private TouchInterceptor.DropListener mDropListener =
new TouchInterceptor.DropListener() {
public void drop(int from, int to) {
final NowPlayingCursor mNowPlayingCursor = (NowPlayingCursor) YOUR_CURSOR;
mNowPlayingCursor.moveItem(from, to);
// Call `notifyDataSetChanged` here.
}
};
You should also look their moveQueueItem method used to move an item from one index to another. This method is used in the NowPlayingCursor when onMove and moveItem are called.
That can be found here - MediaPlaybackService.java
So, there's some work to be done on your part, but this definitely possible.
Here is a library that hopefully will solve your problem, it enables drag and drop reordering of list items.
Has an excellent demo that includes use cases for Fragments and Cursors
https://github.com/bauerca/drag-sort-listview
Key features:
Clean drag and drop (no visual glitches; I hope!).
Intuitive and smooth scrolling while dragging.
Support for heterogeneous item heights.
Public startDrag() and stopDrag() methods.
Public interface for customizing the floating View.

Categories

Resources