【问题标题】:Xamarin Android - FrameLayout display only it's background when i add view first time, but displayed when i add it againXamarin Android - FrameLayout 在我第一次添加视图时仅显示背景,但在我再次添加时显示
【发布时间】:2016-06-02 09:25:57
【问题描述】:

我有一个很奇怪的问题。我有一个自定义的 FrameLayout(只有一个字符串 FileName 与 mvvmcross 和一些方法绑定)。 我用它在项目点击时显示媒体(Pdf、视频、声音和图片)。 我的项目是代表我的媒体文件并绑定到 mediaItems 的小图标。

当我点击其中一个图标时,当我到达断点时,一切都运行良好,framelyout 出现了,但它只是显示它的背景而不是子视图。

如果我缩小它并再次单击同一个项目,框架布局将再次出现并正确显示我的内容,我不知道为什么。

要理解它背后的逻辑是它的工作原理:

  • 我点击我的一个项目

  • 在我的视图模型中,它会引发 onclick 命令,并设置我的属性 SelectedMedia

  • 包含我的自定义 frameLayout 的视图,由于它的可见性绑定到 SelectedMedia (如果 null=>gone if not => visible)将其可见性从 gogone 变为可见)

  • 同时,我的自定义 FrameLayout 设置了其属性 FileName(绑定在 Property SelectedMedia.FileName 上)。

  • FileName 设置器(如您在代码中看到的)调用我的 Init 方法,其工作是选择将哪种视图添加到我的自定义 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 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 开发的新手,我完全不知道为什么这不起作用。也许我的框架布局没有完全加载(这很奇怪,因为它包含在我的视图中)。对于这个问题,我非常愿意接受任何形式的帮助!

谢谢

编辑: 好的,这里有一些更新:

  • 我尝试使用 BringChildToFront、setFocus 来设置包含我的 framelayout tu 的视图(因为我注意到我的点击正在通过)。

编辑 2:

  • 我更新了我的代码(仍然没有按预期工作)

  • 我试图在构造函数调用时设置我的布局,这打破了我第二次尝试加载视图时显示 dsiplay 的事实,让我使用空白框架布局,所以我回到了旧方式

PS:对不起,我的英语很糟糕

【问题讨论】:

    标签: c# android xamarin mvvmcross android-framelayout


    【解决方案1】:

    好的,我终于解决了这个问题!

    由于某些原因和一些我还不了解的 android 行为,我的视图在加载此视图之前已添加到我的自定义框架布局中。

    所以我找到的解决方案是将 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;
            }
        };
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多