Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.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 未连接到主机的片段_Android_Android Fragments_Uinavigationcontroller_Android Context_Android Viewholder - Fatal编程技术网

Android 未连接到主机的片段

Android 未连接到主机的片段,android,android-fragments,uinavigationcontroller,android-context,android-viewholder,Android,Android Fragments,Uinavigationcontroller,Android Context,Android Viewholder,我来解释一下,以防万一。我正在使用底部导航视图和Jetpack的移动导航图等等。我重新实现了这个方法: NavigationUI.setupWithNavController(…) 在导航设置过程中,我没有使用此方法,而是做了一个非常类似的操作: customSetupWithNavController(…) 我所做的唯一更改是更改片段之间的默认淡入淡出过渡,并开始使用更自然(在我看来)的侧幻灯片动画,就像onNavDestinationSelected中的一样: if(origin == 0)

我来解释一下,以防万一。我正在使用底部导航视图和Jetpack的移动导航图等等。我重新实现了这个方法:

NavigationUI.setupWithNavController(…)

在导航设置过程中,我没有使用此方法,而是做了一个非常类似的操作:

customSetupWithNavController(…)

我所做的唯一更改是更改片段之间的默认淡入淡出过渡,并开始使用更自然(在我看来)的侧幻灯片动画,就像onNavDestinationSelected中的一样:

if(origin == 0){
        builder.setEnterAnim(R.anim.slide_in_from_right)
                .setExitAnim(R.anim.slide_out_to_left)
                .setPopEnterAnim(R.anim.slide_in_from_left)
                .setPopExitAnim(R.anim.slide_out_to_right);
    }else if(origin == 1){
        builder.setEnterAnim(R.anim.slide_in_from_left)
                .setExitAnim(R.anim.slide_out_to_right)
                .setPopEnterAnim(R.anim.slide_in_from_right)
                .setPopExitAnim(R.anim.slide_out_to_left);
    }
其中origin表示传入片段的来源方向

它带来了一个问题:我的两个碎片需要一个晶圆厂来向回收器添加元素,而侧滑梯的过渡突然变得难看。所以我在MainActivity的布局中添加了一个FAB,只有在调用这两个片段时,逻辑才会显示FAB

我找不到一种很好的方法将click事件从活动传递到片段,因为我无法实例化片段,因为导航处理整个过程

所以,我所做的就是创建一个ViewHolder,因为我知道它可以经受住生命周期的变化。此视图持有者持有一个int,以及一个MutableLiveData,在MainActivity逻辑中,我将BottomNavigationView所选元素的当前选定id传递给int,并且仅当单击MainActivity的FAB时,live布尔值才设置为true。因此,在FragmentsonViewCreated()中,我向该布尔值添加了观察者,当该值设置为true,并且传递给ViewHolder的id与当前片段的id匹配时,布尔值设置为false,可以执行以下操作:

eventsNotificationHandler.getClickEvent().observe(requireActivity(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            if(aBoolean && eventsNotificationHandler.getPositionId() == R.id.nav_contacts){
                eventsNotificationHandler.setClickEvent(false);
                //do something here
            }
        }
    });
eventsNotificationHandler.getClickEvent().observe(requireActivity(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            if(aBoolean && eventsNotificationHandler.getPositionId() == R.id.nav_contacts){
                eventsNotificationHandler.setClickEvent(false);
                Intent newContact = new Intent(previouslyDefinedContext, NewContactActivity.class);
                startActivity(newContact);
                requireActivity().overridePendingTransition(R.anim.slide_in_from_right,R.anim.slide_out_to_left);
            }
        }
    });
eventsNotificationHandler.getClickEvent().observe(Requiresponsibility(),new Observer()){
@凌驾
更改后的公共void(布尔aBoolean){
if(aBoolean&&eventsNotificationHandler.getPositionId()==R.id.nav_联系人){
eventsNotificationHandler.setClickEvent(false);
//在这里做点什么
}
}
});
此notificationHandler是ViewHolder

到目前为止一切都很好,现在我可以:

1-在BottomNavigationView片段之间自由导航,FAB仅显示所需片段

2-随时在观察者中使用Log.d(…),并查看调试消息

3-吐司消息,我想在任何时候,仅当上下文参数在观察者外部初始化时,,如下所示:

eventsNotificationHandler.getClickEvent().observe(requireActivity(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            if(aBoolean && eventsNotificationHandler.getPositionId() == R.id.nav_contacts){
                eventsNotificationHandler.setClickEvent(false);
                //do something here
            }
        }
    });
