SAPUI5 navigation between apps definitions - android

I'm new in SAPUI5 development and I'd like to know how can I navigate through different apps definitions.
In my case, I'm developing a mobile app that uses the sap.m.App and in some views I'd like to use sap.m.splitApp.
First, I have a login page and a tile container with some options. Depending on the user's choice, I'm showing an splitApp with master and detail page.
Main App Controller: With this method I can navigate to my splitApp view
toApp: function (pageId, context) {
var app = this.getView().app;
// load page on demand
var master = ("Login" === pageId);
if (app.getPage(pageId, master) === null) {
var page = sap.ui.view({
id : pageId,
viewName : "view." + pageId,
type : "JS",
viewData : { component : this }
});
page.getController().nav = this;
app.addPage(page, true);
console.log("app controller > loaded page: " + pageId);
}
// show the page
app.to(pageId);
// set data context on the page
if (context) {
var page = app.getPage(pageId);
page.setBindingContext(context);
}
},
Ticket.view.js: Here I add my master and detail pages to my App
createContent : function(oController) {
// to avoid scroll bars on desktop the root view must be set to block display
this.setDisplayBlock(true);
// create app
this.app = new sap.m.SplitApp();
// load the master page
var master = sap.ui.xmlview("MyTicketsList", "view.MyTicketsList");
master.getController().nav = this.getController();
this.app.addPage(master, true);
// load the empty page
var empty = sap.ui.xmlview("Empty", "view.Empty");
this.app.addPage(empty, false);
return this.app;
}
And it's working fine. I can navigate to my splitApp. The problem is that I have to go back to my Main page (with the tile container) in case the user choice other option. I hope to do that using the following method in my Ticket.controller.js
back : function (pageId) {
this.getView().app.backToPage(pageId);
}
And, on the MyTicketsList controller, I did the handleNavButtonPress using:
this.nav.back("MainPage");
But this, doesn't work!
How can I navigate through apps? Or, perhaps, How is the better way to create my splitter pages view, with Master and Detail pages?
P.S.: I'm following this tutorial
Thanks in advance!

In the splitApp first you should instantiate the view as
oSplitApp.addDetailPage(your view);
then to navigate from the splitapp use,
oSplitApp.toDetailPage(your view);

It's easier than it appears.
I had the same problem and to make the SplitApp preview you just have to call the view like a normal XML view but Insert the TAG

onInit: function() {
this.bus = sap.ui.component(sap.ui.core.Component.getOwnerIdFor(this.getView())).getEventBus();
},
doNavBack: function(event) {
this.bus.publish("nav", "to", {id : "Page1"});
},

Related

Pasting is not working with Nav Controller/Navigation UI

I've been trying to create an auto-paste feature in my downloader app. My app has an editText and when a user opens the app the app will automatically check for a copied link that matches certain parameters. The main page has two fragments, one of them has this feature.
Problem is when I use bottomNavigationView with NavController using Navigation UI, that feature doesn't work. It shows null as a result when checking for clipboard data.
But when I use an adapter extending FragmentStateAdapter instead of navigation UI then it works properly.
if (!this.clipboardManager.hasPrimaryClip()) {
Log.d("ContentValues", "PasteText");
} else if (this.clipboardManager.getPrimaryClipDescription().hasMimeType("text/plain")) {
ClipData.Item itemAt = this.clipboardManager.getPrimaryClip().getItemAt(0);
if (itemAt.getText().toString().contains(TikTok)) {
inputLink.setText(itemAt.getText().toString());
resetButton.setVisibility(View.VISIBLE);
pasteButton.setVisibility(View.GONE);
if (Util.getAuto(requireContext())) {
String string = inputLink.getText().toString();
getDownloadLink(string);
Util.showProgress(requireContext());
}
}
} else if (this.clipboardManager.getPrimaryClip().getItemAt(0).getText().toString().contains(TikTok)) {
inputLink.setText(this.clipboardManager.getPrimaryClip().getItemAt(0).getText().toString());
resetButton.setVisibility(View.VISIBLE);
pasteButton.setVisibility(View.GONE);
if (Util.getAuto(requireContext())) {
String string = inputLink.getText().toString();
getDownloadLink(string);
Util.showProgress(requireContext());
}
}
I don't know what is the issue here. It works in fragment when I use Adapter but not with Navigation UI. Any explanation is appreciated. Thanks.

