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

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.

Related

How to use the RecyclerView selection library with ConcatAdapter?

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.

selenium Page factory handle different elements for same page for different users

I have a simple question. I 'm sure many of us might have got into the same situation. I am using page object pattern. Below are the steps i do along the navigation.
Login to my application as one type of user.
Click some link to go form page.
On form page , fills the fields and submit
Logout
On 3) the form object page shows some different input fields depending on the type of the user, which i need to interact with. So how do i deal it within the same page object. Has anybody got into the same situation and have found some decent way of doing this ?
I know it a simple automation script not a Java project where we should be using all oops concepts but still I would go with the following:
Create a parent page class containing the common WebElements and methods.
Create child classes with elements and methods specific to that customer.
In the test, pass a parameter which specifies the type of customer and call the appropriate child class.
If you don't want any of this inheritance stuff, you can also try the following.
Create a page class with elements for all types of customers.
Create generic methods which can take a parameter customerType and perform operations like if customerType==1 do these operations else do these.
Another solution which popped up in my mind, assuming that all fields for a particular customer are mandatory, is as follows.
Create a common class for all elements.
Create a generic method in the page class which follows the condition, if this element is present then enter value.
If you understand the concept of Page object model then this questions will be more clear to you. Yes, inheritance is a big factor here. I suggest you read through this to see how a real page object model should work. And, solution of #3 question is as simple as UI mapping. Something like
#FindBy(how = How.NAME, using = "q")
private WebElement searchBox;
for each elements or similar implementation.
For a complete page object you should map all the elements not depending on the users. The reason being, every time you call that class it will be instantiated and all the mapped elements as well. There is no need of dynamically load the elements If any elements are not used or hidden on the page those will be available and you will not be using them anyway

Core Data and bindings - binding checkbox to result of many-to-many relationship

Core Data model
I have a many-to-many relationship between two of the principal entities; call them Item and Tag. There will be a large number of Documents. Each may have 0 to an arbitrary number of tags.
Each Item entity relevantly has an attribute called name, and a to-many relationship to Tag called tags. Each Tag entity relevantly has an attribute called name, and a to-many relationship to Item called items.
To display them, within the same window, I have: (i) an NSTableView (itemTableView), fed by an NSArrayController (itemArrayController), showing all Items; and (ii) an NSTableView (tagTableView), fed by a different NSArrayController (tagArrayController) showing all Lists.
tagTableView
In the tagTableView, the Table View is bound to tagArrayController, with controllerKey arrangedObjects.
There is only a single table column. The textfield in it is bound to Table Cell View, to model key path objectValue.name. That works so far; it displays all of the lists as expected, and sorts properly when I add a sort descriptor.
Everything has been set up using interface builder in Xcode.
The problem
I have added a checkbox into the tagTableView, in the same table column as the textfield. I am trying to implement two things:
The checkbox should be checked if the user has previously associated the Item with the relevant Tag. If not, the checkbox should be unchecked.
If the user checks an unchecked checkbox, I want to establish a relationship between the two; if the user unchecked a checked checkbox, I want to break that relationship.
The underlying behavior pattern is that the user will not necessarily have control over the tags and may not be able to create them. They are to choose from existing tags, and therefore should be able to see which ones exist, and be able to check/uncheck those that apply.
However, I can't see how to implement this.
Part solutions so far
I can see a possible way to do at least the first task programmatically, roughly along these lines:
Monitor tableViewSelectionDidChange for itemTableView
For a change, update the data source for tagTableView manually, and work out checkbox state by checking them for those Tags which relate to the Item entity that has just been selected, and otherwise unchecking them
However, this looks likely to add complexity, and ideally I would like to do this with bindings if possible.
I have reviewed the Apple Core Data and Bindings references, all the Cocoa books I have, stack overflow and I've also done extensive googling. I have found lots of similar questions (e.g. http://lists.apple.com/archives/cocoa-dev/2011/Mar/msg00164.html) but no answers.
I've also found a way that might work programmatically, but which seems to be like my idea above, at the expense of being able to use bindings (e.g. http://www.raywenderlich.com/14742/core-data-on-ios-5-tutorial-how-to-work-with-relations-and-predicates)
The only relevant question on this site -- Core-Data Check Box Cell with many-to-many data -- is not answered to a level that I can make use of.
It would seem to me that this should be a prime candidate for bindings. I should be able to ask the itemArrayController what Tags (if any) have a relation to its selected item, and then set the checkbox to ticked if it matches the relevant Tag, and unset it if it doesn't. I would expect I should be able to do this within the bindings for the checkbox itself, in interface builder. But I can't work out what model key path or binding to use, or what to set the cocoa bindings for the checkbox to. Am I missing something obvious? Thanks

Additional actions when NSManagedObject is deleted

I have a core data 'ShoppingList' which contains 'Item' objects. I store a display order as an attribute of each item.
I would like to update the display order of all other items in the shopping list whenever an item is deleted. The code to do this is working fine when I use it in my view controller (from where the item is deleted), but since it is really related to the business objects and not the view, it would be better placed in either ShoppingList or Item.
Ideally, I would like it incorporated into the deletion of the item. So far I have tried the following:
1) Customize the standard Core Data generated ShoppingList.RemoveItemsObject (making sure to observe KVO before.after). What's strange about this way is that the item passed is stripped of its relationships to other core data entities before it gets to my code, which I need to process display orders correctly.
2) Customize Item.didTurnIntoFault. Same applies - but even attributes of the item are gone by this stage.
One answer would be to simply define a new method on ShoppingList that does my processing and then calls the original removeItemsObject. But I would prefer to know that whenever an item is removed, from anywhere, this is taken care of. This works nicely when I customize awakeFromInsert, for example - I know that whenever an item is created certain things are setup for me. But I'm surprised there's no equivalent for deletion.
Did you try to implement prepareForDeletion? Sounds like it's exactly what you're looking for.
The doc says:
You can implement this method to perform any operations required before the object is deleted, such as custom propagation before relationships are torn down, or reconfiguration of objects using key-value observing.

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.