eventsNotificationHandler.getClickEvent().observe(requireActivity(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            if(aBoolean && eventsNotificationHandler.getPositionId() == R.id.nav_contacts){
                eventsNotificationHandler.setClickEvent(false);
                Intent newContact = new Intent(previouslyDefinedContext, NewContactActivity.class);
                startActivity(newContact);
                requireActivity().overridePendingTransition(R.anim.slide_in_from_right,R.anim.slide_out_to_left);
            }
        }
    });
Toast.makeText(以前定义的上下文,“一些文本”,Toast.LENGTH_SHORT.show()

我做不到的:

1-随时启动活动,在观察者内部使用与之前相同的想法,仅在之前初始化上下文,在观察者外部,我能够启动意图,如下所示:

eventsNotificationHandler.getClickEvent().observe(requireActivity(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            if(aBoolean && eventsNotificationHandler.getPositionId() == R.id.nav_contacts){
                eventsNotificationHandler.setClickEvent(false);
                //do something here
            }
        }
    });
eventsNotificationHandler.getClickEvent().observe(requireActivity(), new Observer<Boolean>() {
        @Override
        public void onChanged(Boolean aBoolean) {
            if(aBoolean && eventsNotificationHandler.getPositionId() == R.id.nav_contacts){
                eventsNotificationHandler.setClickEvent(false);
                Intent newContact = new Intent(previouslyDefinedContext, NewContactActivity.class);
                startActivity(newContact);
                requireActivity().overridePendingTransition(R.anim.slide_in_from_right,R.anim.slide_out_to_left);
            }
        }
    });
eventsNotificationHandler.getClickEvent().observe(Requiresponsibility(),new Observer()){
@凌驾
更改后的公共void(布尔aBoolean){
if(aBoolean&&eventsNotificationHandler.getPositionId()==R.id.nav_联系人){
eventsNotificationHandler.setClickEvent(false);
Intent newContact=newintent(以前定义的上下文,NewContactActivity.class);
星触觉(新接触);
require responsibility().覆盖结束转换(R.anim.从右滑入,R.anim.滑出到左);
}
}
});
但在这种特殊情况下,我可以启动新活动任意次数,但只有当我直接导航到应用程序打开后定义观察者的特定片段时,如果我决定先通过其他片段导航,然后转到该片段尝试启动活动,应用程序崩溃了

我注意到,当我从观察者内部调用requireContext()时,会发生这种确切的行为,它可以工作,但随后停止工作

应用程序因以下原因崩溃:

E/AndroidRuntime:致命异常:主 流程:cu.arrowtech.bpawreckproject,PID:18019 java.lang.IllegalStateException:片段碎片联系人{883259b}(9f127bdb-127d-4366-b90b-c8900a5a771e)}未附加到活动

我想要什么:

1-如果可能的话,通过在MainActivity中按FAB键,从片段内部启动新活动的正确方法

2-如果一个可能的解决方案意味着改变我已有的逻辑,那么这是一个切换片段的好方法

3-继续使用Jetpack和导航图

我可以通过在每个片段中使用两个独立的晶圆厂来做我想做的事情,但是转换并不漂亮

我愿意接受建议,即使这意味着要改变逻辑。我几乎可以肯定,这一定是一种更好的方式来完成我正在做的事情,而不是为此使用ViewHolder


我想得到一个类似谷歌支付的东西,似乎是添加支付方式、通行证和转账的按钮是同一个按钮,但它适应每种情况。

经过一些研究,我确实找到了一种方法,可以在片段和移动导航组件之间保持流畅的过渡,并在主活动布局中保持单个晶圆厂

我所做的是使用界面而不是ViewModels(我一直知道这种方法是错误的):

因此,在我的MainActivity中,我将该接口定义为null,并根据情况创建了一个方法来定义它。我的主要活动如下:

public class MainActivity extends AppCompatActivity {
    
    //UI elements
    private FloatingActionButton main_fab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

        //Same dode to get the custom animations
        //.......
    
        //Main and only Fab configuration
        main_fab = findViewById(R.id.main_fab);
        main_fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(sharedViewsInterface !=null){
                    sharedViewsInterface.onFabClicked();
                }
            }
        });    
    }


    //Other auxiliary methods
    public void setInterface(SharedViewsInterface sharedViewsInterface){
        this.sharedViewsInterface = sharedViewsInterface;
    }
}
通过这样做,我可以从每个片段实现onCreate中的接口:

((MainActivity) requireActivity()).setInterface(new SharedViewsInterface() {
        @Override
        public void onFabClicked() {
            Intent newContact = new Intent(requireContext(), NewContactActivity.class);
            startActivity(newContact);
            requireActivity().overridePendingTransition(R.anim.slide_in_from_right_short,R.anim.slide_out_to_left_medium);
        }
});
这很有效,因为只有在具有接口实现的片段可见时才会显示FAB,请参见我的示例gif

请注意,