简体   繁体   English

如何在RecyclerView上设置onClickListener?

[英]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. 我有一个JSONParser类来解析json数据。 Then, I store the data in an arraylist of ListItem type. 然后,我将数据存储在ListItem类型的arraylist中。 But, I am not able to use the onCliclListener. 但是,我无法使用onCliclListener。

Here is the JSONParser.java File: 这是JSONParser.java文件:

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: 这是MainActivity.java文件:

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: 这是我的适配器Java代码:

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: 这是我的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

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. 但是,您不能立即调用jsonParser.getData ,而需要等到asynctask完成。

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 在您的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, 就像NoobGeek所说的那样,您需要将onsetLiestenr设置为您的视图,例如,如果您未设置任何onclicklister,则您将无法监听点击,

  //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());
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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