如何在 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 和 ViewPager2
如何在 CollapsingToolbarLayout 中使用带有 Toolbar 的 TabLayout?