java - RecyclerViewAdapter OnBindViewHolder 的 ID 为空

标签 java android android-recyclerview

我正在编写一个天气预报应用程序,我想尝试实现一个 RecyclerView,这样我基本上就可以拥有一个横向滚动的 ListView。但是,当我设置文本时,由于 View ID 为空,我的 onBindViewHolder() 会抛出 NPE,即使在创建 ViewHolder 时 ID 不为空。如果您能帮助我找到差异,我将不胜感激。谢谢你!

我的代码如下:

主要 Activity :

public class MainActivity extends AppCompatActivity {
EditText searchText;
Button searchButton;
Context context;
int count = 1; // default to one - potentially change later
RecyclerView recyclerView;

WeatherAdapter 适配器; ArrayList 天气列表;

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

适配器:

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:

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
}

}

自定义行 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>

主要 Activity 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>

日志猫:

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)

最佳答案

您的问题出在您的 ViewHolder.java 类中。在构造函数中,您正在定义和初始化新变量,而不是私有(private)变量。所以更换

TextView dateText = (TextView)view.findViewById(R.id.dateTextID);
TextView dayText = (TextView)view.findViewById(R.id.dayTextID);

this.dateText = (TextView)view.findViewById(R.id.dateTextID);
this.dayText = (TextView)view.findViewById(R.id.dayTextID);

或者简单地使用:

dateText = (TextView)view.findViewById(R.id.dateTextID);
dayText = (TextView)view.findViewById(R.id.dayTextID);

关于java - RecyclerViewAdapter OnBindViewHolder 的 ID 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36682384/

相关文章:

java - 有人能解释一下舍入误差是什么意思吗?

java - 我想在弹出窗口中显示旋转结果而不是 toast

android - 使用 RecyclerView 时出现空指针异常

android - RecyclerView 小部件行上的斑马条纹颜色效果

android - 如何在 RecyclerView 中使用不同的 View

java - 如何使用 xml 文件对我的 HtmlUnit 代码进行单元测试

java - 在java中保存多个附件

安卓安装referrer1.1 bug

java - PathClassLoader 的实例是在何时何地在 android 源代码中创建的?

android - 想要增加字符串中 unicode 代理对符号的大小,例如数学符号 i