Created a Page as LoadingIndicator in Xamarin.forms? - android

In my application I have created my own Loading indicator with the help of Page class in xamarin.forms, and I use 'PushModalAsync' api to show Loading Indicator wherever needed like below
var loadingindicator=new LoadingIndicator();
MyApp.CurrentAppInstance.MainPage.Navigation.PushModalAsync(loadingindicator,false);
Everything works as expected and It is looking fine and I also managed to make it look like AndHUD by tweeking the alpha for the controls in that page until I hit an issue,
The issue is that, every time I show and hide the loadingindicator page 'OnAppearing()' getting called on the current top page on view stack.
I can fix this by introducing one additional functionality on all pages where I am using my LoadingIndicator, But I feel there might be some other cleaner way to solve this issue.
Can you guys suggest me if there is any cleaner approach available to solve this issue?
(I target this solution mainly for android and I want to achieve it through common code)

If I have understand the problem, I think there are some way to add Loading indicator.
Use ActivityIndicator
Use aritchie/userdialogs's Loading
using (this.Dialogs.Loading("Test Loading"))
await Task.Delay(3000);
Create a PopUp With Rg.Plugins.Popup
// Use these methods in PopupNavigation globally or Navigation in your pages
// Open new PopupPage
Task PushAsync(PopupPage page, bool animate = true) // Navigation.PushPopupAsync
// Hide last PopupPage
Task PopAsync(bool animate = true) // Navigation.PopPopupAsync
// Hide all PopupPage with animations
Task PopAllAsync(bool animate = true) // Navigation.PopAllPopupAsync
// Remove one popup page in stack
Task RemovePageAsync(PopupPage page, bool animate = true) // Navigation.RemovePopupPageAsync

Related

Focus html page or element from a webview with talckback

I have an hybrid app developed with ionic 1.x. When the app loads I am forcing the webview to take the focus from native side with the hope that after some initialization request a survey dialog appear and take the focus it self(When dialog appear I am forcing it to take focus). I am trying to make it work with talkback
The problem is that when you load the app from scratch the dialog is not focused so it is not read, after navigate through the app and come back to the original page then in works as expected, looks like as the user is in fact inside the page things works ok.
Is there any workaround or strategy to solve this particular situation?
Thanks in advance
I don't know if it helps you,
but we use it to focus on specific elements in the web view.
it works in android and ios,
but in android, before every element it read webview.
(if you found a solution for it please let me know)
function putFocus(elementForFocus) {
var $element = $(elementForFocus);
var focusInterval = 10; // ms, time between function calls
var focusTotalRepetitions = 10; // number of repetitions
$element.attr('tabindex', '0');
$element.blur();
var focusRepetitions = 0;
var interval = window.setTimeout(function () {
$element.focus();
}, focusInterval);
};

Instagram force touch menu on Android

Instagram on Android recently add new feature, when user long click to items at the Browse section, a popup menu shows and allow user to pre-view photo/video instead of going to its details.
It is really cool like iOS force touch feature.
Does anyone know any idea how we can do the same on Android app?
Can we just use Context Menu or Overlay Window to do that?
Thanks
Now I can do quite the same on UI with this library
https://github.com/tvbarthel/BlurDialogFragment
But the thing is:
When I long press the button, I have to RELEASE my finger to continue touching the dialog fragment. The touch event is still sent to activity not DialogFragment.
Do you know how to pass touch event / focus to dialog fragment right after it is showed?
It's the closest library I've found on the internet,
https://github.com/nantaphop/HoverTouchView
it might not be exactly like IG's, but for sure it gives the idea
I Have found 3DTouch as well as in Instagrame.
This library is hosted on Jitpack.io, which means to use it you will have to add the following to your root build.gradle file.
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
And then you will need to add the following dependency to your applications build.gradle file.
dependencies {
compile 'com.github.shalskar:PeekAndPop:v1.0.1'
}
Usage:
Basic usage is easy, simply provide an activity instance, a layout resource for the peek and pop and 1 or more views that will show the peek and pop when long clicked.
PeekAndPop peekAndPop = new PeekAndPop.Builder(this)
.peekLayout(R.layout.peek_view)
.longClickViews(view)
.build();
You can get the peek view by calling getPeekView() on the PeekAndPop object, and use findViewById() to get access any views in the peek layout.
View peekView = peekAndPop.getPeekView();
ImageView imageView = peekView.findViewById(R.id.image_view);
TextView textView = peekView.findViewById(R.id.text_view);
Often you will want to have the peek and pop shown when an item in a list (or other scrollable view) is clicked on, to ensure the peek and pop works correctly, you will have to add this line of code:
.parentViewGroupToDisallowTouchEvents(viewGroup)

