2017-10-30 12 views
0

アンドロイドプロジェクトでプラットフォーム固有のレンダラーを作成して、Xoidのようなタブ付きページをXamarin Formsクロスプラットフォームアプリで作成するために、andoidのBottomNavigationViewを使用しようとしています。基本的には、bottomnavigationviewを含むレイアウトをレンダラーに追加し、レンダラーでこのビューをルートアクティビティーに追加し、フォームのタブ付きページに基づいてメニュー項目を作成します。今、フォームのタブ付きページの現在のページをアンドロイドレイアウトに追加/表示し、バーアイテムがクリックされたときにそれを置き換える方法は問題です。レンダラーでRemoveAllViewsと呼んでいただけでも、タブ付きページのコンテンツページが画面全体を占め、下部のバーを覆うことさえあります。そのため、タブ付きページのいずれかのコンテンツページが表示されている場合、それは画面全体を占有します。また、アンドロイドのAddViewメソッドはアンドロイドビューのみを受け入れ、フォームビューを受け入れません。アンドロイドレイアウトビューでページを追加または置換する方法

BottomNavレイアウト:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
<FrameLayout 
android:id="@+id/rootLayout" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@color/colorAccent" 
android:layout_above="@+id/bottom_navigation" 
android:orientation="vertical"> 
</FrameLayout> 

<android.support.design.widget.BottomNavigationView 
    android:id="@+id/bottom_navigation" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    app:itemBackground="@color/colorPrimary" 
    android:background="@color/colorPrimary" 
    app:itemIconTint="@color/white" 
    app:itemTextColor="@color/white" 
    app:menu="@menu/bottom_navigation_main" /> 

</RelativeLayout> 

レンダラはOnElementChanged:

 base.OnElementChanged(e); 
     TabbedPage oe = e.OldElement; 
     TabbedPage ne = e.NewElement; 
     int id = 1000; 
     foreach(Page p in ne.Children) 
     { 
      items.Add(new Item 
      { 
       text = p.Title, 
       icon = p.Icon, 
       page = p, 
       id = id++, 
      }); 
      p.IsVisible = false; // without this, page show full screen and covers the bottom bar 
     } 

     RemoveAllViews(); 
     Activity activity = this.Context as Activity; 
     view = activity.LayoutInflater.Inflate(Resource.Layout.BottomNav, this, false); 
     AddView(view); 
     layout = view.FindViewById<FrameLayout>(Resource.Id.rootLayout); 
     // add current page to layout, or replace layout with page? and How? 
     // 
     // 

     BottomNavigationView bottomNavigationView = (BottomNavigationView) 
      FindViewById(Resource.Id.bottom_navigation); 
     bottomNavigationView.NavigationItemSelected += BottomNavigationView_NavigationItemSelected; 

     Android.Support.V7.View.Menu.MenuBuilder menu = bottomNavigationView.Menu as Android.Support.V7.View.Menu.MenuBuilder; 
     menu.Clear(); 

     foreach(Item i in items) 
     { 
      IMenuItem mi = menu.Add(0, i.id, 0, i.text); 
      mi.SetIcon(Resource.Drawable.icon); 
     } 

EDIT:より多くのコードやスクリーンショットを追加

私の予想レイアウトは、XFからページを表示せずに、このようなものですタブ付きページでは、赤の主要部分はrootLayoutFrameLayoutです。目的はタブページの現在のページをtに追加することですFramelayoutを表示し、BottomNavigationViewのアイテムがクリックされると、FrameLayoutを切り替えて他のページを表示します。 falseに見え設定せずに、サブページが画面全体を占有する場合は

 foreach (Page p in e.NewElement.Children) 
     { 
      p.IsVisible = false; 
     } 

android view

:しかし、この画面では、すべてのページが見えなくすることによってのみ可能である enter image description here

私のテストXFタブ付きページ:

<?xml version="1.0" encoding="utf-8" ?> 
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     xmlns:local="clr-namespace:BottomTabbed" 
     x:Class="BottomTabbed.TabbedPage1" 
     NavigationPage.HasNavigationBar="False"> 
     <ContentPage Title="Tab 1" BackgroundColor="Green" /> 
     <ContentPage Title="Tab 2" BackgroundColor="Blue"/> 
     <ContentPage Title="Tab 3" BackgroundColor="Red"/> 
     <ContentPage Title="Tab 4" BackgroundColor="Gray" /> 
</TabbedPage> 
+0

どちらかそれは、HTTPSを実装する方法を参照するには、以下のコンポーネントを使用するか、またはコードを見て:

次に、あなたは、このように、たとえばXFのContentPage内の通常のビューコントロールとして、このビューを使用することができます/ /github.com/thrive-now/BottomNavigationBarXF –

+0

私はそれをチェックしました、それはアンドロイドbottomnavigationviewを使用していない、それはそこにrelativelayoutとボタンを使用しています。 – fluter

+0

どのレンダラーをカスタマイズしようとしていますか?カスタムレンダラーのコードはすべて表示されませんでしたが、 'TabbedPageRenderer'を試しているようですね。 –

答えて

1

には、フラグメントの場合はBottomNavigationViewFrameLayoutのビューのみが必要です。次に、ViewRendererをカスタマイズすることができます。

まず、例えばPCLにViewのサブクラスを作成します。

public class BottomTabbedView:View 
{ 
} 

次にアンドロイドクライアントプロジェクトでそのレンダラを実装:

[assembly:ExportRenderer(typeof(BottomTabbedView),typeof(BottomTabbedViewRenderer))] 
namespace PackageNameSpace.Droid 
{ 
    public class BottomTabbedViewRenderer:ViewRenderer 
    { 
     protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e) 
     { 
      base.OnElementChanged(e); 
      if (Control == null) 
      { 
       // Instantiate the native control and assign it to the Control property with 
       // the SetNativeControl method 
       var context = Xamarin.Forms.Forms.Context; 
       LayoutInflater inflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater; 
       var bottomnav_view = inflater.Inflate(Resource.Layout.bottomnav_view, this, false); 
       var frame = bottomnav_view.FindViewById<FrameLayout>(Resource.Id.rootLayout); 
       var navi = bottomnav_view.FindViewById<BottomNavigationView>(Resource.Id.bottom_navigation); 
       SetNativeControl(bottomnav_view); 
      } 

      if (e.OldElement != null) 
      { 
       // Unsubscribe from event handlers and cleanup any resources 
      } 

      if (e.NewElement != null) 
      { 
       // Configure the control and subscribe to event handlers 
      } 
     } 
    } 
} 

私はロジックのためにここにすべてのコードを終了しませんでしたBottomNavigationViewFrameLayoutの場合は、このViewRendererのロジックを実装する必要があります。コードはXamarin.Androidのコードと似ているはずです。

<local:BottomTabbedView/> 
+0

問題は、大きなビューの一部として表示できるように、ContentPage型のサブページをframelayoutに追加する方法です。ページはアンドロイドビューではないので、AddViewは機能しません。 – fluter

+0

@fluter、ええ、私の提案は、アンドロイドクライアントプロジェクトの他のページのビューで直接論理を完成させました。しかし、PCLにネイティブアンドロイドメソッド 'AddView'を公開する方法を知りたければ、後で私の答えを更新します。 –

+0

私は、このアプローチでは、iOSとUWPプロジェクト用のカスタムレンダラーも作成する必要がありますが、他の2つのプラットフォームのネイティブコントロールがうまく動作するので、アンドロイドをカスタマイズする必要があります。 – fluter

関連する問題