androidx.appcompat.widget.AppCompatTextView 无法转换为 android.widget.CheckedTextView

huangapple go评论70阅读模式
英文:

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`:
```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

<details>
<summary>英文:</summary>

I&#39;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`:
```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&lt;nbpCurrency&gt; currencies = new ArrayList&lt;&gt;();
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&lt;?&gt; 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, &quot;Getting currencies&quot;,
&quot;Please wait...&quot;, true);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
URL nbpEndpoint =
new URL(&quot;http://api.nbp.pl/api/exchangerates/tables/a/&quot;);
HttpURLConnection nbpConnection =
(HttpURLConnection) nbpEndpoint.openConnection();
nbpConnection.setRequestProperty(&quot;Accept&quot;, &quot;application/json&quot;);
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&lt;nbpCurrency&gt; arrayAdapter =
new ArrayAdapter&lt;nbpCurrency&gt;(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, &quot;There was a problem getting the data&quot;,
Toast.LENGTH_LONG).show();
}
});
}
} catch(Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
progressDialog.dismiss();
Toast.makeText(context, &quot;There was a problem getting the data&quot;,
Toast.LENGTH_LONG).show();
}
});
}
}
});
}
private void selectChosen() {
SharedPreferences pref =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
Set&lt;String&gt; chosenCurrenciesCodes = pref.getStringSet(&quot;currenciesCodes&quot;, new HashSet&lt;String&gt;());
for(int i = 0; i &lt; 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&lt;String&gt; chosenCurrenciesCodes = new HashSet&lt;&gt;();
for(nbpCurrency currency : currencies) {
if(currency.isChosen()) {
chosenCurrenciesCodes.add(currency.getCode());
}
}
pref.edit().putStringSet(&quot;currenciesCodes&quot;, chosenCurrenciesCodes).apply();
}
}

activity_main.xml:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.MainActivity&quot;&gt;

    &lt;ListView
        android:id=&quot;@+id/listView&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;0dp&quot;
        android:layout_marginStart=&quot;16dp&quot;
        android:layout_marginTop=&quot;8dp&quot;
        android:layout_marginEnd=&quot;16dp&quot;
        android:layout_marginBottom=&quot;8dp&quot;
        app:layout_constraintBottom_toTopOf=&quot;@+id/button&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;&gt;
    &lt;/ListView&gt;

    &lt;Button
        android:id=&quot;@+id/button&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginBottom=&quot;16dp&quot;
        android:onClick=&quot;saveChosen&quot;
        android:text=&quot;Save&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot; /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

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 = &quot;rates&quot;)
    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&lt;nbpCurrency&gt; {
    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(&quot;%s [%s: %.3f]&quot;, 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.

答案1

得分: 1

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

在这里你设置了一个点击监听器。view 字段是从适配器返回的,它是一个 TextView。这就是你出现 ClassCastException 的方式。在这个方法中,你还可以获取 idposition 字段,并且你可以使用它们。

如果你想启用多选功能,你需要使用另一个布局来构建你的 ArrayAdapter,就像这样:

ArrayAdapter<nbpCurrency> arrayAdapter =
    new ArrayAdapter<nbpCurrency>(context,
        android.R.layout.simple_list_item_multiple_choice, currencies);
英文:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView&lt;?&gt; parent, View view, int position, long id) {
                CheckedTextView v = (CheckedTextView) view;
                boolean isCurrentChoice = v.isChecked();
                nbpCurrency currency = (nbpCurrency) listView.getItemAtPosition(position);
                currency.setChosen(isCurrentChoice);
            }
        });

Here you set a ClickListener. The view field is returned from adapter and it is TextView. That's the way you get CastException. In this method you also get id and position fields and you can use them.

If you want to enable multi-choice, you need to build your ArrayAdapter with another layout like this:

ArrayAdapter&lt;nbpCurrency&gt; arrayAdapter =
	new ArrayAdapter&lt;nbpCurrency&gt;(context,
		android.R.layout.simple_list_item_multiple_choice, currencies);

huangapple
  • 本文由 发表于 2020年4月7日 05:06:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/61068990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定