AppGyver Supersonic navigating between Views and creating duplicates

I'm using AppGyver Steroids and Supersonic to build an app and I'm having some issues navigating between views programmatically.
Based on the docs, you navigate between views like this:
var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.push(view_obj);
However, when I inspect things via the Chrome DevTools, it appears that a second duplicate view is created i.e. If I navigate away from the index page and then navigate back, I now have two index pages, instead of what [I think] should be one. It also doesn't close the previous view I was on.
How can I prevent this from happening and simply move to the existing view, instead of duplicating views? How do I close a view after I have navigated away from it?
Thanks.
The problem you're encountering is that you're creating a new supersonic.ui.View("main#index") every time you navigate. On top of this, I think you want to return to the same view when you navigate back to a view for the second time, i.e. you want the view to remain in memory even if it has been removed from the navigation stack with pop() (rather than pushing a new instance of that view). For this, you need to preload or "start()" the view, as described in the docs here.
I implemented my own helper function to make this easier; here is my code:
start = function(dest, isModal) {
var viewId=dest,
view=new supersonic.ui.View({
location: dest,
id: viewId
});
view.isStarted().then(function(started) {
if (started) {
if (isModal) {supersonic.ui.modal.show(view);}
else {supersonic.ui.layers.push(view);}
} else {
// Start Spinner
supersonic.ui.views.start(view).then(function() {
if (isModal) {supersonic.ui.modal.show(view);}
else {supersonic.ui.layers.push(view);}
// Stop Spinner
}, function(error) {
// Stop Spinner
A.error(error);
});
}
});
};
Use it like start('module#view');. As a bonus, you can pass true as the second argument and it gets pushed as a modal instead.
It checks if you've already started a view - if so, it just pushes that view back onto the stack. If not, it start()s (i.e. preloads) it, then pushes it. This ensures that the view stays in memory (with any user input that has been modified) even when you pop() it from the stack.
You have to imagine that the layer stack is actually a stack in the Computer Science sense. You can only add and remove views at the top of the stack. The consequence of this is that complex navigations such as A > B > C > D > B are difficult/hacky to do (in this case, you'd have to pop() D and C in succession to get back to B).
Views will close if you pop() them, as long as you didn't start() them. If you did, and you pop() them, they remain in memory. To kill that view, you have to call stop() on it, as described in the docs I linked above.
try
var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.replace(view_obj);
And take a look at supersonic.ui.layers.pop();
Thanks to LeedsEbooks for helping me get my head around this challenge. I was able to find a solution. Here is the code:
var start = function(route_str, isModal) {
var regex = /(.*?)#(.*)/g;
var match_obj = regex.exec(route_str);
var view_id_str = match_obj[2],
view_location_str = route_str,
view = new supersonic.ui.View({
location: view_location_str,
id: view_id_str
});
view.isStarted().then(function(started) {
if (started)
{
if (isModal)
{
supersonic.ui.modal.show(view);
}
else {
supersonic.ui.layers.push(view);
}
}
else
{
// Start Spinner
supersonic.ui.views.start(view).then(function() {
if (isModal)
{
supersonic.ui.modal.show(view);
}
else
{
supersonic.ui.layers.push(view);
}
// Stop Spinner
}, function(error) {
// Stop Spinner
A.error(error);
});
}
});
};
You must ensure that your route has the format module#view as defined in the documentation.
PLEASE NOTE
There seems to some problem with the supersonic ui method for starting views. If you run the following code:
supersonic.ui.views.start("myapp#first-view");
supersonic.ui.views.find("first-view").then( function(startedView) {
console.log(startedView);
});
You'll notice that your view id and location are identical. This seems to be wrong as the id should be first-view and location should be myapp#first-view.
So I decided to not use the AppGyver methods and create my own preload method instead, which I run from the controller attached to my home view (this ensures that all the views I want to preload are handled when the app loads). Here is the function to do this:
var preload = function(route_str)
{
var regex = /(.*?)#(.*)/g;
var match_obj = regex.exec(route_str);
var view = new supersonic.ui.View({
location: route_str,
id: match_obj[2]
});
view.start();
};
By doing this, I'm sure that the view will get loaded with the right location and id, and that when I use my start() function later, I won't have any problems.
You'll want to make sure that your structure.coffee file doesn't have any preload instructions so as not to create duplicate views that you'll have problems with later.
Finally, I have a view that is 2 levels in that is a form that posts data via AJAX operation. I wanted the view to go back to the previous view when the AJAX operation was complete. Using my earlier function resulted in the push() being rejected. It would be nice if AppGyver Supersonic could intelligently detect that pushing to a previous view should default to a layers.pop operation, but you don't always get what you want. Anyway, I managed to solve this using supersonic.ui.layers.pop(), which simply does what the Back button would have done.
Everything working as intended now.

Android web view "back" button to load previously loaded div

I will try to explain this as clearly as possible. I have an android app using web view to basically load a webpage as my app. I have everything working great, however the back button seems to be an issue. I have set this page up all on one html page, it will load in a div when certain buttons are clicked to give the feel of a new page without actually having one. I basically want the back button (on the android tablet or smartphone) to load the previously loaded div, but I have no idea where to start with this. Here is what the content switching jquery looks like -
function contentSwitcher(settings){
var settings = {
contentClass : '.contentToLoad',
navigationId : '#sideMenu',
servFront : '#clickHomeHome'
};
//Hide all of the content except the first one on the nav
$(settings.contentClass).not(':first').hide();
$(settings.navigationId).find('li:first').addClass('active');
//onClick set the active state,
//hide the content panels and show the correct one
$(settings.navigationId).find('a').click(function(e){
var contentToShow = $(this).attr('href');
contentToShow = $(contentToShow);
//dissable normal link behaviour
e.preventDefault();
//set the proper active class for active state css
$(settings.navigationId).find('li').removeClass('active');
$(this).parent('li').addClass('active');
//hide the old content and show the new
$(settings.contentClass).hide();
contentToShow.show("slow");
});
}
contentSwitcher();
});
note: I've cropped out a bunch of it just to show how it works on a basic level.
Does anyone have any suggestions as to where to begin. I'd just like the back button function to be able to maybe check a started previous div name stored somewhere and load that.
thanks!
You can try using the History API. There are numerous tutorials on the web e.g. this one is quite good:
http://diveintohtml5.info/history.html
Basically this is how it works. When the user clicks the link for the div to show you push the state to the history stack.
history.pushState({<object with any information about state>}, pageTitle, newUrl);
This will push the state to the history stack meaning that when the user presses the back button on any modern browser like webkit it will take that state into consideration. When back action is taken it will then pop the state from the history stack. This action you have to listen to and handle in any way you see fit:
window.addEventListener("popstate", function(event) {
// event object contains the information from the pushed state
// do whatever needed to load the previous page here
});
The History API requires you to structure your code in a certain way for it to work well. For this I would recommend to use some existing framework that handle the back events for you e.g. Backbone.js. Hope this helps.

