Impossible to enable Edge swipe on wear OS with SwipeDismissFrameLayout - android-jetpack-compose

I create a blank jet compose app on Wear OS.
I want to enable edge swipe for exit app with left to right gest because i use pan on my app.
I follow the procedure that can be seen [here][1], but it does not work. Here is my code with MainActivity.kt and main_activity.xml.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
//WearApp("Android")
setContentView(R.layout.activity_main)
val swipeLayout = findViewById<SwipeDismissFrameLayout>(R.id.swipe_dismiss_root)
swipeLayout.addCallback(object : SwipeDismissFrameLayout.Callback() {
override fun onDismissed(layout: SwipeDismissFrameLayout) {
layout.visibility = View.GONE
}
})
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.wear.widget.SwipeDismissFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipe_dismiss_root" >
<TextView
android:id="#+id/test_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Swipe me to dismiss me." />
</androidx.wear.widget.SwipeDismissFrameLayout>
An idea. Thank you.
[1]: https://developer.android.com/training/wearables/views/exit

Related

Xamarin.Forms : UI is not rendering for the same way on iOS 10.1 and iOS 10.4

I work on a Xamarin.Forms app where I need to implement transparent/translucent navigation bar.
I've studied the the Vision Conference sample, where this is implemented.
This is achieved through a CustomNavigationPage and a CustomRenderer.
The XAML of the CustomNavigationPage is:
<?xml version="1.0" encoding="utf-8" ?>
<NavigationPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ConferenceVision.Views.CustomNavigationPage"
xmlns:iOS="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
iOS:NavigationPage.IsNavigationBarTranslucent="True"
BarTextColor="{StaticResource NavigationBarTextColor}">
<NavigationPage.BarBackgroundColor>
<OnPlatform x:TypeArguments="Color">
<On Platform="Android, iOS" Value="Transparent" />
<On Platform="UWP" Value="{StaticResource NavigationBarBackgroundColor}" />
</OnPlatform>
</NavigationPage.BarBackgroundColor>
</NavigationPage>
The code-behind of the CustomNavigationPage is:
public partial class CustomNavigationPage : NavigationPage
{
public bool IgnoreLayoutChange { get; set; } = false;
protected override void OnSizeAllocated(double width, double height)
{
if (!IgnoreLayoutChange)
base.OnSizeAllocated(width, height);
}
public CustomNavigationPage() : base()
{
InitializeComponent();
}
public CustomNavigationPage(Page root) : base(root)
{
InitializeComponent();
}
}
And the CustomRenderer is:
public class CustomNavigationRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.BackgroundColor = UIColor.Clear;
UINavigationBar.Appearance.TintColor = UIColor.White;
UINavigationBar.Appearance.BarTintColor = UIColor.Clear;
UINavigationBar.Appearance.Translucent = true;
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes()
{
Font = UIFont.FromName("HelveticaNeue-Light", (nfloat)20f),
TextColor = UIColor.White
});
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
}
I've tested the app on :
simulators : iPhone 6 on iOS 11.3
my device : iPhone 6 on iOS 10.1
And we can see that the results are not the same. On the simulator and iOS 11.3, there is a gap between the navigation bar and the content:
But on my device under iOS 10.1, there is no gap and the content is displayed "under" the navigation bar:
The page is built like that, but the rendering is the same on all pages:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:effects="clr-namespace:ConferenceVision.Effects"
xmlns:local="clr-namespace:ConferenceVision.Views.Renderers"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
Title="About"
x:Class="ConferenceVision.Views.AboutView">
<ContentPage.Content>
<ScrollView>
<ScrollView.Margin>
<OnPlatform x:TypeArguments="Thickness" Default="15,0">
<On Platform="Android" Value="15,50,15,0"/>
</OnPlatform>
</ScrollView.Margin>
...
</ScrollView>
</ContentPage.Content>
</ContentPage>
How explain it? Could this be related to the use of UseSafeArea?
I know that I get an "old" version on my device, but in my app I have to cover the largest number of users.
The difference between iOS is related to the use of SafeArea. In iOS 11+ the safearea adds a paddind.
ios:Page.UseSafeArea="true"
It's normal for that version. You must always use the last 3 version of each mobile OS, because their marketshare grants you a better stability, compatibility and acceptance with the public.
This are the numbers for the 10.1 in the world (from NetMarketshare)
Just tell the users to use a more updated version.

Xamarin.Forms on iOS 11.1.2: Webview loads a bigger font

