2016-06-02 14 views
0

私は非常に奇妙な問題があります。カスタムFrameLayout(mvvmcrossといくつかのメソッドでバインドされた文字列FileNameがあります)があります。 私はそれを使ってアイテムのクリックにメディア(Pdf、ビデオ、サウンド、写真)を表示します。 私のアイテムは、自分のメディアファイルを表す小さなアイコンで、mediaItemsにバインドされています。Xamarin Android - FrameLayout最初にビューを追加するとバックグラウンドのみ表示されますが、再度追加すると表示されます

ブレークポイントに当たったときにすべてのアイコンがうまくいきますが、framelyoutが表示されますが、それはその背景を表示しているだけで、子ビューではありません。

同じアイテムをもう一度クリックしてもう一度クリックすると、framelayoutが再び表示され、コンテンツが正しく表示され、その理由がわかりません。ここではその背後にあるロジックを理解することが

は、それがどのように動作するかです:

  • 私のviewmodelでは私の項目の1

  • をクリックして、それがonclickのコマンドを高め、そして私の財産SelectedMedia

    を設定
  • 私のカスタムフレームレイアウトを含むビューは、可視性がSelectedMediaにバインドされているため可視から可視になります(ヌル=>表示されていない場合は消えます)

  • 同時に私のカスタムFrameLayoutはプロパティSelectedMedia.FileNameにバインドされたプロパティFileNameを取得しました。

  • ファイル名のセッターは、(あなたがコードsapleに見ることができるように)私のInitメソッドを呼び出して、whoose仕事は私のカスタムでframeLayoutに追加するビューのどの種類を選択することで、その後、最後にそれを

  • を追加するために、私のコンテナが表示され、その中に私のカスタムFrameLayoutがありますが、私はそれがその背景だけで、その子ビューは見ることができず、私は理由を知らないのです。ここで

は、C#のコードでframeLayout私の習慣です:

public class MediaController : FrameLayout 
{ 

    #region [ Fields ] 
    private Context _context; 
    private ImageController _imageController; 
    private SoundAndVideoController _soundAndVideoController; 
    private PdfController _pdfController; 
    private LayoutInflater _layoutInflater; 
    private readonly string[] supportedVideoFormat = { "mp4", "3gp", "mkv", "mpg" }; 
    private readonly string[] supportedPictureFormat = { "png", "bmp", "gif", "jpg" }; 
    private readonly string[] supportedAudioFormat = { "flac", "mp3", "wav" }; 
    private readonly string[] supportedPdfFormat = { "pdf" }; 
    #endregion 
    #region [ Properties ] 
    private string _fileName; 
    public string FileName 
    { 
     get 
     { 
      return _fileName; 
     } 
     set 
     { 
      if (value != null) 
      { 
       _fileName = value; 
       Init(); 
      } 
     } 
    } 
    #endregion 

    #region [ Constructors ] 
    public MediaController(Activity activity) : base(activity) 
    { 
     _context = activity.BaseContext; 
     Init(); 
    } 

    public MediaController(Context context) : base(context) 
    { 
     _context = context; 
     Init(); 
    } 

    public MediaController(Context context, IAttributeSet attrs) : base(context, attrs) 
    { 
     _context = context; 
     Init(); 
    } 

    public MediaController(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr) 
    { 
     _context = context; 
     Init(); 

    } 

    public MediaController(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes) 
    { 
     _context = context; 
     Init(); 
    } 
    #endregion 
    #region [ Methods ] 
    public void InitViews() 
    { 

    } 

    private void Init() 
    { 
     if (!string.IsNullOrEmpty(FileName) &&_context != null) 
     { 
      this.RemoveAllViews(); 
      string extension = FileName.Split('.').Last(); 
      _layoutInflater = (LayoutInflater)_context.GetSystemService(Context.LayoutInflaterService); 
      if (supportedAudioFormat.Any(extension.ToLower().Contains) || supportedVideoFormat.Any(extension.ToLower().Contains)) 
      { 
       InitMusicOrVideoPlayer(extension); 
      } 
      else if (supportedPictureFormat.Any(extension.ToLower().Contains)) 
      { 
       InitImageViewer(); 
      } 
      else if (supportedPdfFormat.Any(extension.ToLower().Contains)) 
      { 
       InitPdfViewer(); 
      } 
      else 
      { 
       //manage error; 
      } 
     } 
    } 

    private void InitMusicOrVideoPlayer(string fileExtension) 
    { 
     SurfaceView musicView = (SurfaceView)layoutInflater.Inflate(Resource.Layout.MusicVideoTemplate, null); 

     FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(this.Width, this.Height); 

     this.AddView(musicView, layoutParams); 

     if (supportedAudioFormat.Any(fileExtension.ToLower().Contains)) 
     { 
      ImageView imageView = new ImageView(_context); 

      imageView.Background = _context.GetDrawable(Resource.Drawable.speaker); 

      imageView.SetScaleType(ImageView.ScaleType.FitCenter); 
      layoutParams = new FrameLayout.LayoutParams(this.Width/4, this.Height/4); 
      layoutParams.SetMargins((int)(this.Width * 0.375f), (int)(this.Height * 0.375f), 0, 0); 
      this.AddView(imageView, layoutParams); 
      soundAndVideoController = new SoundAndVideoController(musicView, FileName, _context, true); 
     } 
     else 
     { 
      soundAndVideoController = new SoundAndVideoController(musicView, FileName, _context, false); 
     } 
    } 

