Reputation: 9
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)
Upvotes: 0
Views: 157
Reputation: 1602
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());
}
}
}
Upvotes: 2