回收器视图 android studio尝试在空对象引用上调用虚拟方法“void android.widget.TextView.setText(java.lang.CharSequence)”

Recycler view android studioAttempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

提问人:Sarimm Chaudhry 提问时间:7/19/2022 更新时间:7/26/2022 访问量:59

问:

我正在创建一个名为 Pricepointcrypto 的应用程序,其中当您的某种加密货币达到您的预算范围时,您会收到通知,说您想购买比特币 15,000 股市,您会收到通知,在这个应用程序中,我需要显示加密货币及其汇率,我正在使用 coinmarket cap API 在 adroid studio 中使用 java。我已经在 Java 中创建了请求和响应功能,它确实可以在 backewnd 上运行,但是当它尝试顶部渲染时,我在 rcyler 视图上遇到了布局问题,然后当我们想要 setText 时,它说它的 null

这是我得到的错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void 
android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

我只是停留在这部分,我已经尝试了许多测试,所以如果有人能提供帮助,那将非常有帮助

谢谢!

代码如下:

主要 Acitivty.java

package com.example.pricepointcrypto;

import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

private ArrayList<CurrencyModal> currencyModalArrayList;
private CurrencyRVAdapter currencyRVAdapter;
private ProgressBar loadingPB;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    EditText searchEdt = findViewById(R.id.idEdtCurrency);

    // initializing all our variables and array list.
    loadingPB = findViewById(R.id.idPBLoading);
    // creating variable for recycler view,
    // adapter, array list, progress bar
    RecyclerView currencyRV = findViewById(R.id.idRVcurrency);
    currencyModalArrayList = new ArrayList<>();

    // initializing our adapter class.
    currencyRVAdapter = new CurrencyRVAdapter(currencyModalArrayList, this);

    // setting layout manager to recycler view.
    currencyRV.setLayoutManager(new LinearLayoutManager(this));

    // setting adapter to recycler view.
    currencyRV.setAdapter(currencyRVAdapter);

    // calling get data method to get data from API.
    getData();

    // on below line we are adding text watcher for our
    // edit text to check the data entered in edittext.
    searchEdt.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            // on below line calling a
            // method to filter our array list
            filter(s.toString());
        }
    });
}

private void filter(String filter) {
    // on below line we are creating a new array list
    // for storing our filtered data.
    ArrayList<CurrencyModal> filteredlist = new ArrayList<>();
    // running a for loop to search the data from our array list.
    for (CurrencyModal item : currencyModalArrayList) {
        // on below line we are getting the item which are
        // filtered and adding it to filtered list.
        if (item.getName().toLowerCase().contains(filter.toLowerCase())) {
            filteredlist.add(item);
        }
    }
    // on below line we are checking
    // weather the list is empty or not.
    if (filteredlist.isEmpty()) {
        // if list is empty we are displaying a toast message.
        Toast.makeText(this, "No currency found..", Toast.LENGTH_SHORT).show();
    } else {
        // on below line we are calling a filter
        // list method to filter our list.
        currencyRVAdapter.filterList(filteredlist);
    }
}

private void getData() {
    // creating a variable for storing our string.
    String url = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest";
    // creating a variable for request queue.
    RequestQueue queue = Volley.newRequestQueue(this);
    // making a json object request to fetch data from API.
    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,          
response -> {
        // inside on response method extracting data
        // from response and passing it to array list
        // on below line we are making our progress
        // bar visibility to gone.
        loadingPB.setVisibility(View.GONE);
        try {
            // extracting data from json.
            JSONArray dataArray = response.getJSONArray("data");
            for (int i = 0; i < dataArray.length(); i++) {
                JSONObject dataObj = dataArray.getJSONObject(i);
                String symbol = dataObj.getString("symbol");
                String name = dataObj.getString("name");
                JSONObject quote = dataObj.getJSONObject("quote");
                JSONObject USD = quote.getJSONObject("USD");
                double price = USD.getDouble("price");

                String finalName = ""+name+" - "+symbol+"";

                // adding all data to our array list.
                currencyModalArrayList.add(new CurrencyModal(finalName, 
 R.drawable.ic_launcher_foreground, price));
            }
            // notifying adapter on data change.
            currencyRVAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
            // handling json exception.
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "Something went amiss. Please try again later", 
Toast.LENGTH_SHORT).show();
        }
    }, error -> {
        // displaying error response when received any error.
        Toast.makeText(MainActivity.this, "Something went amiss. Please try again later", 
Toast.LENGTH_SHORT).show();
    }) {
        @Override
        public Map<String, String> getHeaders() {
            // in this method passing headers as
            // key along with value as API keys.
            HashMap<String, String> headers = new HashMap<>();
            headers.put("X-CMC_PRO_API_KEY", "106d7841-b282-4c8c-aa0f-d53509398468");
            // at last returning headers
            return headers;
        }
    };
    // calling a method to add our
    // json object request to our queue.
    queue.add(jsonObjectRequest);
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/blac_shade_1"
tools:context=".MainActivity">

