How to use the RecyclerView selection library with ConcatAdapter? - android-recyclerview

I am implementing a RecyclerView of notes with a header. To implement the header I used a separate HeaderAdapter and merged it with my NotesAdapter using ConcatAdapter.
The header displays fine. But the multiple selection of notes is now broken, which was working fine before I used ConcatAdapter. I am using the official recyclerview-selection library for implementing multiple selections of notes.
Some strange things are happening like when I select the first note, the onBindViewHolder is called inside the HeaderAdapter and as a result the note's card is not checked.
Has anybody arrived with a similar situation?
EDIT:
I've found the primary problem. When we build the SelectionTracker, the Builder maintins a reference to the RecyclerView Adapter which is taken directly from the RecyclerView instance. As a result, whenever an item change happens, it all happens on the ConcatAdapter which is associated with the RecyclerView.
So I temporarily assign just the NotesAdapter before building the SelectionTracker and then assign the ConcatAdapter to show the header. See the code below:
...
binding.recyclerViewNotes.adapter = notesAdapter
// Setup the Selection API with RecyclerView
setupSelection()
binding.recyclerViewNotes.adapter = ConcatAdapter(headerAdapter, notesAdapter)
...
Now, the selection is working fine BUT with a small bug. On some occassions it selects two items instead of one.
For e.g., if I long press an item at position 0 it also selects the item at position 1.

Related

Intents with extras have a series of params that we don't use - what's their purpose?

From my LandingClass (which contains a ListView called myList), whenever an item from the ListView is clicked, we want to trigger another activity (DetailedActivity), so the code should look like this:
myList.setOnItemClickListener{ view ->
val intent = Intent(this, DetailedActivity::class.java)
startActivity(intent)
}
Now, if we needed to provide additional (extra) info to the Detailed class, such as the position of the element from the ListView that we just clicked, the code would look like this:
myList.setOnItemClickListener{ parent, view, position, id ->
val intent = Intent(this, DetailedActivity::class.java)
intent.putExtra("thePosition (text)", position)
startActivity(intent)
}
So my question is why in case of sending the extra intent, we need a parent and an id, I don't see them being used anywhere... ?
I don't see some examples in the doc to help me understand. So some questions:
What do I need the parent, view and id for?
If I click the 3rd element, the position (int) sent I expect to be 2 if the list is 0-index based, right?
If I wanted to send a Bundle with more complex information than the position, how would my code (with extra) change? Considering that all params have a defined type, like id is type long. WHat if I wanted to send a paragraph of text instead of the id?
https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener - the official docs showing the method signature
From my research (see above link) I noticed that:
parent AdapterView: The AdapterView where the click happened.
Why would we need this? Where is the assignment done, or is it implicitly known?
view View: The view within the AdapterView that was clicked (this will be a view provided by the adapter)
position int: The position of the view in the adapter.
id long: The row id of the item that was clicked.
Still this doesn't clarify how to send additional complex info to the DetailedActivity - not a position (int) or an id (long) but maybe an array of complex objects, or a paragraph of text or something else...
Say that your ListView contains the headers of some news articles.
By clicking on a list item you want to be redirected to a details activity where you can read the full text of the article.
All headers and articles are stored in a List of Article objects, each containing the header and the text of the article.
How will you identify which article's header was clicked?
This is the purpose of the arguments position and id.
Depending on your needs you will choose one or the other, so you will fetch from the List the article's text and pass it as an extra to the Intent that opens the details activity.
You know that you can create very complex ListViews where each item is a container of multiple views or a ListView itself.
This is when you will need the parent and view arguments.
All this is application specific.
If you don't need it fine, but the arguments are there for you to use if and when you will need them.
Now for:
If I wanted to send a Bundle with more complex information
and
Still this doesn't clarify how to send additional complex info to the
DetailedActivity
This is your responsibility to construct a Serializable or Parcelable Bundle and put it as an extra to the Intent and has nothing to do with the available arguments of setOnItemClickListener. There are a lot of examples here in SO and other sites for serializing objects to put as extras, like
Cannot pass custom Object in an Intent: The Method Put Extra is Ambiguous for the type Intent
and
How to send an object from one Android Activity to another using Intents?
Follow the standards and you will be able to send this complex info via intent.

Hiding specific columns within a custom HTML Rally app using the SDK

I'm writing a Cardboard app using the AppSDK within a Custom HTML app. So far, it is displaying properly (rendering all columns, column headers).
Is there a way to target and hide certain columns and their headers from within the Cardboard app code? I can hide them using their CSS ID's.... However, this occurs after the app has rendered and results in a bit of an eyesore as the original app width will not resize.
TL;DR Rally Custom Kanban board (AppSDK) contains 6 User Story states. I want to hide the second and fourth states while still showing the other four.
There's an example in the docs that show how to create a board that has a specific set of columns: https://help.rallydev.com/apps/2.1/doc/#!/example/specific-columns-board
In that case it's doing Owners for columns and some extra stuff with custom rendering of headers, but the guts of it is specifying the columns config to the board, which is just an array of config objects which will be used to instantiate Rally.ui.cardboard.Column objects.

Add Control after Items in GridView Group

