I've a ListView with items containing information about places with a rating and the distance to the current location.
The items are sorted into groups:
Group 1: within 500m
Group 2: 500m - 1km
Group 3: 1km - 1.5km
...
Withing these groups the items are sorted by their rating.
Now I put out these items via my custom adapter (extension of BaseAdapter) into the ListView, which works perfectly.
However, what I'd like to do is to put a separator before the each first item of each group. This separator can be a TextView saying e.g. 500m - 1km followed by all the ListView items in that group.
Any idea on how to realize this?
Here is one implementation that does exactly what you describe.
That one is GPLv3, because it is derived from this implementation, which was GPLv3.
You can also use my MergeAdapter for this, which has the advantage of being Apache License 2.0. Just hand it an alternating set of header TextViews and Adapters containing each section's worth of content.
Or, you can peek at all of these and roll their behaviors into your existing Adapter class. The trick is to return your TextView headers at the right spot, and properly implement methods like getViewTypeCount(), getItemViewType(), areAllItemsEnabled(), and isEnabled().
Here is even nicer implementation, inspired from iOS section list view : http://code.google.com/p/android-section-list/. The nie thing about it is that the section header remains visible even if you scroll the section down.
Related
I am doing a small Android game where the user needs to assign two players to two teams.
My plan is to use a recycler view which lists all existing players (which are stored in a local database).
The items in the recycler view will be possible to reorder. The first two items in the recycler view will be assigned to team A and the next two items will be assigned to team B. The remaining players will not be considered in a team. The implementation of this logic will be fine, there are also enough examples in the web.
But in order to indicate this logic to the user, I would like to offer him some kind of boxes which indidcate the teams. Like in the following wireframe:
Does anybody have an advice how this should be done? Should I put a View above the recycler view?
Alternatively, I am also open for alternative approaches to assign exactly two players (uniquely) to two teams.
If you want use RecyclerView, you need to include divider in item view, or make divider as item itself.
You need to place these Divider backgrounds below recyclerview, calculate heights of these items and place it accordingly.
I'm aware of the DividerItemDecoration with regards to RecyclerViews although instead of a divider between every item I'm more interested in a divider whenever a certain attribute changes within my elements. For example, a list of transactions that hold the date by which they were posted - a divider would then display at each change in date in the list of transactions.
This is definitely possible but I'm just not sure to go about doing it. For example, in the Monzo application - it's the dates that separate the transaction lines.
Any help would be very much appreciated!
You would create a recycler view adapter with two viewholders. In the example of the Monzo app, you would create one ViewHolder for the purchase and the other for the date. Then in onCreateViewHolder you would inflate the correct type of viewholder for that item in that list.
One way you could do it is to add the divider to the ViewHolder layout, defaulting to View.INVISIBLE (or View.GONE if you want it to take up extra space when it's visible - like the divider is outside the list element instead of inside at the top edge)
Then in onBindViewHolder you could do a bit of logic to decide if the divider should be set to visible or not for that item - something that decides if it represents a date change, and make sure to check it's not the first item in the list too (don't want a random divider up there)
I have been working on an app that adds views programmatically to a linear layout.
The problem is if I add too many views it will go off the screen.
I would like to know how to check if a certain child has hit the end of the same view group so I could add it into another layout (a linear layout below the first one) before it "flows" and go off the screen. How might I accomplish this?
Rather than reinvent the wheel yourself, I suggest that you check out the FlexboxLayout project by Google: https://github.com/google/flexbox-layout
A FlexboxLayout will automatically give you the behavior you're describing, plus the potential for much more.
Well, there are a good number of ways you could implement this in android other than going through this hustle. What ever you are trying to do at the moment may fall under one of the following cases.
Creating views programmatically most likely means you have a dynamic data set probably from an external source.
Your dataset is limited or static but just more than the average screen can display.
if any of the above apple then you are better off using a ListView or RecyclerView (Recommended). That way your data is full displayed as a scroll-able list and you don't have to worry about some items or views not showing or going of the screen. This can range from simple string list to complex nested views.
This will be very efficient as it will automatically handle optimization and usage of memory as well as performance.
is it possible to make an expandable list within an expandable list
i am making a recipe application and i've three expandable lists of the same type - vitamins, minerals and macro-nutrients created with expandablelistview with android studio
is it possible to put these three expandable lists under an expandable list called nutrition and if so could you briefly outline how please. thanks in advance
Short answer, yeah you can but you really really shouldn't.
I've tried this before and it didn't end well, I can't remember the exact reasons but conflicts arise between touch listeners and the measure passes when trying to layout the views inside the different adapters don't calculate correctly.
You can find a number of custom ExpandableLists trying to do what you want around the web but I found they also had similar issues.
What I ended up doing was building my own expandable listview. If you check the source code for Android's ExpandableListView and ExpandableListAdapter you'll find that it's basically
just a regular listview
a list of items that are visible
an Async filter for the data source
some meta data to tell if its a child or group, expanded or collapsed, etc
So if all your item are collapsed the visible list only contains the Group Items.
Expand a Group Item and the async filter gets triggered and populates the visible list with the Group Items and the Children of the expanded Group Item.
Depending on the meta data it will call either getGroupView or getChildView.
So if you want you can take a shot at writing your own.
I wrote a blog post for an ExpandableList that I wrote that does, in theory, infinite levels of expansion. NLevelExpandableListView
I'm writing an Android app that reads a single text file and display it on a TextView.
What I'm doing right now is read the whole file into a String (using BufferedReader and StringBuilder) and display it on a TextView using setText(string). A 700KB text file can take about 2 to 3 seconds before it is being displayed on the screen.
But I've used some other ebook readers on the market and they can display the same text almost instantly. Anyone know how I can achieve this?
Thanks you.
Edit: Many suggest ListView, but it doesn't work for my particular case. This is from my reply to one of the answer: ...[ListView] doesn't work for me for a few reasons. (1) To make the Listview look like a TextView, we have to break the text up on new line character. If I load a single large paragraph, it's just as slow as a loading a TextView. (2) Since a ListView only measures the item on the screen, I cannot know ahead of time the total 'pages' or 'height' of the entire text.
Essentially, the key is to only load the data that you need, when you need it. One way to do this would be to put every paragraph into it's own TextView, which is put into a ListAdapter, which is included into a ListView. There has to be some kind of an index set in place, such that each paragraph knows where in the data file to find. This interface will allow you to load only what you need, when you need it. Your list adapter looks something like this (This code isn't complete, but it should give you an idea at least of what you should do):
class ParagraphAdapter extends ListAdapter{
ArrayList<Integer> mLocations; // Somewhere define this to your locations, I'll leave that for you to figure out
protected View getView(int position,View convertView, ViewGroup parent)
{
mLocations.get(position); // Read the file starting at this position, until the next value
String text; // This is the output of the above
TextView tv=new TextView(context);
tv.setText(parent.getContext());
}
}
It can be noted that Amazon uses a system of paging for the Kindle App. If you have the app, you can see at the bottom of each page what section you are on. Each "page" is probably closer to a sentence or so in length. Then it's just a matter of getting the right page, which can fairly quickly be done.
To add on what #PearsonArtPhoto has said -
I suggest you implement some sort of paging mechanism, to divide your text into pages.
What you should do is split your text according to let's say N +M number of characters per pages.
N = fixed number of characters.
M = number of characters from N to nearest end of line character (so you won't see the last
line being "cut").
I would suggest that if your android device allows you to hold this "in memory" - do that,
and don't try to fetch this from the file one page after the other, but rather fetch from the "in memory" structure - this will improve performance.
Once you scroll and realize you need to fetch the next page, fetch it from the "in memory" structure.
You can use Android Paging Library from Jetpack with custom View or RecyclerView
https://developer.android.com/topic/libraries/architecture/paging
Implement DataSource abstraction that provides List of data ranges
Implement Storage abstraction that provides real data (from Database, Network, Files, etc)
Use RecyclerView and Adapter to display data
Sample app to display content of large files can be found here
https://github.com/YablokovDmitry/FileView
Lucas Rocha built a nice library called Smoothie for that purpose.
http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/
At the end of those performance tips for Android listview there's a link to an explanation about Smoothie and finally you'll find the library available on github.
Originally described for loading images, the approach applies for loading text as well.
You must to consider if you are using right components.
Maybe it is mutch better to read lines and put them to listview.
try
List<String> lines;
listview.adapter(new ArrayAdapter<String>(...,lines));
And many times that what you see (Look and Feel) is not like you are think.