[英]RecyclerViewAdapter OnBindViewHolder has null IDs
I'm writing a Weather forecast app and I wanted to try to implement a RecyclerView so that I can have essentially a side-scrolling ListView. 我正在编写一个天气预报应用程序,我想尝试实现一个RecyclerView,这样我就可以实现一个侧滚动的ListView。 However, my onBindViewHolder() throws NPEs when I set the text due to view IDs being null, even though the ID is not null when the ViewHolder is created.
但是,由于视图ID为null,我的onBindViewHolder()在设置文本时会抛出NPE,即使在创建ViewHolder时ID不为null。 I would appreciate any help in finding the discrepancy.
如果发现差异,我将不胜感激。 Thank you!
谢谢!
My code is as follows: 我的代码如下:
MainActivity: 主要活动:
public class MainActivity extends AppCompatActivity {
EditText searchText;
Button searchButton;
Context context;
int count = 1; // default to one - potentially change later
RecyclerView recyclerView;
WeatherAdapter adapter; WeatherAdapter适配器; ArrayList weatherList;
ArrayList weatherList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
recyclerView = (RecyclerView)findViewById(R.id.recyclerViewID);
LinearLayoutManager manager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(manager);
adapter = new WeatherAdapter(context, weatherList);
recyclerView.setAdapter(adapter);
searchText = (EditText) findViewById(R.id.citySearchID);
searchButton = (Button) findViewById(R.id.searchButtonID);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) { startSearch(view); }
});
}
public void startSearch(View view) {
JSONWeatherTask task = new JSONWeatherTask();
String s = searchText.getText().toString();
if (s.isEmpty()){
Toast.makeText(this, R.string.searchError, Toast.LENGTH_SHORT).show();
return;
}
try{ task.execute(s.replaceAll("\\s+", ""));
} catch (Exception e) {
Toast.makeText(this, R.string.searchError, Toast.LENGTH_SHORT).show();
}
}
private class JSONWeatherTask extends AsyncTask<String, Void, ArrayList<Weather>> {
@Override
protected ArrayList<Weather> doInBackground(String... strings) {
weatherList = new ArrayList<>();
JSONObject jObj = ((new WeatherHttpClient()).getWeatherData(strings[0], count));
try { weatherList = JSONWeatherParser.getWeather(jObj, count);
} catch (JSONException e) { e.printStackTrace(); }
return weatherList;
}
@Override
protected void onPostExecute(ArrayList<Weather> weatherList) {
super.onPostExecute(weatherList);
LinearLayoutManager manager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(manager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new WeatherAdapter(context, weatherList);
recyclerView.setAdapter(adapter);
}
}
}
Adapter: 适配器:
public class WeatherAdapter extends RecyclerView.Adapter<ViewHolder> {
private final Context context;
private final ArrayList<Weather> weatherList;
public WeatherAdapter(Context context, ArrayList<Weather> weatherList){
this.context = context;
this.weatherList = weatherList;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
LayoutInflater infl = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = infl.inflate(R.layout.weather_row, null);
ViewHolder holder = new ViewHolder(v);
return holder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int pos){
Weather weather = weatherList.get(pos);
String[] Days = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"};
long unixSeconds = weather.currentCondition.getDate();
Date date = new Date(unixSeconds * 1000L);
SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd");
String formattedDate = dateFormat.format(date);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(unixSeconds * 1000L);
holder.dateText.setText(formattedDate);
holder.dayText.setText(Days[cal.get(Calendar.DAY_OF_WEEK)-1]);
// set other TextViews in the same way
}
@Override
public int getItemCount() {
try{ return weatherList.size();
} catch (NullPointerException e) { return 0; }
}
}
ViewHolder: ViewHolder:
public class ViewHolder extends RecyclerView.ViewHolder{
TextView dateText;
TextView dayText;
// Other TextViews in the same vein
public ViewHolder (View view){
super(view);
TextView dateText = (TextView)view.findViewById(R.id.dateTextID);
TextView dayText = (TextView)view.findViewById(R.id.dayTextID);
// Other TextViews in the same vein
}
}
CustomRow xml: CustomRow xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/dateTextID"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/dayTextID"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<!-- Etc with more TextViews -->
</LinearLayout>
MainActivity xml: MainActivity xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/citySearchID"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:inputType="text"
android:hint="@string/cityHint"/>
<Button
android:id="@+id/searchButtonID"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_weight="1"
android:text="@string/search"/>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerViewID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Logcat: logcat的:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.ak.niceweather.WeatherAdapter.onBindViewHolder(WeatherAdapter.java:48)
at com.ak.niceweather.WeatherAdapter.onBindViewHolder(WeatherAdapter.java:17)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5217)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5250)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4487)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4363)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1961)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1370)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1333)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:562)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2900)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3071)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:435)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
at android.view.View.layout(View.java:15596)
at android.view.ViewGroup.layout(ViewGroup.java:4966)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2072)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1829)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Your problem lies in your ViewHolder.java
class. 您的问题出在
ViewHolder.java
类中。 In the constructor you are defining and initializing new variables and not your private ones. 在构造函数中,您正在定义和初始化新变量而不是私有变量。 So replace
所以更换
TextView dateText = (TextView)view.findViewById(R.id.dateTextID);
TextView dayText = (TextView)view.findViewById(R.id.dayTextID);
With 同
this.dateText = (TextView)view.findViewById(R.id.dateTextID);
this.dayText = (TextView)view.findViewById(R.id.dayTextID);
Or simply with: 或者只是:
dateText = (TextView)view.findViewById(R.id.dateTextID);
dayText = (TextView)view.findViewById(R.id.dayTextID);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.