I'm using Xamarin.Forms to load an internet's webpage (requirements of the client, please don't judge me), the problem is that in iOS the webpage appears to be bigger that it is.
I don't have any custom render on iOS.
Here is the website loaded on safari on a iPhone 6 iOS 11.1.2
And here is loaded on the webview
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Juppie"
x:Class="Juppie.MainPage">
<Grid>
<WebView x:Name="Navegador" Source="http://empleosapp.caonainteractive.com/"
WidthRequest="1000" HeightRequest="1000" IsVisible="{Binding Path=HayInternet}" ></WebView>
<ActivityIndicator IsRunning="{Binding Path=Navegando}" IsVisible="{Binding Path=Navegando}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=0.33}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,
Factor=0.33}"/>
</Grid>
</ContentPage>
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Plugin.Connectivity;
using System.ComponentModel;
namespace Juppie
{
public partial class MainPage : ContentPage, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainPage()
{
InitializeComponent();
Navegador.Navigating += Navegador_Navigating;
Navegador.Navigated += (sender, e) => { Navegando = false; };
HayInternet = true;
BindingContext = this;
}
bool hayInternet;
public bool HayInternet
{
get
{
return hayInternet;
}
set
{
hayInternet = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("HayInternet"));
EvaluarInternet();
}
}
bool navegando;
public bool Navegando
{
get
{
return navegando;
}
set
{
navegando = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Navegando"));
}
}
public async void EvaluarInternet(){
if (!HayInternet)
{
await DisplayAlert("Aviso","Se requiere conexion a internet para emplear esta aplicacion", "OK");
}
}
protected override void OnAppearing()
{
HayInternet = CrossConnectivity.IsSupported && CrossConnectivity.Current.IsConnected;
CrossConnectivity.Current.ConnectivityChanged += (sender, args) =>
{
HayInternet = args.IsConnected;
};
base.OnAppearing();
}
protected override bool OnBackButtonPressed()
{
if (Navegador.CanGoBack)
{
Navegador.GoBack();
return false;
}
return base.OnBackButtonPressed();
}
void Navegador_Navigating(object sender, WebNavigatingEventArgs e)
{
Navegando = true;
if (e.Url.Contains("/banner"))
{
e.Cancel = true;
var uri = new Uri(e.Url.Replace("/banner", ""));
Device.OpenUri(uri);
}
}
}
}
I tried with a custom render and set the scalePageToFit = false, without success.
If anyone knows how can I fix this, please let me know.
Xaml: - VerticalOptions="FillAndExpand" seems to fill the HeightRequest and WidthRequest property specification requirements for the WebView to render in a StackLayout - in a Grid it seems to render anyway:
<Grid>
<WebView x:Name="webView"
VerticalOptions="FillAndExpand"
Source="https://www.xamarin.com/"/>
</Grid>
Renderer, ScalesPageToFit is false by default (at least in the simulator with iPhone SE 11.2)
[assembly: ExportRenderer(typeof(WebView), typeof(MyWebViewRenderer))]
namespace MyNamespace.iOS
{
public class MyWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (NativeView != null && e.NewElement != null)
{
var webView = ((UIWebView)NativeView);
webView.ScalesPageToFit = true;
}
}
}
}
The screenshots below are from the simulator with iPhone SE.
ScalesPageToFit = true:
ScalesPageToFit = false:
Tested on my iPhone 6 and the app was showing the same size of font as Safari.
I also tested with larger system font in the font size in the app and it was not affected with the app font size.
But I did notice that when the activity indicator was running, my font size became smaller and it turned normal after the activity indicator disappear.
Maybe the font size issue was cause by the side effect of any additional stuff like a Nuget packages or Activity indicator?
You could try to use a new empty form and load only the Webview to compare the differences.
By the way, your app appearance is very alike with iPhone with turned on Display Zoom function.
Before turn on Display Zoom:
After turned on Display Zoom:
Is it possible that the sizing is overwritten by the accessability-settings from the iPhone?
See Settings-App -> General -> Accessability -> Bigger Text
(freely translated from german, actual menu entries may be named different)
I have faced the same issue.
In Xamarin.Forms App resolution is based on the Launch screen. If you are using Assets (LaunchImage) for Launch screen. Then your app resolution is set as per LaunchImage.
The best solution is: use storyboard (LaunchScreen.storyboard) or XIB for Launch screen. This improves your App UI. like font size and App resolution

TextInputLayout hint issue when handling FocusChange event

