简体   繁体   中英

How to set onClickListener on RecyclerView?

I have made a card view which loads data from the internet and displays it. I have a JSONParser class to parse the json data. Then, I store the data in an arraylist of ListItem type. But, I am not able to use the onCliclListener.

Here is the JSONParser.java File:

public class JSONParser extends AsyncTask<Void,Void,Boolean>{

    Context c;
    String jsonData;
    RecyclerView rv;
    private final Context context=null;

    ProgressDialog pd;
    ArrayList<String> names=new ArrayList<>();
    ArrayList<String> ages=new ArrayList<>();
    ArrayList<String> addresses=new ArrayList<>();
    ArrayList<String> bgs=new ArrayList<>();

    List<ListItem> data = new ArrayList<>();


    public JSONParser(Context c, String jsonData, RecyclerView rv) {
        this.c = c;
        this.jsonData = jsonData;
        this.rv = rv;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pd=new ProgressDialog(c);
        pd.setTitle("Parse JSON");
        pd.setMessage("Parsing...Please wait");
        pd.show();
    }

    @Override
    protected Boolean doInBackground(Void... voids) {
        return parse();
    }

    @Override
    protected void onPostExecute(Boolean isParsed) {
        super.onPostExecute(isParsed);

        pd.dismiss();
        if(isParsed)
        {
            //BIND
            MyAdapter adapter=new MyAdapter(c,names,ages,addresses,bgs);
            rv.setAdapter(adapter);
        }else
        {
            Toast.makeText(c, "Unable To Parse,Check Your Log output", Toast.LENGTH_SHORT).show();
        }
    }

    private Boolean parse()
    {
        try
        {
            JSONArray ja=new JSONArray(jsonData);
            JSONObject jo;

            names.clear();
            ages.clear();
            addresses.clear();
            bgs.clear();

            for (int i=0;i<ja.length();i++)
            {
                jo=ja.getJSONObject(i);

                List<ListItem> ldata = new ArrayList<>();
                ListItem item = new ListItem();

                String name=jo.getString("name");
                String age=jo.getString("mob");
                String address=jo.getString("add");
                String bg=jo.getString("bg");

                names.add(name);
                ages.add(age);
                addresses.add(address);
                bgs.add(bg);

                item.setName(name);
                item.setAge(age);
                item.setAddress(address);
                item.setBg(bg);

                ldata.add(item);

                setData(ldata);
            }

            return true;

        } catch (JSONException e) {
            e.printStackTrace();
            return false;
        }
    }

    public void setData(List<ListItem> data) {
        this.data = data;
    }

    public List<ListItem> getData() {
        return data;
    }
}

Here is the MainActivity.java file:

public class MainActivity extends AppCompatActivity implements MyAdapter.ItemClickCallback {

    String jsonURL="http://projectred.in/phploginwebservice/index.php?tag=reqjson&cur=JAIPUR";
    RecyclerView rv;
    ArrayList listData;
    JSONParser jsonParser;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        listData = (ArrayList) jsonParser.getData();

        rv = (RecyclerView) findViewById(R.id.rv);
        rv.setLayoutManager(new LinearLayoutManager(this));

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new JSONDownloader(MainActivity.this,jsonURL, rv).execute();
            }
        });
    }

    @Override
    public void onItemClick(int p) {
        ListItem item = (ListItem) listData.get(p);

        Toast.makeText(MainActivity.this, "Title: " + item.getName() + "\nSubtitle :" + item.getAge()+ "\nAddress :" + item.getAddress(), Toast.LENGTH_LONG).show();
    }

    @Override
    public void onSecondaryIconClick(int p) {

    }
}

This is my adapter java code:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    Context c;
    ArrayList<String> names;
    ArrayList<String> ages;
    ArrayList<String> addresses;
    ArrayList<String> bgs;


    private ItemClickCallback itemClickCallback;

    public MyAdapter(Context c, ArrayList<String> names, ArrayList<String> ages, ArrayList<String> addresses, ArrayList<String> bgs) {
        this.c = c;
        this.names = names;
        this.ages = ages;
        this.addresses = addresses;
        this.bgs = bgs;
    }

    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(c).inflate(R.layout.model, parent, false);
        return new MyViewHolder(v);
    }

    public interface ItemClickCallback {
        void onItemClick(int p);

        void onSecondaryIconClick(int p);
    }

    public void setItemClickCallback(final ItemClickCallback itemClickCallback) {
        this.itemClickCallback = itemClickCallback;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        //BIND
        holder.nameTxt.setText(names.get(position));
        holder.ageTxt.setText(ages.get(position));
        holder.addTxt.setText(addresses.get(position));
        if (bgs.get(position).toString().equals("AP")) {
            holder.bg.setImageResource(R.drawable.apr);
        }
        if (bgs.get(position).toString().equals("AN")) {
            holder.bg.setImageResource(R.drawable.anr);
        }
        if (bgs.get(position).toString().equals("BP")) {
            holder.bg.setImageResource(R.drawable.bpr);
        }
        if (bgs.get(position).toString().equals("BN")) {
            holder.bg.setImageResource(R.drawable.bnr);
        }
        if (bgs.get(position).toString().equals("ABP")) {
            holder.bg.setImageResource(R.drawable.abpr);
        }
        if (bgs.get(position).toString().equals("ABN")) {
            holder.bg.setImageResource(R.drawable.abnr);
        }
        if (bgs.get(position).toString().equals("OP")) {
            holder.bg.setImageResource(R.drawable.opr);
        }
        if (bgs.get(position).toString().equals("ON")) {
            holder.bg.setImageResource(R.drawable.onr);
        }

    }

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


    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView nameTxt, ageTxt, addTxt;
        ImageView bg;

        public MyViewHolder(View itemView) {
            super(itemView);

            nameTxt = (TextView) itemView.findViewById(R.id.textView101);
            ageTxt = (TextView) itemView.findViewById(R.id.textView887);
            addTxt = (TextView) itemView.findViewById(R.id.textView77);
            bg = (ImageView) itemView.findViewById(R.id.imageView83);
        }


        @Override
        public void onClick(View view) {
            if (view.getId() == R.id.cont_item_root) {
                itemClickCallback.onItemClick(getAdapterPosition());
            } else {
                itemClickCallback.onSecondaryIconClick(getAdapterPosition());
            }
        }
    }
}

