2016-08-02 4 views
0

У меня есть recyclerView, что получить мне аварии:Android - RecyclerView NullPointerException getItemCount?

enter image description here

Вот мой StartActivity:

public class StartActivity extends AppCompatActivity { 

    TextView txtTest; 
    private ProgressDialog pDialog; 
    // These tags will be used to cancel the requests 
    private String tag_json_obj = "jobj_req", tag_json_arry = "jarray_req"; 

    private RecyclerView.Adapter mAdapter; 
    RecyclerView UserCode_Recycler; 
    private LinearLayoutManager mLayoutManager; 


    List<Marketing_Code> userCodeList; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_start); 
     txtTest = (TextView) findViewById(R.id.txtTest); 
     UserCode_Recycler = (RecyclerView) findViewById(R.id.UserCode_Recycler); 
     pDialog = new ProgressDialog(this); 
     pDialog.setMessage("Loading..."); 
     pDialog.setCancelable(false); 

     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     if (fab != null) { 
      fab.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 
          .setAction("Action", null).show(); 
       } 
      }); 
     } 

     makeJsonArryReq(); 

     userCodeList = new ArrayList<>(); 
     // create an Object for Adapter 
     mAdapter = new UserCodeList_Adapter(userCodeList, StartActivity.this); 
     // set the adapter object to the Recyclerview 
     UserCode_Recycler.setAdapter(mAdapter); 

     mAdapter.notifyDataSetChanged(); 


     UserCode_Recycler.setHasFixedSize(true); 

     mLayoutManager = new LinearLayoutManager(this); 
     // use a linear layout manager 
     UserCode_Recycler.setLayoutManager(mLayoutManager); 

    } 

    private void showProgressDialog() { 
     if (!pDialog.isShowing()) 
      pDialog.show(); 
    } 

    private void hideProgressDialog() { 
     if (pDialog.isShowing()) 
      pDialog.hide(); 
    } 


    /** 
    * Making json array request 
    */ 
    private void makeJsonArryReq() { 
     showProgressDialog(); 
     JsonArrayRequest req = new JsonArrayRequest(Const.Marketing_List, 
       new Response.Listener<JSONArray>() { 
        @Override 
        public void onResponse(JSONArray response) { 
         Log.d("MYData", response.toString()); 
         userCodeList = MarketingCode_JSONParser.parseFeed(response.toString()); 
         /* // create an Object for Adapter 
         mAdapter = new UserCodeList_Adapter(userCodeList, StartActivity.this); 
         // set the adapter object to the Recyclerview 
         Search_Recycler.setAdapter(mAdapter); 
         mAdapter.notifyDataSetChanged(); 
         //txtTest.setText(response.toString());*/ 
         mAdapter.notifyDataSetChanged(); 
         hideProgressDialog(); 
        } 
       }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       VolleyLog.d("Custom Log Error", "Error: " + error.getMessage()); 
       hideProgressDialog(); 
      } 
     }); 

     // Adding request to request queue 
     AppController.getInstance().addToRequestQueue(req, tag_json_arry); 
     // Cancelling request 
     // ApplicationController.getInstance().getRequestQueue().cancelAll(tag_json_arry); 
    } 


    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 
} 

И мой адаптер:

public class UserCodeList_Adapter extends RecyclerView.Adapter<UserCodeList_Adapter.ViewHolder> { 

    private List<Marketing_Code> ucList; 
    public static Activity activity; 
    public UserCodeList_Adapter(List<Marketing_Code> userCodeList, Activity activity) { 
     this.ucList = userCodeList; 
     this.activity = activity; 
    } 
    @Override 
    public UserCodeList_Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     // create a new view 
     View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.listmarketing_cardview, null); 

     // create ViewHolder 
     ViewHolder viewHolder = new ViewHolder(itemLayoutView); 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(UserCodeList_Adapter.ViewHolder viewHolder, int position) { 
     String userCode =String.valueOf(ucList.get(position).getMarketCode()); 
     viewHolder.txtUserID.setText(userCode); 
    } 

    @Override 
    public int getItemCount() { 
     return ucList.size(); 
     //return ucList == null ? 0 : ucList.size(); 
    } 

    public static class ViewHolder extends RecyclerView.ViewHolder { 

     public TextView txtUserID; 

     public Marketing_Code items; 

     public ViewHolder(View itemLayoutView) { 
      super(itemLayoutView); 

      txtUserID = (TextView) itemLayoutView.findViewById(R.id.txtUserID); 
      // Onclick event for the row to show the data in toast 
      itemLayoutView.setOnClickListener(new View.OnClickListener() { 

       @Override 
       public void onClick(View v) { 
       } 
      }); 

     } 

    } 
} 

