AlertDialog не может получить контекст в пользовательском адаптере - PullRequest
0 голосов
/ 12 февраля 2019

Я пытаюсь показать AlertDialog, когда я нажимаю кнопку из ViewHolder из моего адаптера.Но когда я запускаю этот сбой со следующим сообщением.

E / AndroidRuntime: FATAL EXCEPTION: main Процесс: cl.abitsoft.todotick, PID: 4172 android.view.WindowManager $ BadTokenException: невозможно добавитьwindow - токен null недействителен;ваша деятельность работает?atroid.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();
    }
    [...]

Ответы [ 4 ]

0 голосов
/ 12 февраля 2019

Вы должны будете использовать либо 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(); 
} 

Вы не получите это исключение

0 голосов
/ 12 февраля 2019

Передайте контекст, который вы объявили глобально

AlertDialog.Builder builder = new AlertDialog.Builder(context);

и измените следующую строку на

adapter = new CustomAdapter(row_models, getApplicationContext());

на

adapter = new CustomAdapter(row_models, this);

Надеюсь, это поможет.

0 голосов
/ 12 февраля 2019

Сделайте это 3 изменения, чтобы решить вашу проблему,

  1. первый проход "this" в CustomAdapter.

    adapter = new CustomAdapter(row_models,this);
    
  2. получите Activity вCustomAdapter.

    public CustomAdapter(ArrayList<RowModel> data, Activity activity) {
    super(context, R.layout.list_item_main, data);
    this.DataSet = data;
    this.context = context;
    }
    
  3. Создание AlertDialoge с использованием «Activity».

    AlertDialog.Builder builder = new AlertDialog.Builder(activity);
    
0 голосов
/ 12 февраля 2019

Вы можете получить Context от вашего View следующим образом:

@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; 
    } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...