<!--edit text for searching our currency-->
<EditText
    android:id="@+id/idEdtCurrency"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:focusable="auto"
    android:hint="Search Currency"
    android:textColor="@color/white"
    android:textColorHint="@color/white" />

<!--recycler view for displaying the list of currencies-->
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/idRVcurrency"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/idEdtCurrency"
    tools:listitem="@layout/crypto_card_layout" />

<!--progress bar for loading indicator-->
<ProgressBar
    android:id="@+id/idPBLoading"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:visibility="gone" />

   </RelativeLayout>

货币RVApdapter

package com.example.pricepointcrypto;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.text.DecimalFormat;
import java.util.ArrayList;

// on below line we are creating our adapter class
// in this class we are passing our array list
// and our View Holder class which we have created.
public class CurrencyRVAdapter extends 
RecyclerView.Adapter<CurrencyRVAdapter.CurrencyViewholder> {
private static DecimalFormat df2 = new DecimalFormat("#.##");
private ArrayList<CurrencyModal> currencyModals;
private Context context;

public CurrencyRVAdapter(ArrayList<CurrencyModal> currencyModals, Context context) {
    this.currencyModals = currencyModals;
    this.context = context;
}

// below is the method to filter our list.
public void filterList(ArrayList<CurrencyModal> filterllist) {
    // adding filtered list to our
    // array list and notifying data set changed
    currencyModals = filterllist;
    notifyDataSetChanged();
}

@NonNull
@Override
public CurrencyRVAdapter.CurrencyViewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    // this method is use to inflate the layout file
    // which we have created for our recycler view.
    // on below line we are inflating our layout file.
    View view = LayoutInflater.from(context).inflate(R.layout.crypto_card_layout , parent, false);
    return new CurrencyViewholder(view);
}

@SuppressLint("SetTextI18n")
@Override
public void onBindViewHolder(@NonNull CurrencyRVAdapter.CurrencyViewholder holder, int position) {
    // on below line we are setting data to our item of
    // recycler view and all its views.

    CurrencyModal modal = currencyModals.get(position);



    holder.nameTV.setText(modal.getName());
    holder.rateTV.setText("$ " + df2.format(modal.getPrice()) + " USD");
    holder.symbolTV.setImageResource(modal.getSymbol());

}

@Override
public int getItemCount() {
    // on below line we are returning
    // the size of our array list.
    return currencyModals.size();
}

// on below line we are creating our view holder class
// which will be used to initialize each view of our layout file.
public class CurrencyViewholder extends RecyclerView.ViewHolder {
    private ImageView symbolTV;
    private TextView rateTV, nameTV;

    public CurrencyViewholder(@NonNull View itemView) {
        super(itemView);
        // on below line we are initializing all
        // our text views along with its ids.

        symbolTV = itemView.findViewById(R.id.currency_logo);
        rateTV = itemView.findViewById(R.id.currency_Rate);
        nameTV = itemView.findViewById(R.id.currency_name);

    }

 }
 }

货币模态

package com.example.pricepointcrypto;

public class CurrencyModal {
// variable for currency name,
// currency symbol and price.
private String name;
private int symbol;
private double price;

public CurrencyModal(String name, int symbol, double price) {
    this.name = name;
    this.symbol = symbol;
    this.price = price;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getSymbol() {
    return symbol;
}

public void setSymbol(int symbol) {
    this.symbol = symbol;
}

public double getPrice() {
    return price;
}

public void setPrice(double price) {
    this.price = price;
}
}

crypto_card_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>

<androidx.cardview.widget.CardView
    android:id="@+id/currency_card"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardBackgroundColor="#03A9F4"
    card_view:cardCornerRadius="20dp"
    card_view:cardElevation="5dp"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/currency_logo"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:layout_weight="1"
            android:src="@drawable/ic_launcher_foreground"
            android:tag="image_tag"
            android:contentDescription="@string/currencylogo" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:layout_weight="2"
            android:orientation="vertical">

            <TextView
                android:id="@+id/currency_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start|center_horizontal"
                android:layout_marginTop="10dp"
                android:fontFamily="casual"
                android:text="Currency Name"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="#FFEB3B"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/currency_Rate"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="start|center_horizontal"
                android:layout_marginTop="0dp"
                android:fontFamily="@font/stick"
                android:text="Current Rate: "
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="#FFFFFF"
                android:textColorHighlight="#FFFFFF"
                android:textStyle="bold|italic" />


        </LinearLayout>
        </LinearLayout>

   </androidx.cardview.widget.CardView>

  </LinearLayout>
java android android-layout android-recyclerview nullpointerexception

评论

0赞 DrHowdyDoo 7/20/2022
使 ImageView 和 TextView 在CurrencyViewholderCurrencyRVApdapter

答:

1赞 Sangita Elango 7/26/2022 #1
    View view = LayoutInflater.from(context).inflate(R.layout.crypto_card_layout , parent, false);

尝试设置 LayoutInflater.from(parent.getContext()) 而不是 LayoutInflater.from(context)