Call with a button a saved number in another page( IONIC, Angular)

Hi I want to call a number which is saved in another page.
I don't know how to explain this well but I put some captures, and the code that I'm trying to use, I just only want to catch the value of the number and put into the button to call.
I'm using ionic framework and angular. I'm very new at this but I want to create an app and I'm stuck with this.
Sorry for my english is not my native language.
Client Detail
Call button
Button page .ts
Detail html page(the first image)
button page html (click) function
import { ICompanyAddress } from './../interfaces/Map';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class SharedDataService {
_phoneNumber: string;
constructor() { }
get phoneNumber(): string {
return this._phoneNumber;
}
set phoneNumber(newValue: string) {
this._phoneNumber = newValue;
}
}
Now You could change access its data from any page and changing its value:
example1 (change phoneNumber from a page)
constructor(private sharedDataService : SharedDataService) {
this.changePhoneNumber()
}
changePhoneNumber(){
this.sharedDataService.phoneNumber = '12345678'
}
example1 (get last phoneNumber changed value in a page)
constructor(private sharedDataService : SharedDataService) {
console.log(this.sharedDataService.phoneNumber)// 12345678
}
For that, you can create services and then store your PhoneNumber in services.
Check this out .I hope it will help you.

Adding/removing items from Listview programatically?

I'm trying to create an app for my Samsung Gear S3 that takes data from an API, dynamically creates a Listview, and propagates it using the data returned via the API. I've got as far as putting the items in the list, but when the page is hidden I want to remove everything from the list. Since I'm doing it programmatically in the first place, there's no easy way such as removing all of the elements using a querySelector and refreshing the Listview.
That said, much how I'm using .addItem - is there a .removeItem or equivalent that isn't documented?
At the moment, I'm listening to the pagebeforehide event and calling .destroy() on the created Listview - which works in the sense that the _items property is cleared but the Listview is still displaying all of the items from before...
The code I have at the moment can be seen below.
(function() {
var page = document.getElementById('search.results'),
listView;
var elems = [ ];
page.addEventListener("pagebeforeshow", function() {
if(sessionStorage.length && sessionStorage.getItem("currentResults")) {
var currentResults = JSON.parse(sessionStorage.getItem("currentResults"));
var elem = document.getElementById("results-list");
listView = tau.widget.Listview(elem, { dataLength: currentResults.length, bufferSize: 10 });
listView.setListItemUpdater(function(listElement, newIndex) {
var data = currentResults[newIndex];
listElement.innerHTML = data.Description;
listElement.id = data.EAN;
});
}
$("li").click(function(e) {
var li = $(e.target);
if(li.attr("id")) {
var EAN = li.attr("id");
tau.changePage("product.html", { name: li.innerHTML, ean: EAN });
}
});
});
page.addEventListener("pagebeforehide", function() {
console.log("page before hide");
if(sessionStorage.length && sessionStorage.getItem("currentResults")) {
console.log(sessionStorage);
sessionStorage.removeItem("currentResults");
console.log(sessionStorage);
}
listView.destroy();
console.log(listView);
});
}());
This list does not actually have an API for removing items or binding to data.
I see you have solved this problem practically by yourself.
I think it is enough to clear the base element of the list now, eg. listView.element.innerHTML = "" or document.getElementById("results-list").innerHTML = "".
I think you can also create issue on https://github.com/Samsung/TAU/issues
because the .destroy() method should remove items which was not attached to widget before widget build.

React Native: Integration With Existing Apps