It is showing a null pointer exception.

This is my LogCat:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.List com.tutorials.hp.jsonrecyclerview.m_JSON.JSONParser.getData()' on a null object reference
                                                                                       at com.tutorials.hp.jsonrecyclerview.MainActivity$override.onCreate(MainActivity.java:32)
                                                                                       at com.tutorials.hp.jsonrecyclerview.MainActivity$override.access$dispatch(MainActivity.java)
                                                                                       at com.tutorials.hp.jsonrecyclerview.MainActivity.onCreate(MainActivity.java:0)
                                                                                       at android.app.Activity.performCreate(Activity.java:6259)
                                                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
                                                                                       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
                                                                                       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490) 
                                                                                       at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4098) 
                                                                                       at android.app.ActivityThread.-wrap15(ActivityThread.java) 
                                                                                       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1360) 
                                                                                       at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                       at android.os.Looper.loop(Looper.java:148) 
                                                                                       at android.app.ActivityThread.main(ActivityThread.java:5443) 
                                                                                       at java.lang.reflect.Method.invoke(Native Method) 
                                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
                                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 

You should initialize JsonParser

jsonParser = new JsonParser(c, jsonData, rv);
listData = (ArrayList) jsonParser.getData();

However you can't call jsonParser.getData right away you need to wait until the asynctask finishes.

public class JSONParser {
ProgressDialog pd;
ArrayList<String> names=new ArrayList<>();
ArrayList<String> ages=new ArrayList<>();
ArrayList<String> addresses=new ArrayList<>();
ArrayList<String> bgs=new ArrayList<>();

ArrayList<ListItem> data = new ArrayList<>();

public JSONParser(final Context c, final String jsonData, final RecyclerView rv, final OnFinishListener onFinishListener) {

    new AsyncTask<Void, Void, Boolean>() {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd=new ProgressDialog(c);
            pd.setTitle("Parse JSON");
            pd.setMessage("Parsing...Please wait");
            pd.show();
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            try {
                JSONArray ja=new JSONArray(jsonData);
                JSONObject jo;

                names.clear();
                ages.clear();
                addresses.clear();
                bgs.clear();

                for (int i=0;i<ja.length();i++) {
                    jo=ja.getJSONObject(i);

                    ArrayList<ListItem> ldata = new ArrayList<>();
                    ListItem item = new ListItem();

                    String name=jo.getString("name");
                    String age=jo.getString("mob");
                    String address=jo.getString("add");
                    String bg=jo.getString("bg");

                    names.add(name);
                    ages.add(age);
                    addresses.add(address);
                    bgs.add(bg);

                    item.setName(name);
                    item.setAge(age);
                    item.setAddress(address);
                    item.setBg(bg);

                    ldata.add(item);

                    setData(ldata);
                }

                return true;

            } catch (JSONException e) {
                e.printStackTrace();
                return false;
            }
        }

        @Override
        protected void onPostExecute(Boolean isParsed) {
            super.onPostExecute(isParsed);

            pd.dismiss();
            if(isParsed) {
                //BIND
                MyAdapter adapter=new MyAdapter(c,names,ages,addresses,bgs);
                rv.setAdapter(adapter);
                onFinishListener.finished(data);
            }else {
                Toast.makeText(c, "Unable To Parse,Check Your Log output", Toast.LENGTH_SHORT).show();
            }
        }
    }.execute();
}




public void setData(ArrayList<ListItem> data) {
    this.data = data;
}

public ArrayList<ListItem> getData() {
    return data;
}

public interface OnFinishListener{
    void finished(ArrayList<ListItem> data);
}
} 

In your MainActivity.java

jsonParser = new JsonParser(c, jsonData, rv,new JSONParser.OnFinishListener() {
        @Override
        public void finished(ArrayList<ListItem> data) {
            listData = data;
        }
    });

This should work, if i missed something let me know.

Just like NoobGeek said you need to setOnclickLiestenr to your views, if you don't set any onclicklister you wont be able to get listen for clicks for example,

  //nameTxt.setOnClickListener(this);
  //ageTxt.setOnClickListener(this);
  //addTxt.setOnClickListener(this);

  //i don't see the cont_item_root anywhere 

  //bg = (ImageView) itemView.findViewById(R.id.imageView83);
  bg.setOnClickListener(this);

  ...
  @Override
    public void onClick(View view) {
        if (view.getId() == R.id.imageView83) { //maybe this?
            itemClickCallback.onItemClick(getAdapterPosition());
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM