【问题标题】:RecyclerView returning null for adapter position [duplicate]RecyclerView为适配器位置返回null [重复]
【发布时间】:2019-12-08 18:50:26
【问题描述】:

在我的应用程序中,我有一个 Mysql,我通过 volley 获取数据并用它填充 recyclerView所以我需要餐厅 id 及其位置,因为我数据库中的 note 表是一个子表,它使用 FK 连接到餐厅表并使用餐厅 id 作为参考,我不知道为什么我为适配器获取 NPE。getPosition 请帮助

主活动

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener{
    RecyclerView recyclerView;
    RecyclerView.Adapter mAdapter;
    RecyclerView.LayoutManager layoutManager;
    SwipeRefreshLayout swipeRefreshLayout;
    RestaurantAdapter adapter;
    List<Restaurant> restaurants = new ArrayList<>();
    String request_url = "https://localhost/api/all_fastfoods.php";
    String post_url= "https://localhost/api/add_note.php";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        swipeRefreshLayout=findViewById(R.id.swipe_layout);
        swipeRefreshLayout.setOnRefreshListener(this);

        recyclerView = findViewById(R.id.recycleViewContainer);

        layoutManager = new LinearLayoutManager(this);

        recyclerView.setLayoutManager(layoutManager);

        restaurants = new ArrayList<>();
        registerForContextMenu(recyclerView);
        getData();
        NukeSSLCerts.nuke();
    }
    private void getData() {
        swipeRefreshLayout.setRefreshing(true);
        sendRequest();
    }
    public void sendRequest(){

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, request_url, null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                restaurants.clear();
                for (int i = 0; i < response.length(); i++) {
                    Restaurant restaurant = new Restaurant();

                    try {
                        JSONObject jsonObject = response.getJSONObject(i);
                        restaurant.setId(jsonObject.getInt("restaurant_id"));
                        restaurant.setName(jsonObject.getString("restaurant_name"));
                        restaurant.setAddress(jsonObject.getString("restaurant_address"));
                        restaurant.setImage(jsonObject.getInt("restaurant_image_type"));
                        restaurant.setHasNote(jsonObject.getBoolean("restaurant_has_note"));
                        swipeRefreshLayout.setRefreshing(false);
                    } catch (JSONException e) {
                        swipeRefreshLayout.setRefreshing(false);
                        Log.i("Error",e.toString());
                        e.printStackTrace();
                    }
                    restaurants.add(restaurant);
                }
                mAdapter = new RestaurantAdapter(MainActivity.this, restaurants);
                recyclerView.setAdapter(mAdapter);
                swipeRefreshLayout.setRefreshing(false);

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.i("Volley Error:", String.valueOf(error));
            }
        });
        RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
        queue.add(jsonArrayRequest);
    }

    public boolean onContextItemSelected(MenuItem item) {
        final Restaurant restaurant= new Restaurant();
        if (item.getTitle().equals("Add Note")){
            AlertDialog.Builder notepad = new AlertDialog.Builder(MainActivity.this);
            LayoutInflater noteInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

            View notepadView = noteInflater.inflate(R.layout.notes,null,false);
            notepad.setView(notepadView);

            final AlertDialog notepadDialog = notepad.create();
            notepadDialog.getWindow().getAttributes().windowAnimations = R.style.customdialog;
            notepadDialog.show();

            final EditText notepadedit = notepadView.findViewById(R.id.notepad);
            final Button addnote = notepadView.findViewById(R.id.fab);

            notepadedit.requestFocus();
            addnote.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    JSONObject update = new JSONObject();
                    JSONObject postparams = new JSONObject();
                    try {
                        postparams.put("Content-Type", "application/json");
                        postparams.put("Accept", "application/json");
                        postparams.put("note_content",notepadedit.getText());
                        postparams.put("note_date_time",System.currentTimeMillis());
                        postparams.put("restaurant_id",restaurants.get(adapter.getPosition()).getId());
                        update.put("restaurant_has_note",true);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, post_url, postparams, new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Toast.makeText(getApplicationContext(), "SuccessFull", Toast.LENGTH_LONG).show();
                        }
                    }, new Response.ErrorListener() {
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            Log.i("PostLog", String.valueOf(error));
                        }
                    }

RecyclerView 适配器

public class RestaurantAdapter extends RecyclerView.Adapter<RestaurantAdapter.MyViewHolder> implements View.OnClickListener{

    private Context context;
    private List<Restaurant> restaurantList;
    private int position;

    public int getPosition() {return position;}

    public void setPosition(int position) {this.position = position; }

    public RestaurantAdapter(Context context,List <Restaurant> restaurantList){
        this.context = context;
        this.restaurantList = restaurantList;
    }

    @Override
    public void onClick(View view){
    }


    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener{

        public TextView FastFoodName;
        public TextView FastFoodAddress;
        ImageView icon,noteIcon;

        MyViewHolder(View itemView){
            super(itemView);
            icon = itemView.findViewById(R.id.type_ic);
            FastFoodName = itemView.findViewById(R.id.listview_name);
            FastFoodAddress = itemView.findViewById(R.id.listview_address);
            noteIcon = itemView.findViewById(R.id.note_icon);
            itemView.setOnCreateContextMenuListener(this);
        }
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
            menu.add(0, 1, 0, "Add Note");
            menu.add(0, 2, 1, "All Notes");
        }

    }

    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout,parent,false);
        return new MyViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                setPosition(holder.getAdapterPosition());
                return false;
            }
        });
        Restaurant restaurant = restaurantList.get(position);
        holder.FastFoodName.setText(restaurant.getName());
        holder.FastFoodAddress.setText(restaurant.getAddress());

        switch (restaurant.getImage()){
            case 1:
                holder.icon.setImageResource(R.drawable.phoneorderr);
                break;
            case 2:
                holder.icon.setImageResource(R.drawable.sitdownn);
                break;
            case 3:
                holder.icon.setImageResource(R.drawable.takeaway);
                break;
        }
        holder.noteIcon.setImageResource(R.drawable.notepadicon);
        if(restaurant.isHasNote()){
            holder.noteIcon.setVisibility(View.VISIBLE);
        }else {
            holder.noteIcon.setVisibility(View.INVISIBLE);
        }

    }

    @Override
    public int getItemCount() {
        return restaurantList.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
}

和我的模型类

public class Restaurant implements Serializable {
    private int id;
    private String name;
    private String address;
    private int type;
    private boolean hasNote = false;
    private int image;

    public Restaurant() {
    }

    public Restaurant(String name, String address,int type){
        this.name = name;
        this.address = address;
        this.type = type;
    }

    public Restaurant(int id, String name, String address,int type){
        this.id = id;
        this.name = name;
        this.address = address;
        this.type = type;
    }

    public Restaurant(int id,  String name, String address, int type,int image) {
        this.id = id;
        this.name = name;
        this.address = address;
        this.type = type;
        this.image = image;
    }
    public int getId() { return id;}

    public void  setId (int id) { this.id = id;}

    public String getName() {
        return name;
    }

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

    public boolean isHasNote(){
        return hasNote;
    }

    public void setHasNote(boolean hasNote){
        this.hasNote = hasNote;
    }

    public String getAddress() { return address;}

    public void setAddress(String address) { this.address = address;}

    public void setType(int type) {this.type = type;}

    public int getType() {return type;}

    public int getImage() {return image;}

    public void setImage(int image) {this.image = image;}

}

【问题讨论】:

  • 如果是Exception,千万不要忘记添加堆栈跟踪

标签: java android android-recyclerview nullpointerexception


【解决方案1】:

你还没有初始化adapter。使用前尝试初始化。

public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener{

    //remove this
    //RecyclerView.Adapter mAdapter;

    //User this everywhere
    RestaurantAdapter adapter;

    .....


    public void sendRequest() {
        ....

        adapter = new RestaurantAdapter(MainActivity.this, restaurants);
        recyclerView.setAdapter(adapter);
        ....

    }
}

【讨论】:

  • 试过了,没用。谢谢
  • 哪个不工作?
  • 您可能将positionposition 混合在一起。更改position以外的全局变量名称
  • 我刚刚将 holder.getAdapterPosition 更改为您告诉我的位置,我仍然在 logcat 中得到这个 ``` java.lang.NullPointerException: Attempt to invoke virtual method 'int com.test.fastfoodfinderclient.adapter .RestaurantAdapter.getPosition()' 在空对象引用 ```
  • 这意味着你还没有初始化adapter。删除 RecyclerView.Adapter mAdapter; 并在 Activity 中使用 adapter;
猜你喜欢
  • 2017-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多