如何在 TabLayout 中找到由 RecyclerView 打开的对话框的上下文?

Posted

技术标签:

【中文标题】如何在 TabLayout 中找到由 RecyclerView 打开的对话框的上下文?【英文标题】:How do I find the Context of a Dialog opened by a RecyclerView inside a TabLayout? 【发布时间】:2020-08-29 02:34:48 【问题描述】:

我正在尝试从回收器视图的适配器打开一个对话框,该对话框用于选项卡布局内的片段中。当我单击 recyclerview 的某一行时,应用程序崩溃并出现以下错误:

android.view.WindowManager$BadTokenException: 无法添加窗口 -- 令牌 null 不适用于应用程序

活动打开,声明了tablayout,以及viewpager ...片段xml包含recycler-view。 OrderActivity.getAllUserOrders() 正在声明适配器,并将 OrderActivity 设置为其上下文。

一切都按计划进行,直到点击。此时,对话框正在尝试打开,但应用程序崩溃,我收到上述错误...

在调试时,我发现 recycler-view 适配器中 mContext 中的“mActivityLifecycleCallbacks”值等于 2。它可能有连接,但我找不到如何处理它。我还发现 mContext 可能指向应用程序上下文而不是活动上下文...

片段:

public class orders_current extends Fragment 

    public orders_current() 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        View rootView = inflater.inflate(R.layout.fragment_orders, container, false);

        [...]

        OrdersActivity.getAllUserOrders(getContext(), rootView, prefs.getInt("ID", 0), true);

        return rootView;
    

RecyclerView 适配器:

public class CustomOrdersAdapter extends RecyclerView.Adapter<CustomOrdersAdapter.MyViewHolder> 

    private Context mContext ;

    [...]

    @Override
    public void onBindViewHolder(final CustomOrdersAdapter.MyViewHolder holder, int position) 
        holder.layOrdersItem.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                openDialogOrderItem(mData.get(holder.getAdapterPosition()));
            
        );
    

    [...]

    private void openDialogOrderItem(Order order) 
        final Dialog myDialog = new Dialog(mContext);
        myDialog.setContentView(R.layout.dialog_view_order);
        if(myDialog.getWindow() != null)
            myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        [...]

        myDialog.show();
    

    [...]


【问题讨论】:

【参考方案1】:

搜索了一段时间后找到了答案。彻底调试后,我明白对话框得到的上下文实际上是应用程序上下文,所以我想也许可以给适配器一个静态值来使用。

在 CustomOrdersActivity 中:

public static Activity instanceActivity;

在声明适配器之前,在片段的 onCreateView 中发送信息(只是为了更安全的方法和更好的做法):

CustomOrdersAdapter.instanceActivity = getActivity();

然后在对话框声明中:

final Dialog myDialog = new Dialog(instanceActivity);

就这么简单。 注意:我确实收到了警告:

不要将 Android 上下文类放在静态字段中;这是内存泄漏(也会破坏 Instant Run)

据我所知,它没有造成任何崩溃或问题...

【讨论】:

以上是关于如何在 TabLayout 中找到由 RecyclerView 打开的对话框的上下文?的主要内容,如果未能解决你的问题,请参考以下文章

Android TabLayout 的默认高度是多少

如何从片段更改 Tablayout 的背景颜色?

如何在 Android 中使用 TabLayout 和 ViewPager2

如何在 CollapsingToolbarLayout 中使用带有 Toolbar 的 TabLayout?

如何使用 tabLayout 在 ViewPager 中显示片段?

如何在我的Activity中删除tablayout中的选项卡?