2016-06-02 7 views
0

У меня очень странная проблема. У меня есть собственный FrameLayout (у которого есть только строка FileName, связанная с mvvmcross и несколькими методами). Я использую его для отображения медийных (Pdf, видео, звуков и изображений) по щелчку элемента. Мои объекты - маленькие значки, представляющие мои медиафайлы и привязанные к mediaItems.Xamarin Android - FrameLayout отображает только его фон, когда я добавляю просмотр в первый раз, но отображается, когда я добавляю его снова

Когда я нажимаю на один из этих значков, все хорошо, когда я ударяю свои точки останова, появляется рамка, но это просто отображение его фона, а не его дочернего вида.

Если я уменьшу его и снова нажму на тот же элемент, рамка будет отображаться снова и покажет мое содержимое правильно, и я не могу понять, почему.

Чтобы понять логику его вот как это работает:

  • я нажимаю на одном из моих пунктов

  • В моем ViewModel это поднять команду OnClick и установите мое свойство SelectedMedia

  • Вид, содержащий мой пользовательский frameLayout, получает видимость от видимого до его видимости, так как его видимость привязана к SelectedMedia (если null => go if not => visible)

  • В то же время мой пользовательский FrameLayout получил свое свойство FileName (которое привязано к Property SelectedMedia.FileName).

  • Имя файла сеттер (как вы можете видеть в коде saple) называет свой метод Init, whoose работа, чтобы выбрать, какой вид зрения, чтобы добавить к моему обычаю FrameLayout, а затем добавить его

  • Наконец мой контейнер, внутри него есть мой пользовательский FrameLayout, но я могу видеть только его фон, а не его дочерний вид, и я не знаю почему.

Вот мой заказ framelayout C# код:

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 
} 

А вот мой XML, содержащий мои пользовательские framelayout:

<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 и у меня есть абсолютно не знаю, почему это не работает. Может быть, мой макет кадра не полностью загружен (это странно, потому что он включен в мой просмотр). Я бы очень принял любую помощь по этой проблеме!

Благодаря

Edit: Хорошо вот некоторые обновления:

  • Я пытался использовать BringChildToFront, SETFOCUS, чтобы установить вид, содержащий мой framelayout tử кликабельным (как я заметил, мои щелчки проходили).

Edit 2:

  • Я обновил свой код (до сих пор не работает, как ожидалось)

  • Я попытался установить мой макет на вызове конструктора, которым просто сломал тот факт, что мнение dsiplay во второй раз я стараюсь, чтобы загрузить его, давая мне с пустым framelayout, поэтому я вернусь к старому

PS: Извините за мой ужасный английский

ответ

1

Хорошо, поэтому я, наконец, решил это!

По каким-то причинам и некоторым поведением в Android-стиле я пока не понимаю, мое представление было добавлено к моей пользовательской рамке, прежде чем этот был загружен.

Так что решение я нашел в том, чтобы добавить ViewTreeObserver к моему customlayout, а затем загрузить мой взгляд ребенка есть:

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; 
     } 
    }; 
}