简体   繁体   中英

androidx.appcompat.widget.AppCompatTextView cannot be cast to android.widget.CheckedTextView

I'm new in android apps in Java. The example app should let me choose currencies I want to have in the ListView . Every time I want to choose a currency from the list, the app crashes I get the error:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.a5_listview, PID: 12333
    java.lang.ClassCastException: androidx.appcompat.widget.AppCompatTextView cannot be cast to android.widget.CheckedTextView
        at com.example.a5_listview.MainActivity$1.onItemClick(MainActivity.java:48)

MainActivity.java :

package com.example.a5_listview;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ListView;
import android.widget.Toast;

import com.google.gson.Gson;

import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class MainActivity extends AppCompatActivity {

    List<nbpCurrency> currencies = new ArrayList<>();
    ListView listView;
    Context context;
    ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView);
        context = this;

        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CheckedTextView v = (CheckedTextView) view;
                boolean isCurrentChoice = v.isChecked();
                nbpCurrency currency = (nbpCurrency) listView.getItemAtPosition(position);
                currency.setChosen(isCurrentChoice);
            }
        });
        
        getCurrencies();
    }

    private void getCurrencies() {
        progressDialog = ProgressDialog.show(context, "Getting currencies",
                "Please wait...", true);

        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    URL nbpEndpoint =
                            new URL("http://api.nbp.pl/api/exchangerates/tables/a/");
                    HttpURLConnection nbpConnection =
                            (HttpURLConnection) nbpEndpoint.openConnection();
                    nbpConnection.setRequestProperty("Accept", "application/json");

                    if(nbpConnection.getResponseCode() == 200) {
                        InputStreamReader is =
                                new InputStreamReader(nbpConnection.getInputStream());
                        Gson gson = new Gson();
                        final nbpCurrencies[] nbpCurrenciesArray = gson.fromJson(is, nbpCurrencies[].class);
                        nbpConnection.disconnect();

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                currencies.addAll(Arrays.asList(nbpCurrenciesArray[0].getCurrencies()));
                                Collections.sort(currencies);
                                ArrayAdapter<nbpCurrency> arrayAdapter =
                                        new ArrayAdapter<nbpCurrency>(context,
                                                android.R.layout.simple_list_item_1, currencies);
                                listView.setAdapter(arrayAdapter);
                                selectChosen();
                                progressDialog.dismiss();
                            }
                        });
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                progressDialog.dismiss();
                                Toast.makeText(context, "There was a problem getting the data",
                                        Toast.LENGTH_LONG).show();
                            }
                        });
                    }
                } catch(Exception e) {
                    e.printStackTrace();

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            progressDialog.dismiss();
                            Toast.makeText(context, "There was a problem getting the data",
                                    Toast.LENGTH_LONG).show();
                        }
                    });
                }
            }
        });
    }

    private void selectChosen() {
        SharedPreferences pref =
                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        Set<String> chosenCurrenciesCodes = pref.getStringSet("currenciesCodes", new HashSet<String>());

        for(int i = 0; i < currencies.size(); i++) {
            nbpCurrency currency = currencies.get(i);
            if(chosenCurrenciesCodes.contains(currency.getCode())) {
                currency.setChosen(true);
                listView.setItemChecked(i, true);
            }
        }
    }

    public void saveChosen(View view) {
        SharedPreferences pref =
                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        Set<String> chosenCurrenciesCodes = new HashSet<>();

        for(nbpCurrency currency : currencies) {
            if(currency.isChosen()) {
                chosenCurrenciesCodes.add(currency.getCode());
            }
        }

        pref.edit().putStringSet("currenciesCodes", chosenCurrenciesCodes).apply();
    }
}

activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    </ListView>

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:onClick="saveChosen"
        android:text="Save"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

nbpCurrencies.java :

package com.example.a5_listview;

import com.google.gson.annotations.SerializedName;

public class nbpCurrencies {
    private String table;
    private String no;
    private String effectiveDate;

    @SerializedName(value = "rates")
    private nbpCurrency[] currencies;

    public String getTable() {
        return table;
    }

    public void setTable(String table) {
        this.table = table;
    }

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

    public String getEffectiveDate() {
        return effectiveDate;
    }

    public void setEffectiveDate(String effectiveDate) {
        this.effectiveDate = effectiveDate;
    }

    public nbpCurrency[] getCurrencies() {
        return currencies;
    }

    public void setCurrencies(nbpCurrency[] currencies) {
        this.currencies = currencies;
    }
}

nbpCurrency.java :

package com.example.a5_listview;

class nbpCurrency implements Comparable<nbpCurrency> {
    private String currency;
    private String code;
    private double mid;

    private transient boolean chosen = false;

    public nbpCurrency() {
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public double getMid() {
        return mid;
    }

    public void setMid(double mid) {
        this.mid = mid;
    }

    public boolean isChosen() {
        return chosen;
    }

    public void setChosen(boolean chosen) {
        this.chosen = chosen;
    }

    @Override
    public String toString() {
        return String.format("%s [%s: %.3f]", code, currency, mid);
    }

    @Override
    public int compareTo(nbpCurrency nbpCurrency) {
        return code.compareTo(nbpCurrency.getCode());
    }
}

In logs I can see the line causing all of mess: CheckedTextView v = (CheckedTextView) view;

What is cause of that error? I've looked through other answers on StackOverflow but I still can't find any solution. Maybe I just don't see an obvious mistake. Thanks for help.

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            CheckedTextView v = (CheckedTextView) view;
            boolean aktualnyWybor = v.isChecked();
            WalutaNBP waluta = (WalutaNBP) listView.getItemAtPosition(position);
            waluta.setWybrana(aktualnyWybor);
        }
    });

Here you set a clicklistener. The "view" field is returning from adapter and it is TextView. That's way you get castexception. In this method you get id and position fields you can use them.

and If you want to enabled multi choice you need to build your ArrayAdapter with another layout like this:

ArrayAdapter<WalutaNBP> arrayAdapter =
            new ArrayAdapter<WalutaNBP>(context,
                    android.R.layout.simple_list_item_multiple_choice, waluty);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM