2016-04-17 9 views
1

Ich schreibe eine Wettervorhersage App und ich wollte versuchen, eine RecyclerView zu implementieren, so dass ich im Wesentlichen eine Side-Scroll-ListView haben kann. Wie dem auch sei, onBindViewHolder() löst NPEs aus, wenn ich den Text aufgrund von View-IDs auf null gesetzt habe, obwohl die ID beim Erstellen des ViewHolders nicht null ist. Ich würde jede mögliche Hilfe bei der Entdeckung der Diskrepanz schätzen. Vielen Dank!RecyclerViewAdapter OnBindViewHolder hat null IDs

Mein Code ist wie folgt:

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

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:

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

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

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) 

Antwort

0

Ihr Problem in Ihrer ViewHolder.java Klasse liegt. Im Konstruktor definieren und initialisieren Sie neue Variablen und nicht Ihre privaten. So ersetzen

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

Mit

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

Oder einfach mit:

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