我是Java中的android应用程序的新手。示例应用程序应该让我选择我想要在ListView
中使用的货币。每次我想从列表中选择一种货币时,应用程序崩溃,我得到错误:
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());
}
}
在日志中,我可以看到导致所有混乱的代码行:CheckedTextView v = (CheckedTextView) view;
该错误的原因是什么?我已经在StackOverflow上查看了其他答案,但我仍然找不到任何解决方案。也许我只是看不到一个明显的错误。谢谢你的帮助。
发布于 2020-04-06 21:23:11
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);
}
});
您可以在这里设置一个ClickListener
。适配器返回的view
字段为TextView
。这就是你获得CastException
的方式。在这个方法中,您还可以获得id
和position
字段,并且可以使用它们。
如果您希望启用多项选择,则需要使用如下所示的另一个布局构建ArrayAdapter
:
ArrayAdapter<nbpCurrency> arrayAdapter =
new ArrayAdapter<nbpCurrency>(context,
android.R.layout.simple_list_item_multiple_choice, currencies);
https://stackoverflow.com/questions/61068990
复制