    private void InitPdfViewer() 
    { 
     FrameLayout pdfContainer = (FrameLayout)_layoutInflater.Inflate(Resource.Layout.PdfTemplate, null); 
     FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(this.Width, this.Height); 
     this.AddView(pdfContainer, layoutParams); 
     _pdfController = new PdfController(FileName, pdfContainer, _context); 
    } 

    private void InitImageViewer() 
    { 
     FrameLayout mediaImageContainer = (FrameLayout)_layoutInflater.Inflate(Resource.Layout.MediaImageTemplate, null); 
     FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(this.Width, this.Height); 
     this.AddView(mediaImageContainer, layoutParams); 
     _imageController = new ImageController(FileName, mediaImageContainer); 
    } 

    #endregion 
} 

そして、ここでは私のカスタムでframeLayoutを含む私のxmlです:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:local="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center" 
    android:layout_gravity="center" 
    android:background="@color/Black" 
    local:MvxBind="Visibility MustShowMedias, Converter=Visibility "> 
    <LinearLayout 
     android:orientation="horizontal" 
     android:weightSum="1" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 
     <LinearLayout 
      android:id="@+id/MediaLeftLayout" 
      android:layout_width="0dp" 
      android:layout_height="match_parent" 
      android:layout_weight="0.05"> 
      <Button 
       android:id="@+id/MediaPreviousButton" 
       android:layout_width="match_parent" 
       android:layout_height="35dp" 
       android:layout_gravity="center" 
       android:text="Previous" /> 
     </LinearLayout> 
     <LinearLayout 
      android:id="@+id/MediaCenterLayout" 
      android:layout_width="0dp" 
      android:layout_height="match_parent" 
      android:layout_weight="0.9" 
      android:orientation="vertical" 
      android:weightSum="1"> 
      <space 
       android:layout_width="match_parent" 
       android:layout_height="0dp" 
       android:layout_weight="0.05" /> 
      <MyProject.Droid.Views.MediaControllers.MediaController 
       android:id="@+id/MediaContainer" 
       android:layout_width="match_parent" 
       android:layout_height="0dp" 
       android:layout_weight="0.9" 
       android:background="#FFFFFF" 
       local:MvxBind="FileName SelectedMedia.Source"> 

      </MyProject.Droid.Views.MediaControllers.MediaController> 
     </LinearLayout> 
     <LinearLayout 
      android:id="@+id/MediaRightLayout" 
      android:orientation="vertical" 
      android:layout_width="0dp" 
      android:layout_height="match_parent" 
      android:layout_weight="0.05"> 
      <Button 
       android:id="@+id/MediaCloseButton" 
       android:layout_width="match_parent" 
       android:layout_height="35dp" 
       android:textColor="#FF0000" 
       android:text="X" 
       local:MvxBind="Click CloseMediaWindowCommand" /> 
      <Button 
       android:id="@+id/MediaNextButton" 
       android:layout_width="match_parent" 
       android:layout_height="35dp" 
       android:layout_gravity="center" 
       android:text="Next" /> 
     </LinearLayout> 
    </LinearLayout> 
</FrameLayout> 

私はAndroidの開発にはかなり新しいですし、私が持っていますなぜこれが機能しないのか全く分かりません。たぶん私のフレームレイアウトが完全に読み込まれていない(それは私のビューにインクルードされているので奇妙です)。私は大いにこの問題の助けを受け入れるだろう!

おかげ

編集:ここ わかりましたが、いくつかの更新です:

  • 私は私のクリックを介さ気づいたように私は私でframeLayout TUのクリッカブルを(含むビューを設定するBringChildToFront、のSetFocus、使用しようとしました)。

編集2:

  • 私は自分のコードを更新しました(まだとして期待される動作していない)

  • 私はコンストラクタ呼び出しに私のレイアウトを設定しようとした、ただ眺めている事実を破ったWICH私はそれをロードしようと2回目をdsiplay、私は空のframelayoutで私をさせるので、私は古い方法に戻る

PS:申し訳ありません私のひどい英語

答えて

1

私は最終的にこれを解決しました!

いくつかのアンドロイドの振る舞いについて私はまだ理解していませんが、私の見解はこのフレームが読み込まれる前に私のカスタムフレームレートに追加されました。だから、私が見つけた解決策は、私のcustomlayoutにViewTreeObserverを追加し、そこに私の子ビューをロードするようにした

protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    base.OnMeasure(widthMeasureSpec, heightMeasureSpec); 
    ViewTreeObserver vto = this.ViewTreeObserver; 
    vto.AddOnGlobalLayoutListener(this); 
    vto.GlobalLayout += (sender, args) => 
    { 
     if (!_hasLoaded) 
     { 
      Init(); 
      _hasLoaded =true; 
     } 
    }; 
} 
関連する問題