ответ

3

Вы не инициализирован ваш userCodeList.

Увидев ваш код, вы подключили свой адаптер к этому списку, пока он еще не инициализирован. Следовательно, когда адаптер попытался узнать, сколько предметов у вашего списка есть, он выбрасывает NullPointerException.

Изменить декларацию userCodeList к одному, как показано ниже:

List<Marketing_Code> userCodeList = new ArrayList<>(); 

Видя ваш обновленный вопрос, вы, похоже, основывают свои данные из ответа JSON. Если это так, то, что вы сейчас делаете, это почти правильно.

Наблюдайте это слегка измененный фрагмент кода:

private void makeJsonArryReq() { 
    showProgressDialog(); 
    JsonArrayRequest req = new JsonArrayRequest(Const.Marketing_List, 
      new Response.Listener<JSONArray>() { 
       @Override 
       public void onResponse(JSONArray response) { 
        Log.d("MYData", response.toString()); 
        /* YOUR OLD CODE -> */ // userCodeList = MarketingCode_JSONParser.parseFeed(response.toString()); 
        /* HOW IT SHOULD'VE BEEN */ userCodeList.addAll(MarketingCode_JSONParser.parseFeed(response.toString())); 
        mAdapter.notifyDataSetChanged(); 
        hideProgressDialog(); 
       } 
      }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      VolleyLog.d("Custom Log Error", "Error: " + error.getMessage()); 
      hideProgressDialog(); 
     } 
    }); 

// ... 

Посмотрите на комментировал части выше фрагмента кода. Это должно решить вашу проблему и сделать данные видимыми на экране.

+0

Не поймите меня любую аварию сейчас, но мой список еще пуст? –

+0

Это правда? String userCode = String.valueOf (ucList.get (position) .getMarketCode()); –

+0

Ну, это ..Вы должны заполнить этот «Список» позже в этом процессе. Просто вызовите 'adapter.notifyDataSetChaged()' как только вы это сделаете, и вы увидите, что ваши элементы отображаются на экране. – ridsatrio

1

Два способа справиться с этим:

  1. Вы должны проверить, если список NULL перед запросом, чтобы проверить его размер

    public int getItemCount() { 
        if(ucList == null) 
         return 0; 
        return ucList.size(); 
    } 
    
  2. В качестве альтернативы, и это рекомендуемый подход к этот вопрос, должен инициализировать его пустым списком в начале или убедиться, что он всегда инициализирован до того, как он будет доступен соответствующим адаптером.

    List<Marketing_Code> userCodeList = new ArrayList<>();

Надеется, что это помогает.

+0

Первый способ может работать. Но нет никакой гарантии, что он остановит последующие сбои, вызванные «нулевым» списком. Адаптеры в значительной степени полагаются на свой «Список», поэтому он никогда не должен быть «нулем» в первую очередь. – ridsatrio

+0

Согласен. Обновленная точка ответа 2 для указания рекомендуемого подхода с помощью инициализации перед доступом – akdsouza

0

Я думаю, вам нужно использовать функцию replaceAll для списка вместо прямого приравнивания. Здесь

userCodeList = MarketingCode_JSONParser.parseFeed(response.toString()); 

Попробуйте проверить, если userCodeList содержит какие-либо данные, прежде чем initialzing адаптер.

0

Пожалуйста сделайте следующее и попробуйте

// create an Object for Adapter   
    userCodeList = new ArrayList<>(); 
    mAdapter = new UserCodeList_Adapter(userCodeList, StartActivity.this); 
Смежные вопросы