如何在RecyclerView上设置onClickListener?

时间:2016-10-08 14:03:46

标签: java android android-recyclerview android-cardview cardview

我制作了一张卡片视图,可以从互联网上加载数据并进行显示。我有一个JSONParser类来解析json数据。然后,我将数据存储在ListItem类型的arraylist中。但是,我无法使用onCliclListener。

这是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;
    }
}

这是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) {

    }
}

这是我的适配器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());
            }
        }
    }
}

显示空指针异常。

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

1 个答案:

答案 0 :(得分:2)

你应该初始化JsonParser

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

但是你无法立即调用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);
}
} 

MainActivity.java

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

这应该有用,如果我错过了什么让我知道。

就像NoobGeek说你需要将setOnclickLiestenr设置为你的观点,如果你没有设置任何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());
        }
    }
}