我在显示我在RecyclerView适配器中创建的MaterialDialog时遇到问题。我想在回收者视图所在的活动中显示该对话框,并且我已经通过了活动上下文,但是它总是给我这个例外:
com.afollestad.materialdialogs.MaterialDialog$DialogException: Bad window token, you cannot show a dialog before an Activity is created or after it's hidden.
这是我的RecyclerView适配器:
public class AssetsAdapter extends RecyclerView.Adapter<AssetsAdapter.ItemHolder>{
private static final String TAG = "AssetsAdapter";
private ArrayList<Asset> listData;
private Context activityContext;
private MaterialDialog dialog;
public AssetsAdapter(ArrayList<Asset> listData, Context activityContext, UserService userService) {
this.listData = listData;
this.activityContext = activityContext;
}
public AssetsAdapter(Context activityContext) {
this.activityContext = activityContext;
}
@NonNull
@Override
public ItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_item_assets, parent, false);
return new ItemHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemHolder holder, final int position) {
holder.tv_name.setText(listData.get(position).getName());
holder.tv_manufacturer.setText(listData.get(position).getAsset_id());
holder.tv_quantity.setText(listData.get(position).getPurchase_cost());
holder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showCreateDialog(position);
}
});
holder.btn_edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activityContext, "Edit", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
if(listData.isEmpty()) return 0;
else return listData.size();
}
public class ItemHolder extends RecyclerView.ViewHolder{
private ImageView iv_asset;
private TextView tv_name;
private TextView tv_manufacturer;
private TextView tv_quantity;
private TextView tv_status;
private ImageButton btn_edit;
private ImageButton btn_delete;
public ItemHolder(View itemView) {
super(itemView);
iv_asset = itemView.findViewById(R.id.iv_asset);
tv_name = itemView.findViewById(R.id.tv_name);
tv_manufacturer = itemView.findViewById(R.id.tv_manufacturer);
tv_quantity = itemView.findViewById(R.id.tv_quantity);
tv_status = itemView.findViewById(R.id.tv_status);
btn_edit = itemView.findViewById(R.id.btn_edit);
btn_delete = itemView.findViewById(R.id.btn_delete);
}
}
private void showCreateDialog(final int id){
Log.i(TAG, "showCreateDialog: called");
MaterialDialog.Builder builder = new MaterialDialog.Builder(activityContext)
.content("Are you sure you want to delete this data?")
.contentGravity(GravityEnum.CENTER)
.autoDismiss(true)
.positiveText("Yes")
.negativeText("No")
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
//deleteAsset(id);
}
})
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
// do nothing
}
})
.canceledOnTouchOutside(true);
dialog = builder.build();
dialog.show();
}
}
我认为我正确地传递了上下文,因为我没有表现出敬酒的问题。所以我不确定我做错了什么。任何答案将不胜感激,谢谢。
答案 0 :(得分:1)
在适配器中使用这样的界面
public class AssetsAdapter extends RecyclerView.Adapter<AssetsAdapter.ItemHolder>{
private static final String TAG = "AssetsAdapter";
private OnButtonClickListener listener;
...........
..........
.........
public AssetsAdapter(ArrayList<Asset> listData, Context activityContext, UserService userService,OnButtonClickListener listener) {
this.listData = listData;
this.activityContext = activityContext;
this.listener = listener;
}
.......
......
...
..
@Override
public void onBindViewHolder(@NonNull ItemHolder holder, final int position) {
holder.tv_name.setText(listData.get(position).getName());
holder.tv_manufacturer.setText(listData.get(position).getAsset_id());
holder.tv_quantity.setText(listData.get(position).getPurchase_cost());
holder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
listener.showCreateDialog();
}
});
holder.btn_edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activityContext, "Edit", Toast.LENGTH_SHORT).show();
}
});
}
创建类似的界面
public interface OnButtonClickListener {
void showCreateDialog();
}
在您的活动中实现界面,并在该方法的实现中创建材料对话框。
答案 1 :(得分:1)
您可以使用EventBus
在您的 gradle文件
中dependencies {
implementation 'org.greenrobot:eventbus:3.1.1'
}
在 onBindViewHolder
holder.btn_delete.setTag(holder);
holder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ItemHolder myItemHolder = (ItemHolder) v.getTag();
EventBus.getDefault().post(listData.get(myItemHolder.getAdapterPosition()));
}
});
在活动
中 @Override
protected void onStart () {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop () {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void deleteAssetEvent (Asset asset){
//Call your dialog here
}
答案 2 :(得分:1)
因为您正在使用适配器内的对话框视图。不要在适配器内进行诸如clickListeners之类的操作。使用界面执行点击操作。
内部适配器中添加点击侦听器
var mItemClickListener: MyCallback? = null
fun setOnClickListener(click: MyCallback) {
mItemClickListener = click
}
MyCallback
public interface MyCallback {
void onListClick(int position, Object _list);
}
点击适配器内的操作
holder.btn_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mItemClickListener.onListClick(getAdapterPosition(), yourItemModel)
}
});
活动/片段
MyAdapter myAdapter = new MyAdapter()
recyclerView.setAdapter(myAdapter)
myAdapter.setOnClickListener(new MyCallback(){
@Override
public void onListClick(Int position, Item yourItem) {
//here you can show dialog
showDialog()
}
})
希望对您有帮助:)