Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/208.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 有没有办法让Snackbar在活动更改中保持不变?_Android_Android Studio - Fatal编程技术网

Android 有没有办法让Snackbar在活动更改中保持不变?

Android 有没有办法让Snackbar在活动更改中保持不变?,android,android-studio,Android,Android Studio,虽然Snackbar很漂亮,但它在更改活动时不会持久。如果我想在完成活动之前确认消息是使用Snackbar发送的,那么这种情况就很糟糕了。我曾考虑过在退出活动之前暂停代码,但我发现这是一种不好的做法 如果我所描述的不可能,是否有任何类型的材料设计信息?或者一种制作长方形祝酒词的方法;半径较小的圆边?更新:参见所选答案 我的问题的最佳解决方案是在显示Snackbar之后使用计时器,然后在计时器的run()方法中启动活动 Snackbar.show(); // Excluded make for b

虽然
Snackbar
很漂亮,但它在更改活动时不会持久。如果我想在完成活动之前确认消息是使用
Snackbar
发送的,那么这种情况就很糟糕了。我曾考虑过在退出活动之前暂停代码,但我发现这是一种不好的做法


如果我所描述的不可能,是否有任何类型的材料设计信息?或者一种制作长方形祝酒词的方法;半径较小的圆边?

更新:参见所选答案

我的问题的最佳解决方案是在显示
Snackbar
之后使用
计时器,然后在计时器的
run()
方法中启动活动

Snackbar.show(); // Excluded make for brevity.

Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            Intent chooseVideoIntent = new Intent(Intent.ACTION_GET_CONTENT); // Any type of content/file. Song, doc, video...
            chooseVideoIntent.setType("video/*");
            startActivityForResult(chooseVideoIntent, CHOOSE_VIDEO_REQUEST);
        }
    }, 2 * 1000);

更新:我发现通过使用
findViewById(android.R.id.content)
作为
Snackbar.make()
中的视图,Snackbar在片段更改中保持不变。

要有一个矩形
土司,为土司设置一个矩形背景,或者只为土司设置一个不同的背景颜色


请参考作为问题发布的位置。但这是一个可能的解决方案。