My app has a couple of EditTexts with a TextInputLayout wrapped around them. This works fine in most cases, but when I attach a handler to the FocusChange event of the EditText, the hint fails to animate.
I found this issue on the android forum, but he uses the OnFocusChangeListener. Proxying the call should not be necessary with events, right?
Any ideas on this issue? Is it a bug in the Xamarin android design support NuGet package?
Thanks in advance
Layout code:
<android.support.design.widget.TextInputLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<EditText
android:id="#+id/txtProductCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:inputType="textCapCharacters|textNoSuggestions"
android:hint="Artikelcode" />
</android.support.design.widget.TextInputLayout>
Fragment code:
public override void OnStart()
{
base.OnStart();
txtProductCode.FocusChange += txtProductCode_FocusChange;
// ...
}
void txtProductCode_FocusChange(object sender, View.FocusChangeEventArgs e)
{
if (!e.HasFocus)
txtDescription.Text = GetProductDescription();
}
From this post this i found my solution for the problem.
As stated in the post it's kind of a workaround but i think this should work in the new design library version 22.2.1 but for me the problem still persists.
Here is my code based on the mentioned post:
final View.OnFocusChangeListener userNameEtFocusListener = userNameEt.getOnFocusChangeListener();
userNameEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
userNameEtFocusListener.onFocusChange(v, hasFocus);
if (!hasFocus){
userInfoValidator.checkUserNameAvailable(userNameEt.getText().toString());
}
}
});

How to display custom player controls on youtube chromeless player using Flash builder 4.6?