Moving between "pages" ( CCLayer ) in cocos2dx

I have 2 MyGameScreen objects that extends cocos2d::CCLayer. I am capturing the ccTouchesMove of the first screen so that I can create the moving effect exactly like sliding between pages of iOS application screen.
My class is like so:
class MyGameScreen: public cocos2d::CCLayer {
cocos2d::CCLayer* m_pNextScreen;
}
bool MyGameScreen::init() {
m_pNextScreen = MyOtherScreen::create();
}
void MyGameScreen::ccTouchesMoved(CCSet *touches, CCEvent *event){
// it crashes here... on the setPosition... m_pNextScreen is valid pointer though I am not sure that MyOtherScreen::create() is all I need to do...
m_pNextScreen->setPosition( CCPointMake( (fMoveTo - (2*fScreenHalfWidth)), 0.0f ) );
}
EDIT: adding clear question
It crashed when I try to setPosition on m_pNextScreen...
I have no idea why it crashed as m_pNextScreen is a valid pointer and is properly initialized. Could anybody explain why?
EDIT: adding progress report
I remodelled the whole system and make a class CContainerLayer : public cocos2d::CCLayer that contains both MyGameScreen and MyOtherScreen side by side. However, this looked like not an efficient approach, as when it grows I may need to have more than 2 pages scrollable side by side, I'd prefer to load the next page only when it is needed rather than the entire CContainerLayer that contains all the upcoming pages whether the user will scroll there or not... Do you have any better idea or github open source sample that does this?
Thank you very much for your input!
Use paging enable scrollview.download files from following link and place in your cocos2d/extenision/gui/ after that you have to set property of scrollview to enablepaging true with paging view size.
https://github.com/shauket/paging-scrollview
For Scene Transitions you can do this:
void MyGameScreen::ccTouchesMoved(CCSet *touches, CCEvent *event)
{
CCScene* MyOtherScene = CCTransitionFadeUp::create(0.2f, MyOtherScreen::scene());
CCDirector::sharedDirector()->replaceScene(MyOtherScene);
}

Categories

Resources