I'm new to react and I followed the tutorial about integrating existing apps open in the React Native Docs.
private ReactRootView mReactRootView;
.......
Bundle launchOptions = new Bundle();
launchOptions.putBoolean("test", true);
//mReactRootView.startReactApplication(mReactInstanceManager, "ThirdAwesomeComponent", launchOptions);
mReactRootView.startReactApplication(mReactInstanceManager, "ThirdAwesomeComponent", null); // Actual example
Is there a way to read launchOptions in the HelloWorld Component at index.android.js?
Also I have two activities from where I need to call the react native daemon and want to render two different layouts returned by the server.
How can I do that since currently I only have one:
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
The best way to do is doing something like,
Redirect to App.js from the index page using
AppRegistry.registerComponent("App",()=>App)
This will redirect to app
Then for rendering two different scenes based on server output. You can create a state variable and initialize it to be the default state.
in the render function of you component you can then check the state value and assign the layout as per your necessity.
Use something like
export default Class App extends Component{
constructor(props){
super(props)
this.state{
data1:false,
data2:true,
loaded:false,
}
}
//do all the fetching data to server here
componentWillMount(){
//after fetching the data to server
change the state as
this.setState({
data1:true,
data2:false,
loaded:true
})
}
render({
if(this.state.loaded && this.state.data1){
return(
//layout which you want to return
)
}else if( this.state.loaded && this.state.data2){
return(
//second layout code
)
}else{
return(
//can create a loading spinner here
<Text>Loading.....</Text>
)
}
})
}
Hope this helps
Cheers
Your launching options will be passed to the constructor of your component as props.
Just implement the constructor
constructor(props){
super(props)
// do stuff to pops dictionary
}

Titanium - Changes done to TableViewRow custom properties aren ignored

I'm working with Titanium SDK 2.1.3 and developing for both iOS 6.1 and Android 4.0.
My application has a TableView, each TableViewRow represents a file and has a custom property called lockedStatus that can be either true or false, when a row is clicked, depending on the value of lockedStatus, a window is opened indicating the state of the element of the row. In this window I can modify the lockedStatus from true to false and viceversa.
The problem I'm having is that in Android the changes done to this property are ignored, unless a completely force the application to stop, this doesn't happen in iOS.
To change the lockedStatus value in the window, I fire an event like this:
Ti.App.fireEvent('updateLockedStatus', {
lockedStatus : true //this can be true or false
});
Then the listener is like this:
Ti.App.addEventListener('updateLockedStatus', function(e){
var rows = table.data[0].rows;
for (var i = 0; i < rows.length; i++) //iterate through the rows to look for the file
{
if (rows[i].fileID == currentlyEditingFile)
{
rows[i].updateLockedStatus(e.lockedStatus);
files[currentlyEditingFile].lockedStatus = e.lockedStatus; //update the file lockedStatus
rows[i].fileObject = files[currentlyEditingFile];
saveFilesToDatabase();
}
}
});
Each row is generated with a updateLockedStatus function, that has the following definition:
row.updateLockedStatus = function(lockedStatus)
{
row.lockedStatus = lockedStatus;
}
The saveFilesToDatabase function looks like this:
function saveFilesToDatabase()
{
var tempFilesArray = [];
for(var i=0;i<filesIds.length;i++)
{
tempFilesArray.push(files[filesIds[i]]);
}
Ti.App.Properties.setString('filesApp', JSON.stringify(tempFilesArray)); //save the file values in the application properties
}
What I mean by being ignored is that when I exit the window and return to the view with the table of files, if I click again on the file I just modified, the window will be opened as if no change had been done.
How can I force an update for all of the contents in the TableView? In iOS there's no problem, but with Android this isn't updated unless I close the application.
Any help will be appreciated.
try using Ti.API.fireEvent & Ti.API.addEventListener instead of Ti.App
you would take care when doing this :
Each row is generated with a updateLockedStatus function, that has the following definition:
row.updateLockedStatus = function(lockedStatus)
{
row.lockedStatus = lockedStatus;
};
If the code above is put in a loop then executing the row.updateLockedStatus may affect only the last row because the row variable gets reused and contains at the end only the last row object. Take a look at this
You can simply use this code :
row.updateLockedStatus = function(lockedStatus)
{
this.lockedStatus = lockedStatus; // this is the current row
};
Or using closures, something like that :
row.updateLockedStatus = (function(r){
return function(lockedStatus){
r.lockedStatus = lockedStatus; // r is the current row
};
})(row);
the local r variable should retain the right row object.
BTW, when you listen events using Ti.App, you should use variables for handlers. Instead of doing this :
Ti.App.addEventListener('updateLockedStatus', function(e){
use this way
var updateLockedStatusHandler = function(e){
//...
};
Ti.App.addEventListener('updateLockedStatus', updateLockedStatusHandler);
Then this could be useful to remove the handler and avoid a potential memory leak :
Ti.App.removeEventListener('updateLockedStatus', updateLockedStatusHandler);

Categories

Resources