I have a View component which initialises youtube cloud api using "http://www.youtube.com/apiplayer?version=3&modestbranding=1" url and plays the video fullscreen. It has play, pause and progress bar under s:actionContent, but I am trying to put "rewind", "play/pause", "forward" and a interactive progress bar on top of the chromeless player itself (transparent popup with image buttons for the same), like the below image.
My View component which initialises youtube api does not have any items. (Removed s:actionContent to try out popup)
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="YoutubeVideoPlay" viewActivate="init()" >
<fx:Script source="YoutubePlayer.as"/>
<fx:Script>
<![CDATA[
//navigator.addEventListener(TouchEvent.TOUCH_BEGIN,showPlayerControl); How to add a event listener on the youtube player?
public function showPlayerControl():void{
PopUpManager.addPopUp(PlayerControls,player);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:View>
Need help with this popup manager to appear on top of chromeless player, when the user taps on the playing video.
<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" width="400" height="300">
<fx:Script source="../YoutubePlayer.as"/>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
global
{
modal-transparency: 0.0;
modal-transparency-color: white;
modal-transparency-blur: 0;
}
</fx:Style>
<fx:Script>
<![CDATA[
import mx.managers.PopUpManager;
/*[Bindable][Embed(source="view/assets/images/play32.png")]
public static var iconPlay : Class;*/
[Bindable][Embed(source="view/assets/images/pause32.png")]
public static var iconPause : Class;
[Bindable][Embed(source="view/assets/images/forward32.png")]
public static var iconForward : Class;
[Bindable][Embed(source="view/assets/images/rewind32.png")]
public static var iconRewind : Class;
//addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE,removePlayerControls);
/*private function removePlayerControls(event:FlexMouseEvent):void {
PopUpManager.removePopUp(this);
}*/
public function closeAndBackup():void {
dispose();
navigator.popView();
}
public function initAndPlay():void {
player.playVideo();
}
private var _duration:String = "";
[Bindable]
public function get duration():String {
return _duration;
}
public function set duration(val:String):void {
_duration = val;
}
protected function ytVideoSlider_changeHandler(event:Event):void
{
// TODO Auto-generated method stub
trace(event.currentTarget.value);
player.seekTo(event.currentTarget.value,true);
}
]]>
</fx:Script>
<s:VGroup>
<s:HGroup>
<s:layout>
<s:HorizontalLayout paddingTop="10" paddingLeft="10"/>
</s:layout>
<s:HSlider id="ytVideoSlider"
liveDragging="true"
dataTipPrecision="1"
maximum="{duration}"
change="ytVideoSlider_changeHandler(event)"/>
<s:Label text="{Math.round(ytVideoSlider.value)}"/>
</s:HGroup>
<s:Button icon="{iconRewind}" click="player.playVideo()"/>
<s:Button icon="{iconPause}" click="player.pauseVideo()"/>
<s:Button icon="{iconForward}" click="closeAndBackup()"/>
</s:VGroup>
</s:Panel>
Any help will be appreciated. :)
I have just started with Flash Builder's spark components, so pardon me if my question is too lame.
Or Is there any link/tutorial available to place player controls on top of chromeless youtube player?
Update: I was able to solve my problem, and provided my solution too
You should be able to add a click listener to the entire view. While I have never used this API before, I would imagine it would look something like this:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="YoutubeVideoPlay"
viewActivate="init()" click="showPlayerControl()">
<fx:Script source="YoutubePlayer.as"/>
<fx:Script>
<![CDATA[
public function showPlayerControl():void{
PopUpManager.addPopUp(PlayerControls,player);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
So you're nearly there. What you need to remember is that the YouTube player has its own interactions, eg when the user clicks the video it usually pauses/resumes. Now you can get around this by placing an invisible Sprite on top of the video as this'll allow you to capture the user's mouse movements and clicks.
The only issue with this is the current state of autoplaying; at the moment (and for the future I guess) autoplays don't count as views against the video. The user needs to press the play button on the YouTube video to actually make that count as a view.
So what I do is only add this invisible Sprite once playback has commenced. You can then also be clever and send pause/resume events to the player itself when the user clicks on your invisible Sprite.
Regarding the UI components that you're after: they're very easy to put together, you can always grab standard UI Flash/Flex components and hook them up to the player API (I see you've made a start); it's always a good idea, though, to get a design in you head rather than sketching out UIs over and over again in code.
As a footnote: you're always welcome to use my middleware class for the YouTube player on github: https://github.com/ahmednuaman/AS3/blob/master/com/firestartermedia/lib/as3/display/component/video/YouTubePlayerAS3.as
Solution to my question
I have a PlaylistsView.mxml which has a List with all the videos. Once clicked it pushes a new view called YtPlayView.mxml
<!--YtPlayView.mxml-->
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:popup="views.popup.*"
title="{data.title}" viewActivate="init()" viewDeactivate="deactivateYoutubePlayer()">
<fx:Script source="ytfeeds/YoutubePlayer.as"/>
<fx:Script>
<![CDATA[
public function deactivateYoutubePlayer():void{
PopUpManager.removePopUp(ytcPopup);
dispose();
}
]]>
</fx:Script>
</s:View>
In YoutubePlayer.as, onPlayerReady(event:Event) I add a mouseclick eventlistener player.addEventListener(MouseEvent.CLICK,showPlayerControl);
<!--YoutubePlayer.as contents-->
public function showPlayerControl(event:MouseEvent):void{
ytcPopup=new PlayerControls();
ytcPopup.player=player;
ytcPopup.duration=data.duration;
ytcPopup.currentPosition="00:00:00";
ytcPopup.open(this,true);
ytcPopup.width = this.stage.width;
ytcPopup.setStyle("modalTransparency",0);
ytcPopup.setStyle("modalTransparencyBlur",3);
ytcPopup.setStyle("modalTransparencyColor", "#ff0000");
if(ytcPopup.player.getPlayerState()==1){
ytcPopup.playPauseBtn.setStyle("icon",ytcPopup.iconPause);
}
else if(ytcPopup.player.getPlayerState()==2){
ytcPopup.playPauseBtn.setStyle("icon",ytcPopup.iconPlay);
}
ytcPopup.y = this.stage.height-195;
PopUpManager.bringToFront(ytcPopup);
if(player.getCurrentTime()!=0)
ytcPopup.ytVideoSlider.value=player.getCurrentTime();
}
Which gives me something like below (It's a portrait view, on Landscape view it comes on top of the video)
If anyone wants more source code or help, i'll be happy to help :) Just drop a comment.

AdMob AdView SDK 6.0.1 memory usage

I try to include an AdMob banner in my Android App using the AdMobsAdsSdk6.0.1.
The banner shows up correctly but increases the displayed memory-usage in the phones task manager from 2 MB to 10 MB. DDMS shows approx. 5MB. I have read some articles about possible memory leaks in older versions, but could not find anything solving my problem. I reproduced the behavior with a simple test app.
The Activity only holds the AdView
public class TestActivity extends Activity {
private AdView adView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
adView = new AdView(this, AdSize.BANNER, "adunitid");
LinearLayout layout = (LinearLayout) findViewById(R.id.content_Layout);
layout.addView(adView);
adView.loadAd(new AdRequest());
}
#Override
protected void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
}
The Manifest is also only a copy from the tutorial
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="admobtest.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="13" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TestActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
</application>
</manifest>
I also tried to include the banner via xml but i finally get the same results. Switching to landscape and back raises the memory further and further. Am i missing something or can somebody give me some hint how to solve this? I thought adView.destroy solved the memory leak.

Resources