我是Java的android应用程序的新手。该示例应用程序应让我选择我想要在ListView中使用的货币。每次我想从列表中选择一种货币时,应用程序崩溃都会收到错误消息:

    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


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<WalutaNBP> waluty = 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 aktualnyWybor = v.isChecked();
                WalutaNBP waluta = (WalutaNBP) listView.getItemAtPosition(position);
                waluta.setWybrana(aktualnyWybor);
            }
        });

        pobierzWaluty();
    }

    private void pobierzWaluty() {
        progressDialog = ProgressDialog.show(context, "Pobieram waluty",
                "Proszę czekać...", 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 WalutyNBP[] walutyNBP = gson.fromJson(is, WalutyNBP[].class);
                        nbpConnection.disconnect();

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                waluty.addAll(Arrays.asList(walutyNBP[0].getWaluty()));
                                Collections.sort(waluty);
                                ArrayAdapter<WalutaNBP> arrayAdapter =
                                        new ArrayAdapter<WalutaNBP>(context,
                                                android.R.layout.simple_list_item_1, waluty);
                                listView.setAdapter(arrayAdapter);
                                zaznaczWybrane();
                                progressDialog.dismiss();
                            }
                        });
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                progressDialog.dismiss();
                                Toast.makeText(context, "Wystąpił problem z pobraniem danych",
                                        Toast.LENGTH_LONG).show();
                            }
                        });
                    }
                } catch(Exception e) {
                    e.printStackTrace();

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            progressDialog.dismiss();
                            Toast.makeText(context, "Wystąpił problem z pobraniem danych",
                                    Toast.LENGTH_LONG).show();
                        }
                    });
                }
            }
        });
    }

    private void zaznaczWybrane() {
        SharedPreferences pref =
                PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        Set<String> kodyWybranychWalut = pref.getStringSet("kodyWalut", new HashSet<String>());

        for(int i = 0; i < waluty.size(); i++) {
            WalutaNBP waluta = waluty.get(i);
            if(kodyWybranychWalut.contains(waluta.getCode())) {
                waluta.setWybrana(true);
                listView.setItemChecked(i, true);
            }
        }
    }

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

        for(WalutaNBP waluta : waluty) {
            if(waluta.isWybrana()) {
                kodyWybranychWalut.add(waluta.getCode());
            }
        }

        pref.edit().putStringSet("kodyWalut", kodyWybranychWalut).apply();
    }
}


activity_main.xml

<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="zapiszWybrane"
        android:text="Zapisz"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>


WalutyNBP.java


import com.google.gson.annotations.SerializedName;

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

    @SerializedName(value = "rates")
    private WalutaNBP[] waluty;

    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 WalutaNBP[] getWaluty() {
        return waluty;
    }

    public void setWaluty(WalutaNBP[] waluty) {
        this.waluty = waluty;
    }
}


WalutaNBP.java


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

    private transient boolean wybrana = false;

    public WalutaNBP() {
    }

    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 isWybrana() {
        return wybrana;
    }

    public void setWybrana(boolean wybrana) {
        this.wybrana = wybrana;
    }

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

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


在日志中,我可以看到导致所有混乱的行:
CheckedTextView v = (CheckedTextView) view;

该错误的原因是什么?我已经查看了StackOverflow上的其他答案,但仍然找不到任何解决方案。也许我只是看不到明显的错误。感谢帮助。

最佳答案

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);
        }
    });


在这里,您可以设置点击监听器。 “视图”字段是从适配器返回的,它是TextView。这样就可以得到castexception。在这种方法中,您可以使用id和position字段。

如果要启用多选,则需要使用其他布局来构建ArrayAdapter,如下所示:

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

09-27 15:36