如果我理解正确,您可以这样做:

  • 活动A启动活动B以发送消息
  • 消息发送后,您将显示一条确认消息
  • 你回到活动A
  • 您可以通过使用ActivityResult(是一个StackOverflow帖子,介绍了如何使用它)使用SnackBar来实现这一点

    以下是步骤:

  • 活动A使用startActivityForResult启动活动B
  • 在活动B中完成你的任务
  • 设置结果(查看上面的链接以了解)
  • 完成活动
  • 在活动A中,在OnActivityResult中获取该代码并显示 带有正确消息的SnackBar
  • 这允许您在活动a中显示对应于活动B结果的Snackar


    希望它能帮助您的问题

    创建一个包含应用程序上下文的Snackbar,该上下文在多个活动中可见:

  • WindowManager
    作为系统服务获取
  • 创建并将类型为
    WindowManager.LayoutParams.type_TOAST
    WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
    FrameLayout
    (rootView)添加到
    WindowManager
  • 等待,直到在
    FrameLayout
    (rootView)中调用onAttachedToWindow()
  • 使用
    View.getWindowToken()
  • 使用应用程序上下文和派生的
    @style/Theme.AppCompat
  • 使用新上下文创建附加的
    框架布局
    (snackbarContainer)
  • 使用类型
    WindowManager.LayoutParams.type\u APPLICATION\u面板
    和标志
    WindowManager.LayoutParams.flag\u NOT\u TOUCH\u model添加此
    FrameLayout
    (snackbarContainer)
  • 等待,直到在
    FrameLayout
    (snackbarContainer)中调用了on
    View.onAttachedToWindow()
  • 使用
    FrameLayout
    (snackbarContainer)像普通一样创建Snackbar
  • View.onDismissed()
    回调设置为Snackbar并删除框架布局(rootView和Snackbar容器)
  • 显示snackbar
    snackbar.Show()
  • 这里有一个有效的包装器(注意:滑动关闭不起作用。可能其他人找到了正确的
    WindowManager。LayoutParams
    标志接收由CoordinatorLayout修复的触摸事件):

    编辑
    定义了
    SnackbarWrapper
    后,您可以这样使用它:

    final SnackbarWrapper snackbarWrapper = SnackbarWrapper.make(getApplicationContext(),
                "Test snackbarWrapper", Snackbar.LENGTH_LONG);
    
    snackbarWrapper.setAction(R.string.snackbar_text,
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(getApplicationContext(), "Action",
                                Toast.LENGTH_SHORT).show();
                    }
                });
    
    snackbarWrapper.show();
    
    如果没有主题,可以在
    styles.xml
    中快速定义主题:

    <style name="FOL_Theme_SnackbarWrapper" parent="@style/Theme.AppCompat">
        <!--Insert customization here-->
    </style>
    

    以防万一有人需要在Xamarin这样做,我已经改编了,我发现这非常有用

    using Android.Content;
    using Android.Graphics;
    using Android.OS;
    using Android.Runtime;
    using Android.Support.Design.Widget;
    using Android.Views;
    using Android.Widget;
    using System;
    
    public class SnackbarWrapper
    {
        private readonly string text;
        private readonly int duration;
        private readonly IWindowManager windowManager;
        private readonly Context appplicationContext;
        private Snackbar.Callback externalCallback;
        private SnackbarAction action { get; set; }
    
        public static SnackbarWrapper make(Context applicationContext, string text, int duration)
        {
            return new SnackbarWrapper(applicationContext, text, duration);
        }
    
        private SnackbarWrapper(Context appplicationContext, string text, int duration)
        {
            this.appplicationContext = appplicationContext;
            var wm = appplicationContext.GetSystemService(Context.WindowService);
            // We have to use JavaCast instead of a normal cast
            this.windowManager = wm.JavaCast<IWindowManager>();
            this.text = text;
            this.duration = duration;
        }
    
        public void Show()
        {
            WindowManagerLayoutParams layoutParams = createDefaultLayoutParams(WindowManagerTypes.Toast, null);
            var frameLayout = new FrameLayout(appplicationContext);
            frameLayout.ViewAttachedToWindow += delegate
            {
                //this.onAttachedToWindow();
                onRootViewAvailable(frameLayout);
            };
    
            windowManager.AddView(frameLayout, layoutParams);
        }
    
        private void onRootViewAvailable(FrameLayout rootView)
        {
            var ctw = new ContextThemeWrapper(appplicationContext, Resource.Style.Base_Theme_AppCompat);
            CoordinatorLayout snackbarContainer = new CoordinatorLayout(ctw);
            snackbarContainer.ViewAttachedToWindow += delegate
            {
                onSnackbarContainerAttached(rootView, snackbarContainer);
            };
    
            windowManager.AddView(snackbarContainer, createDefaultLayoutParams(WindowManagerTypes.ApplicationPanel, rootView.WindowToken));
        }
    
        private void onSnackbarContainerAttached(View rootView, CoordinatorLayout snackbarContainer)
        {
            Snackbar snackbar = Snackbar.Make(snackbarContainer, text, duration);
    
            snackbar.SetCallback(new SnackbarCallbackImpl(rootView, snackbarContainer, windowManager));
    
            if (action != null)
            {
                snackbar.SetAction(action.Text, action.Listener);
            }
            snackbar.Show();
        }
    
        private WindowManagerLayoutParams createDefaultLayoutParams(WindowManagerTypes type, IBinder windowToken)
        {
            WindowManagerLayoutParams layoutParams = new WindowManagerLayoutParams();
            layoutParams.Format = Format.Translucent;
            layoutParams.Width = ViewGroup.LayoutParams.MatchParent;
            /* Si ponemos aqui WrapContent en alguna ocasion en la que haya un action largo y el texto tambien, el snackbar puede volverse como loco
             * asi que usamos MatchParent. Aun asi sucede que a veces se puede mostrar en una linea o en dos el mismo texto, pero al menos no hace el temblor loco que de la otra forma*/
            layoutParams.Height = ViewGroup.LayoutParams.MatchParent;
            layoutParams.Gravity = GravityFlags.CenterHorizontal | GravityFlags.Bottom;
            layoutParams.Flags = WindowManagerFlags.NotTouchModal;
            layoutParams.Type = type;
            layoutParams.Token = windowToken;
            return layoutParams;
        }
    
        public SnackbarWrapper SetCallback(Snackbar.Callback callback)
        {
            this.externalCallback = callback;
            return this;
        }
    
        public SnackbarWrapper SetAction(string text, Action<View> listener)
        {
            action = new SnackbarAction(text, listener);
            return this;
        }
    
    }//class
    
    internal class SnackbarAction
    {
        public string Text { get; set; }
        public Action<View> Listener { get; set; }
    
        public SnackbarAction(string text, Action<View> listener)
        {
            Text = text;
            Listener = listener;
        }
    }
    
    internal class SnackbarCallbackImpl : Snackbar.Callback
    {
        public Snackbar.Callback externalCallback { get; set; }
    
        View rootView;
        CoordinatorLayout snackbarContainer;
        IWindowManager windowManager;
    
        public SnackbarCallbackImpl(View rootView, CoordinatorLayout snackbarContainer, IWindowManager windowManager)
        {
            this.rootView = rootView;
            this.snackbarContainer = snackbarContainer;
            this.windowManager = windowManager;
        }
    
        public override void OnShown(Snackbar snackbar)
        {
            base.OnShown(snackbar);
            externalCallback?.OnShown(snackbar);
        }
    
        public override void OnDismissed(Snackbar snackbar, int evt)
        {
            base.OnDismissed(snackbar, evt);
    
            // Clean up (NOTE! This callback can be called multiple times)
            if (snackbarContainer.Parent != null && rootView.Parent != null)
            {
                windowManager.RemoveView(snackbarContainer);
                windowManager.RemoveView(rootView);
            }
    
            externalCallback?.OnDismissed(snackbar, evt);
        }
    }
    
    使用Android.Content;
    使用Android.Graphics;
    使用Android.OS;
    使用Android.Runtime;
    使用Android.Support.Design.Widget;
    使用Android.Views;
    使用Android.Widget;
    使用制度;
    公共类SnackbarWrapper
    {
    私有只读字符串文本;
    私有只读int持续时间;
    专用只读iWindows管理器windowManager;
    私有只读上下文AppApplicationContext;
    私有Snackbar.callbackexternalcallback;
    私有SnackbarAction操作{get;set;}
    公共静态SnackbarWrapper生成(上下文应用程序上下文、字符串文本、int持续时间)
    {
    返回新的SnackbarWrapper(应用程序上下文、文本、持续时间);
    }
    专用SnackbarWrapper(上下文应用程序上下文、字符串文本、整型持续时间)
    {
    this.appapplicationcontext=appapplicationcontext;
    var wm=appapplicationcontext.GetSystemService(Context.WindowService);
    //我们必须使用JavaCast而不是普通的cast
    this.windowManager=wm.JavaCast();
    this.text=文本;
    这个。持续时间=持续时间;
    }
    公开展览(
    {
    WindowManagerLayoutParams layoutParams=createDefaultLayoutParams(WindowManagerTypes.Toast,null);
    var frameLayout=新的frameLayout(应用程序上下文);
    frameLayout.ViewAttachedToWindow+=委托
    {
    //这个.onAttachedToWindow();
    onRootViewAvailable(框架布局);
    };
    AddView(框架布局、布局参数);
    }
    私有void onRootView可用(FrameLayout rootView)
    {
    var ctw=new ContextThemeWrapper(appapplicationcontext,Resource.Style.Base\u Theme\u AppCompat);
    CoordinatorLayout snackbarContainer=新的CoordinatorLayout(ctw);
    snackbarContainer.ViewAttachedToWindow+=委托
    {
    OnNackBarContainerAttached(rootView、snackbarContainer);
    };
    AddView(snackbarContainer,createDefaultLayoutParams(WindowManagerTypes.ApplicationPanel,根目录
    
        if(!Settings.canDrawOverlays(Activity.this){
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, URI.parse("package:" + getPackageName()));
            startActivityForResult(intent, REQ_CODE);
        }
    
    using Android.Content;
    using Android.Graphics;
    using Android.OS;
    using Android.Runtime;
    using Android.Support.Design.Widget;
    using Android.Views;
    using Android.Widget;
    using System;
    
    public class SnackbarWrapper
    {
        private readonly string text;
        private readonly int duration;
        private readonly IWindowManager windowManager;
        private readonly Context appplicationContext;
        private Snackbar.Callback externalCallback;
        private SnackbarAction action { get; set; }
    
        public static SnackbarWrapper make(Context applicationContext, string text, int duration)
        {
            return new SnackbarWrapper(applicationContext, text, duration);
        }
    
        private SnackbarWrapper(Context appplicationContext, string text, int duration)
        {
            this.appplicationContext = appplicationContext;
            var wm = appplicationContext.GetSystemService(Context.WindowService);
            // We have to use JavaCast instead of a normal cast
            this.windowManager = wm.JavaCast<IWindowManager>();
            this.text = text;
            this.duration = duration;
        }
    
        public void Show()
        {
            WindowManagerLayoutParams layoutParams = createDefaultLayoutParams(WindowManagerTypes.Toast, null);
            var frameLayout = new FrameLayout(appplicationContext);
            frameLayout.ViewAttachedToWindow += delegate
            {
                //this.onAttachedToWindow();
                onRootViewAvailable(frameLayout);
            };
    
            windowManager.AddView(frameLayout, layoutParams);
        }
    
        private void onRootViewAvailable(FrameLayout rootView)
        {
            var ctw = new ContextThemeWrapper(appplicationContext, Resource.Style.Base_Theme_AppCompat);
            CoordinatorLayout snackbarContainer = new CoordinatorLayout(ctw);
            snackbarContainer.ViewAttachedToWindow += delegate
            {
                onSnackbarContainerAttached(rootView, snackbarContainer);
            };
    
            windowManager.AddView(snackbarContainer, createDefaultLayoutParams(WindowManagerTypes.ApplicationPanel, rootView.WindowToken));
        }
    
        private void onSnackbarContainerAttached(View rootView, CoordinatorLayout snackbarContainer)
        {
            Snackbar snackbar = Snackbar.Make(snackbarContainer, text, duration);
    
            snackbar.SetCallback(new SnackbarCallbackImpl(rootView, snackbarContainer, windowManager));
    
            if (action != null)
            {
                snackbar.SetAction(action.Text, action.Listener);
            }
            snackbar.Show();
        }
    
        private WindowManagerLayoutParams createDefaultLayoutParams(WindowManagerTypes type, IBinder windowToken)
        {
            WindowManagerLayoutParams layoutParams = new WindowManagerLayoutParams();
            layoutParams.Format = Format.Translucent;
            layoutParams.Width = ViewGroup.LayoutParams.MatchParent;
            /* Si ponemos aqui WrapContent en alguna ocasion en la que haya un action largo y el texto tambien, el snackbar puede volverse como loco
             * asi que usamos MatchParent. Aun asi sucede que a veces se puede mostrar en una linea o en dos el mismo texto, pero al menos no hace el temblor loco que de la otra forma*/
            layoutParams.Height = ViewGroup.LayoutParams.MatchParent;
            layoutParams.Gravity = GravityFlags.CenterHorizontal | GravityFlags.Bottom;
            layoutParams.Flags = WindowManagerFlags.NotTouchModal;
            layoutParams.Type = type;
            layoutParams.Token = windowToken;
            return layoutParams;
        }
    
        public SnackbarWrapper SetCallback(Snackbar.Callback callback)
        {
            this.externalCallback = callback;
            return this;
        }
    
        public SnackbarWrapper SetAction(string text, Action<View> listener)
        {
            action = new SnackbarAction(text, listener);
            return this;
        }
    
    }//class
    
    internal class SnackbarAction
    {
        public string Text { get; set; }
        public Action<View> Listener { get; set; }
    
        public SnackbarAction(string text, Action<View> listener)
        {
            Text = text;
            Listener = listener;
        }
    }
    
    internal class SnackbarCallbackImpl : Snackbar.Callback
    {
        public Snackbar.Callback externalCallback { get; set; }
    
        View rootView;
        CoordinatorLayout snackbarContainer;
        IWindowManager windowManager;
    
        public SnackbarCallbackImpl(View rootView, CoordinatorLayout snackbarContainer, IWindowManager windowManager)
        {
            this.rootView = rootView;
            this.snackbarContainer = snackbarContainer;
            this.windowManager = windowManager;
        }
    
        public override void OnShown(Snackbar snackbar)
        {
            base.OnShown(snackbar);
            externalCallback?.OnShown(snackbar);
        }
    
        public override void OnDismissed(Snackbar snackbar, int evt)
        {
            base.OnDismissed(snackbar, evt);
    
            // Clean up (NOTE! This callback can be called multiple times)
            if (snackbarContainer.Parent != null && rootView.Parent != null)
            {
                windowManager.RemoveView(snackbarContainer);
                windowManager.RemoveView(rootView);
            }
    
            externalCallback?.OnDismissed(snackbar, evt);
        }
    }