AlertDialog 无法在自定义适配器中获取上下文
AlertDialog can't get context in custom adapter
当我从适配器的 ViewHolder 按下按钮时,我试图显示 AlertDialog。但是当我用下一条消息启动这个崩溃时。
E/AndroidRuntime: FATAL EXCEPTION: main
Process: cl.abitsoft.todotick, PID: 4172
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:798)
public class CustomAdapter extends ArrayAdapter<RowModel> implements View.OnClickListener {
private ArrayList<RowModel> DataSet;
Context context;
private static class ViewHolder {
[...]
}
public CustomAdapter(ArrayList<RowModel> data, Context context) {
super(context, R.layout.list_item_main, data);
this.DataSet = data;
this.context = context;
}
@Override
public void onClick(View v) {
int position = (Integer) v.getTag();
final Object object = getItem(position);
switch (v.getId()) {
case R.id.list_delete_button:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.show();
break;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
[...]
}
}
编辑:添加了 MainActivity.class
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener {
ListView listview;
private CustomAdapter adapter;
private Button no, button_accept;
private EditText edittext_title;
private Spinner spinner_classes;
private RowModel rowModel;
private ArrayList<RowModel> row_models;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(this);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// Se inicializan las variables
edittext_title = findViewById(R.id.main_edittext_title);
spinner_classes = findViewById(R.id.main_spinner_classes);
button_accept = findViewById(R.id.main_button_accept);
listview = findViewById(R.id.main_listview);
row_models = new ArrayList<>();
adapter = new CustomAdapter(row_models, getApplicationContext());
// AL ListView se le asigna el Adapter con el tipo de objeto que usaremos
listview.setAdapter(adapter);
// Creamos un arreglo del tipo String con las variables para el Spinner
String[] values = {"Pagar", "Cobrar", "Llamar", "Pedir", "Comprar", "Revisar", "Otro"};
// Agregamos las variables a nuestro Spinner
spinner_classes.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.spinner_main, values));
// Habilitamos el click en nuestro boton
button_accept.setOnClickListener(this);
loadRows();
}
[...]
您可以像这样从您的 View
中获取 Context
:
@Override public void onClick(View v) {
int position = (Integer) v.getTag();
final Object object = getItem(position);
switch (v.getId()) {
case R.id.list_delete_button:
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.show();
break;
}
}
传递您全局声明的上下文
AlertDialog.Builder builder = new AlertDialog.Builder(context);
并将以下行更改为
adapter = new CustomAdapter(row_models, getApplicationContext());
到
adapter = new CustomAdapter(row_models, this);
希望对您有所帮助。
进行这 3 项更改以解决您的问题,
CustomAdapter 中的第一遍 "this"。
adapter = new CustomAdapter(row_models,this);
在 CustomAdapter 中获取 Activity。
public CustomAdapter(ArrayList<RowModel> data, Activity activity) {
super(context, R.layout.list_item_main, data);
this.DataSet = data;
this.context = context;
}
使用 "activity" 创建 AlertDialoge。
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
您将必须使用 Activity
实例或可以将 Context
类型转换为 Activity
,如下所示:
AlertDialog.Builder builder = new AlertDialog.Builder(YourActivity.this);
或
AlertDialog.Builder builder = new AlertDialog.Builder((Activity)context);
和你展示的地方 AlertDialog
然后做这样的事情
if(!((Activity)context).isFinishing())
{
builder.show();
}
你不会得到那个例外
当我从适配器的 ViewHolder 按下按钮时,我试图显示 AlertDialog。但是当我用下一条消息启动这个崩溃时。
E/AndroidRuntime: FATAL EXCEPTION: main Process: cl.abitsoft.todotick, PID: 4172 android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running? at android.view.ViewRootImpl.setView(ViewRootImpl.java:798)
public class CustomAdapter extends ArrayAdapter<RowModel> implements View.OnClickListener {
private ArrayList<RowModel> DataSet;
Context context;
private static class ViewHolder {
[...]
}
public CustomAdapter(ArrayList<RowModel> data, Context context) {
super(context, R.layout.list_item_main, data);
this.DataSet = data;
this.context = context;
}
@Override
public void onClick(View v) {
int position = (Integer) v.getTag();
final Object object = getItem(position);
switch (v.getId()) {
case R.id.list_delete_button:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.show();
break;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
[...]
}
}
编辑:添加了 MainActivity.class
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, View.OnClickListener {
ListView listview;
private CustomAdapter adapter;
private Button no, button_accept;
private EditText edittext_title;
private Spinner spinner_classes;
private RowModel rowModel;
private ArrayList<RowModel> row_models;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(this);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// Se inicializan las variables
edittext_title = findViewById(R.id.main_edittext_title);
spinner_classes = findViewById(R.id.main_spinner_classes);
button_accept = findViewById(R.id.main_button_accept);
listview = findViewById(R.id.main_listview);
row_models = new ArrayList<>();
adapter = new CustomAdapter(row_models, getApplicationContext());
// AL ListView se le asigna el Adapter con el tipo de objeto que usaremos
listview.setAdapter(adapter);
// Creamos un arreglo del tipo String con las variables para el Spinner
String[] values = {"Pagar", "Cobrar", "Llamar", "Pedir", "Comprar", "Revisar", "Otro"};
// Agregamos las variables a nuestro Spinner
spinner_classes.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.spinner_main, values));
// Habilitamos el click en nuestro boton
button_accept.setOnClickListener(this);
loadRows();
}
[...]
您可以像这样从您的 View
中获取 Context
:
@Override public void onClick(View v) {
int position = (Integer) v.getTag();
final Object object = getItem(position);
switch (v.getId()) {
case R.id.list_delete_button:
AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.show();
break;
}
}
传递您全局声明的上下文
AlertDialog.Builder builder = new AlertDialog.Builder(context);
并将以下行更改为
adapter = new CustomAdapter(row_models, getApplicationContext());
到
adapter = new CustomAdapter(row_models, this);
希望对您有所帮助。
进行这 3 项更改以解决您的问题,
CustomAdapter 中的第一遍 "this"。
adapter = new CustomAdapter(row_models,this);
在 CustomAdapter 中获取 Activity。
public CustomAdapter(ArrayList<RowModel> data, Activity activity) { super(context, R.layout.list_item_main, data); this.DataSet = data; this.context = context; }
使用 "activity" 创建 AlertDialoge。
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
您将必须使用 Activity
实例或可以将 Context
类型转换为 Activity
,如下所示:
AlertDialog.Builder builder = new AlertDialog.Builder(YourActivity.this);
或
AlertDialog.Builder builder = new AlertDialog.Builder((Activity)context);
和你展示的地方 AlertDialog
然后做这样的事情
if(!((Activity)context).isFinishing())
{
builder.show();
}
你不会得到那个例外