I'm currently developing a Windows 8 Store app that uses a Grouped GridView in the HubPage showing Highlights for some Categories. So far, when clicking the Header you see More Highlights for this Category.
Now i want to add a control at the end of every Group leading the User to the "non-highlight" Category site, where just all the Items of this category are displayed.
Is there an easy and elegant way to do this - propably with a Template is suppose.
( i think the latest Bing-News-App has a similar feature )
Thanks in advance for every help.
There are a couple of ways you can do this.
You can add an arbitrary object to the end of your group, then use a DataTemplateSelector to style it.
You can create your own VariableSizedWrapGrid with the control added to the end in the constructor (slash "Arrange"). You can then add an arbitrary click handler as a dependency property and only show the button if the click handler is set, so you can reuse this on other pages, etc.
You can change the GroupStyle to include something similar at the end of the group, but it likely won't animate with the other items in the group (if that's important to you).
The easiest one to do is probably the first one. If your group is a list of SampleItems then make a subclass of the SampleItem class called something similar to TerminalSampleItem. Create a template for it (like you've made other data templates). Make an ItemTemplateSelector that has two properties, NonTerminalDataTemplate and TerminalDataTemplate (assuming you only have two data templates). Have the SelectTemplateOverride function check for (item is TerminalSampleItem);

BlackBerry 10 Cascades app stuck affecting property

I have an issue with a list/detail pattern. I have an Article class, inheriting from QObject, defining some properties (title, updated and content being the ones that matters for now). To populate my (QML) ListView, I have a C++ GroupDataModel, filled with some Article*. Here's my list's onTriggered:
onTriggered: {
if (indexPath.length > 1) {
currentArticle = dataModel.data(indexPath);
var page = articlePageDefinition.createObject();
nav.push(page)
}
}
As you can guess, the articlePageDefinition defines a page using the upper currentArticle property.
Now, when I display the articlePage once, it's working fine. I can go back, click on the same list item, display the same Article details, works great. But when I pick a second article, the app kind of freezes. I can go back in my navigation pane, but I can't click on list items anymore. I tried to add some logs, the onTriggered is stuck on currentArticle = dataModel.data(indexPath);. At this point, I can log every property of dataModel.data(indexPath) without any issue. I tried to not create/push the page, simply affect currentArticle and display some of its properties, it's working fine too. I really don't understand what I am doing wrong here, any help appreciated.
In case you need to see more code, everything is here: https://github.com/Kernald/tt-rss-bb10/tree/e29e3b616aa179dd42f66804ecc20a6a45b6bb22
Here what can cause the problem your are having:
You create the articlePage and bind it's data to the "currentArticle" global variable
When you go back the articlePage is not deleted.
You open an other instance of this same articlePage. The last one still bind its data to the same currentArticle instance.
When you go back and click another item: the previous articlePage still exists in memory. It binds to "currentArticle". The problem is, it's not the data of "currentArticle" that has changed but the object referenced by "currentArticle". The Qml binder just fails then.
I had a similar behavior of my app, but I did not inspect your github code if the reason can be the same. I think you can verify that more quickly than me.
When removing and adding a list item with the same index, the code gets stucked. I removed an entry on user action and added a new one at that place, and it got stuck. This is a known issue to BB10, I found here: https://developer.blackberry.com/cascades/download/releasenotes/#known

Add dynamic tabs in tabbed property view of eclipse

I am trying to create a tabbed property view as per given article : The Eclipse Tabbed Properties View
As per article, org.eclipse.ui.views.properties.tabbed.propertyTabs extension point can be used to add new tabs.
<extension point="org.eclipse.ui.views.properties.tabbed.propertyTabs">
<propertyTabs contributorId="mview.views.SampleView">
<propertyTab
category="sample"
id="mview.ButtonTab"
label="Button"/>
<propertyTab
afterTab="mview.ButtonTab"
category="sample"
id="mview.AdvancedTab"
label="Advanced"/>
</propertyTabs>
</extension>
However in my case the tabs of property view vary depending on the item selected in view. So I have to add the tabs dynamically into extension depening on the item selected.
Please suggest how to do so.
Update:
One of the way to do so (I am not sure if its adviced) is using IExtensionRegistry.addContribution() method. Here I provided an inputstream object containing desired extension details. This added tabs to property view at run time. However with change in selection of item in list viewer, the property view is not updated. Please suggest if this is the right approach to do so.
Ok, I got the solution Its a two step process. Using this one can dyanamically add tabs (and their sections):
Step 1: Associate a tab descriptor provider with the view.
Add an extension point - org.eclipse.ui.views.properties.tabbed.propertyContributor to the view (if not already added). In the propertyContributor section, add a class for tabDescriptorProvider item. This class will implement ITabDescriptorProvider interface.
Step 2: Provide Tabs and Sections:
TabDescriptor provider will return array of TabDescriptors when its getTabDescriptor() method is called. Each TabDescriptor return a list of SectionDecriptors and each SectionDescriptor is linked to a Section. Finally it is the Section class that contains widgets to be displayed on screen. Each widget in Section class has a modify listner which updates the properties of selected items.
While the answer from Viral may not match the specific needs of the OP, the provided answer is likely acceptable to many.
If a tab does not have any sections to display, the default TabbedPropertySheetPage will not show that tab. Thus, if the problem domain is specified in terms of IFilter implementing classes, "dynamic" tabs may be achieved.
Tabs will be added or be removed as the selection changes depending upon whether any sections are present. A visible tab may have one or more sections present on it, and the number of sections on a visible tab may change from selection to selection.
As I came across this page with the same basic issue, I was a bit disappointed that I would need to intervene in the way the OP suggested. After some experimentation, I was able to achieve what I needed purely through the IFilter approach as suggested by Viral.
A tutorial is provided at http://www.eclipse.org/articles/Article-Tabbed-Properties/tabbed_properties_view.html
You need to define a new YourPropertySection derived fromAbstract PropertySection . Also define a filter derived from IFilter and override the select method to return true only for the desired type of selection. Then in plugin.xml write an extension point which would map your PropertySection to the required PropertyTab and will also associate your filter. So this section & tab will only show when your filter returns true.