I'm making a list of links and for that I have made a custom adapter, but the list is not ready when the adapter starts so I get the following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
this is because when the adapter is started the list is empty, and just moments after the list is filled but it's too late here is my code:
UPDATE: the code has been changed so now I du not get the error but it doesn't run getView in the adapter:
public class Controller extends Activity {
private String TAG = Controller.class.getSimpleName();
private String http;
CustomAdapter adapter;
public Controller con = null;
private ListView lv;
private static String url;
ArrayList<Selfservice> linkList = new ArrayList<Selfservice>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
con = this;
http = this.getString(R.string.http);
url = this.getString(R.string.path1);
new GetLinks().execute();
lv = (ListView)findViewById(R.id.list);
//Resources res = getResources();
//adapter = new CustomAdapter(con, linkList, res);
//lv.setAdapter(adapter);
}
private class GetLinks extends AsyncTask<Void, Void, List<Selfservice>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected List<Selfservice> doInBackground(Void... arg0) {
Document doc;
Elements links;
List<Selfservice> returnList = null;
try {
doc = Jsoup.connect(url).timeout(0).get();
links = doc.getElementsByClass("processlink");
returnList = ParseHTML(links);
} catch (IOException e) {
e.printStackTrace();
}
return returnList;
}
#Override
protected void onPostExecute(final List<Selfservice> result) {
super.onPostExecute(result);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
//getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setTitle("");
toolbar.setSubtitle("");
Resources res = getResources();
Log.e(TAG, linkList.toString());
linkList = (ArrayList<Selfservice>) result;
adapter = new CustomAdapter(con, result, res);
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
});
}
}
and my adapter:
public class CustomAdapter extends BaseAdapter implements OnClickListener {
private String TAG = CustomAdapter.class.getSimpleName();
Context context;
List<Selfservice> data;
private Activity activity;
public Resources res;
Selfservice self = null;
private static LayoutInflater inflater;
int layoutResourceId = 0;
public CustomAdapter(Activity act, List<Selfservice> dataList, Resources resources) {
res = resources;
activity = act;
data = dataList;
}
private class Holder {
TextView title;
TextView link;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int pos) {
return pos;
}
#Override
public long getItemId(int pos) {
return pos;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = convertView;
Holder holder;
if(rowView == null){
rowView = inflater.inflate(R.layout.list_item, null);
holder = new Holder();
holder.title = (TextView) rowView.findViewById(R.id.title);
holder.link = (TextView) rowView.findViewById(R.id.link);
rowView.setTag(holder);
}else{
holder = (Holder)rowView.getTag();
}
if(data.size()<=0){
holder.title.setText("did not work");
}else{
self = null;
self = (Selfservice) data.get(position);
holder.title.setText(self.getTitle());
holder.link.setText(self.getLink());
Log.i(TAG, "adapter");
rowView.setOnClickListener(new OnItemClickListener(position));
}
return rowView;
}
#Override
public void onClick(View v){
Log.v("CustomAdapter", "row clicked");
}
private class OnItemClickListener implements OnClickListener{
private int mPos;
OnItemClickListener(int position){
mPos = position;
}
#Override
public void onClick(View arg0){
Controller con = (Controller)activity;
con.onItemClick(mPos);
}
}
}
So How do I get the adapter to wait to the list is full?
firstly use ArrayAdapter<Selfservice> instead of BaseAdapter
use constructor
public CustomAdapter(Context context, int resource, List<Selfservice> objects) {
super(context, resource, objects);
data = objects;
}
then override only two methods
public int getCount()
public View getView(int position, View convertView, ViewGroup parent)
then return list.size() in getCount()
in getView() method
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_item, null);
}
in doInBackground() method in the try block
instead of linkList = ParseHTML(links);
do linkList.addAll(ParseHTML(links));
and in onPostExcecute() method
adapter.notifyDatasetChanged(); in the ui thread
You can create the adapter in the onPostExecute;
Change the Async Task to this:
private class GetLinks extends AsyncTask<Void, Void, List<Selfservice>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
Document doc;
Elements links;
List<Selfservice> returnList
try {
doc = Jsoup.connect(url).timeout(10000).get();
links = doc.getElementsByClass("processlink");
returnList = ParseHTML(links);
} catch (IOException e) {
e.printStackTrace();
}
return returnList;
}
#Override
protected void onPostExecute(List<Selfservice> result) {
super.onPostExecute(result);
runOnUiThread(new Runnable() {
#Override
public void run() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
//getSupportActionBar().setDisplayShowTitleEnabled(false);
toolbar.setTitle("");
toolbar.setSubtitle("");
linkList = result
adapter = new CustomAdapter(con, result, res);
lv.setAdapter(adapter);
}
});
}
This way you will only create the adapter when your list is ready.
Edit:
You are not creating the variable context inside your adapter. Change your constructor to this:
public CustomAdapter(Context context, Activity act, List<Selfservice> dataList, Resources resources) {
res = resources;
activity = act;
data = dataList;
this.context = context;
}
And you will stop seeing the NullPointerExecption
Related
So I have an activity with a listview inside of it and when I click a delete button I want to remove the object from the list. I already know how to find which object I want to remove and remove it from the list that populates my array adapter but I am not sure what i need to do to call the .notifyDataSetChanged() routine which Is what I believe I need to do. Any help would be much appreciated.
My activity code
public class MealActivity2 extends AppCompatActivity {
private ListView lv;
public static ArrayList<Model> modelArrayList;
private CustomAdapter customAdapter;
private Button btnnext;
private String[] fruitlist = new String[]{"Apples", "Oranges", "Potatoes", "Tomatoes","Grapes"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_meal2);
Integer numFoodItems = ((Globals) getApplication()).getLength();
lv = (ListView) findViewById(R.id.lv);
btnnext = (Button) findViewById(R.id.next);
modelArrayList = getModel(numFoodItems);
customAdapter = new CustomAdapter(this);
lv.setAdapter(customAdapter);
btnnext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MealActivity2.this,NextActivity.class);
startActivity(intent);
}
});
}
// this builds the array list of model opbjects that will be used by the adapter to populate
// the list view dynamically
private ArrayList<Model> getModel(Integer length){
ArrayList<Model> list = new ArrayList<>();
for(int i = 0; i < length; i++){
FoodDetailsPost food = ((Globals) getApplication()).getFoodList().get(i);
Model model = new Model();
model.setNumber(((Globals) getApplication()).getServing(i));
model.setFruit(food.getDescription());
list.add(model);
}
return list;
}
}
and here is my custom adapter code if you look near the end at the last comment that is where i need to notify my activity that I have changed the contents of the list and should update the displaying items
public class CustomAdapter extends BaseAdapter {
private Context context;
private adapterGlobalAccess g = new adapterGlobalAccess();
private CustomAdapter customAdapter;
public CustomAdapter(Context context) {
this.context = context;
}
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getCount() {
return MealActivity2.modelArrayList.size();
}
#Override
public Object getItem(int position) {
return MealActivity2.modelArrayList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.lv_item, null, true);
holder.tvFruit = (TextView) convertView.findViewById(R.id.animal);
holder.tvnumber = (TextView) convertView.findViewById(R.id.number);
holder.btn_edit = (Button) convertView.findViewById(R.id.plus);
holder.btn_minus = (Button) convertView.findViewById(R.id.minus);
convertView.setTag(holder);
}else {
// the getTag returns the viewHolder object set as a tag to the view
holder = (ViewHolder)convertView.getTag();
}
holder.tvFruit.setText(MealActivity2.modelArrayList.get(position).getFruit());
holder.tvnumber.setText(String.valueOf(MealActivity2.modelArrayList.get(position).getNumber()));
holder.btn_edit.setTag(R.integer.btn_plus_view, convertView);
holder.btn_edit.setTag(R.integer.btn_plus_pos, position);
holder.btn_edit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View) holder.btn_edit.getTag(R.integer.btn_plus_view);
TextView tv = (TextView) tempview.findViewById(R.id.number);
Integer pos = (Integer) holder.btn_edit.getTag(R.integer.btn_plus_pos);
Double number = Double.parseDouble(tv.getText().toString()) + 1;
tv.setText(String.valueOf(number));
MealActivity2.modelArrayList.get(pos).setNumber(number);
g.setServing(pos, number);
}
});
holder.btn_minus.setTag(R.integer.btn_minus_view, convertView);
holder.btn_minus.setTag(R.integer.btn_minus_pos, position);
holder.btn_minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View) holder.btn_minus.getTag(R.integer.btn_minus_view);
TextView tv = (TextView) tempview.findViewById(R.id.number);
Integer pos = (Integer) holder.btn_minus.getTag(R.integer.btn_minus_pos);
((Globals) context.getApplicationContext()).remove(pos);
MealActivity2.modelArrayList.remove(pos);
// i need to do .notifyDataSetChanged() here but im not sure how
}
});
return convertView;
}
You can just use a interface to solve the problem
CustomAdapter
public class CustomAdapter extends BaseAdapter {
...
private CustomAdapterListener listener;
interface CustomAdapterListener{
void itemClick();
}
public CustomAdapter(Context context, CustomAdapterListener listener) {
this.context = context;
this.listener = listener;
}
MainActivity2
public class MealActivity2 extends AppCompatActivity implements CustomAdapterListener {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_meal2);
...
customAdapter = new CustomAdapter(this, this);
}
#Override
public void itemClick() {
// you can do .notifyDataSetChanged() here
}
after that you can use listener to callback to Activity and do anything you want
CustomAdapter
#Override
public void onClick(View v) {
listener.itemClick();
// i need to do .notifyDataSetChanged() here but im not sure how
}
[EDIT] I'm new to android development, so please bear with me. I have two java classes named Join Game, extends to AppCompatActivity and HintList,extends to ArrayAdapter<>. This is connected to a database. So maybe its one of the factors?
For the layout of join game, I have a listview
and for the layout of hintlist I have three textview.
The code goes this way
JoinGame
public class JoinGame extends AppCompatActivity {
ListView list;
String[] itemdescription = {};
String[] itemhints = {};
String[] itemlocasyon = {};
ProgressDialog progress;
View view;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_joingame);
Button schan = (Button)findViewById(R.id.tarascan);
schan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(JoinGame.this,ScanActivity.class);
startActivity(intent);
}
});
}
#Override
protected void onStart() {
super.onStart();
progress = new ProgressDialog(this);
progress.setMessage("Connecting...");
progress.setCancelable(false);
progress.show();
RequestFactory.joingameitems(JoinGame.this, RequestFactory.user_id, new RequestCallback<JSONArray>() {
#Override
public void onSuccess(final JSONArray response) {
runOnUiThread(new Runnable() {
#Override
public void run() {
RequestFactory.response = response;
itemdescription = new String[response.length()];
itemhints = new String[response.length()];
itemlocasyon = new String[response.length()];
for (int hl = 0; hl < response.length(); hl++){
try{
itemdescription[hl] = ((String)(response.getJSONObject(hl)).get("description"));
itemhints[hl] = ((String)(response.getJSONObject(hl)).get("hint"));
itemlocasyon[hl] = ((String)(response.getJSONObject(hl)).get("location"));
} catch (JSONException e) {
e.printStackTrace();
}
} ////////// below this is the adapter
final HintList hladapt = new HintList(JoinGame.this,itemdescription,itemlocasyon,itemhints);
list = (ListView)findViewById(R.id.item_hints_and_location);
list.setAdapter(hladapt);
progress.dismiss();
}
});
}
#Override
public void onFailed(final String message) {
runOnUiThread(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(JoinGame.this, message, Toast.LENGTH_LONG).show();
progress.dismiss();
}
});
}
});
}
});
}
HintList
public class HintList extends ArrayAdapter<String> {
private final Activity context;
private String[] itemDesc = {};
private String[] itemHints = {};
private String[] itemLocation = {};
public HintList(Activity context,String[] itemDesc,String[] itemhints,String[] itemlocation) {
super(context,R.layout.hints_list);
this.context = context;
this.itemDesc = itemDesc;
itemHints = itemhints;
itemLocation = itemlocation;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.hints_list, null, true);
TextView itemDesc2 = (TextView)rowView.findViewById(R.id.itemdescription);
TextView itemHint = (TextView)rowView.findViewById(R.id.itemhint);
TextView itemLocation2 = (TextView)rowView.findViewById(R.id.itemlocation);
itemDesc2.setText(itemDesc[position]);
itemHint.setText(itemHints[position]);
itemLocation2.setText(itemLocation[position]);
return rowView;
}
}
I actually retrieved the data (here)
E/DB: [{"description":"chinese garter","location":"near Tricycle station","hint":"garter plus chinese"},{"description":"isang pinoy game","location":"near ....","hint":"may salitang baka"},{"description":"\"tinik\"","location":"below...","hint":"may salitang tinik"},{"description":"aka Tinubigan","location":"at the back...","hint":"katunog ng pintero"},{"description":"\"knock down the can\"","location":"near...","hint":"gumagamit ng lata"}]
but it doesnt display on my listview
I dont know anymore what I should do.
I actually tried making this (I added view)
final HintList hladapt = new HintList(JoinGame.this,itemdescription,itemlocasyon,itemhints);
list = (ListView)view.findViewById(R.id.item_hints_and_location);
list.setAdapter(hladapt);
progress.dismiss();
but it will only returns an error of java.lang.NullPointerException: Attempt to invoke virtual method
Change this:
View rowView = inflater.inflate(R.layout.hints_list, null, true);
to:
View rowView = inflater.inflate(R.layout.hints_list, parent, false);
Modify your getView() method to:
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.hints_list, parent, false);
TextView itemDesc2 = (TextView)rowView.findViewById(R.id.itemdescription);
TextView itemHint = (TextView)rowView.findViewById(R.id.itemhint);
TextView itemLocation2 = (TextView)rowView.findViewById(R.id.itemlocation);
itemDesc2.setText(itemDesc[position]);
itemHint.setText(itemHints[position]);
itemLocation2.setText(itemLocation[position]);
return rowView;
}
try adding getCount
#Override
public int getCount() {
return itemHints.length;
}
Try to change your code to this
public class HintList extends ArrayAdapter<String> {
private final Activity context;
private String[] itemDesc = {};
private String[] itemHints = {};
private String[] itemLocation = {};
private LayoutInflater inflater=null;
public HintList(Activity context,String[] itemDesc,String[] itemhints,String[] itemlocation) {
super(context,R.layout.hints_list);
this.context = context;
this.itemDesc = itemDesc;
itemHints = itemhints;
itemLocation = itemlocation;
inflater = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return itemHints.length;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view==null){
view=inflater.inflate(R.layout.hints_list, null, true);
holder = new ViewHolder(view);
view.setTag(holder);
}else {
holder = (ViewHolder) view.getTag();
}
holder.itemDesc2.setText(itemDesc[position]);
holder.itemHint.setText(itemHints[position]);
holder.itemLocation2.setText(itemLocation[position]);
return view;
}
static class ViewHolder{
TextView itemDesc2,itemHint,itemLocation2;
ViewHolder(View view) {
itemDesc2 = (TextView)view.findViewById(R.id.itemdescription);
itemHint = (TextView)view.findViewById(R.id.itemhint);
itemLocation2 = (TextView)view.findViewById(R.id.itemlocation);
}
}
}
My suggestions is create a bean class (DetailsBean), used for setter and getter method, and also the ArrayList (details1).
List<DetailsBean> details1 = new ArrayList<>(); // declare this as global
Then add the bean to below code
public void run() {
RequestFactory.response = response;
itemdescription = new String[response.length()];
itemhints = new String[response.length()];
itemlocasyon = new String[response.length()];
for (int hl = 0; hl < response.length(); hl++){
try{
itemdescription[hl] = ((String)(response.getJSONObject(hl)).get("description"));
itemhints[hl] = ((String)(response.getJSONObject(hl)).get("hint"));
itemlocasyon[hl] = ((String)(response.getJSONObject(hl)).get("location"));
// here the bean
DetailsBean dbean = new DetailsBean(itemDescription, itemhints, itemlocasyon);
details1.add(dbean); // add all the data to details1 ArrayList
HintList hladapt = new HintList(getActivity(), details1);
(ListView)findViewById(R.id.item_hints_and_location);
list.setAdapter(hladapt);
} catch (JSONException e) {
e.printStackTrace();
}
}
Your DetailsBean should looked like this
public class DetailsBean {
private String itemDescription="";
private String itemhints="";
private String itemlocasyon ="";
public DetailsBean(String description, String hints, String itemlocasyon) {
this.itemDescription=description;
.....
}
public void setItemDescription(String itemDescription) {
this.itemDescription = itemDesription;
}
public String getItemDescription() {
return itemDescription;
}
....
}
Then your HintList
public class HintList extends BaseAdapter{
Activity context;
List<DetailsBean> details;
private LayoutInflater mInflater;
public CustomBaseAdapter(Activity context,List<DetailsBean> details) {
this.context = context;
this.details = details;
}
........
}
Add these Override methods in your adapter
#Override
public int getCount() {
return itemHints.length;
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
I have a database with a column named "noteName". What I want is to populate the listView with mySQLiteDatabase. I use a display adapter to help the process.
But the problems come with Null Pointer Exception. I have to try to figure it out what cause the NPO but I still didn't get it.
Please help me, I have just been stuck here for two days.
NB. This my code for MainActivity.java (where the listview will show)
public class MainActivity extends ActionBarActivity {
SQLiteDatabase db;
DatabaseHelper dBHelper = new DatabaseHelper(this);
private ListView list;
private ArrayList<String> NoteName = new ArrayList<String>();
private static final String TABLE_NOTES_NAME = "Notes";
private ArrayList<Contact> noteData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.pink_icon).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent registerIntent = new Intent(MainActivity.this, AddNote.class);
MainActivity.this.startActivity(registerIntent);
}
});
display();
}
public void display() {
db = dBHelper.getReadableDatabase();
Cursor mCursor = db.rawQuery("SELECT NoteName FROM " + TABLE_NOTES_NAME , null);
ListView list = (ListView)findViewById(android.R.id.list);
NoteName.clear();
if (mCursor.moveToFirst()) {
do {
NoteName.add(mCursor.getString(mCursor.getColumnIndex(dBHelper.TOL_NOTENAME)));
} while (mCursor.moveToNext());
}
DisplayAdapterTrans disadptr = new DisplayAdapterTrans(MainActivity.this, NoteName);
list.setAdapter(disadptr); // Here the console says have a null pointer exception
mCursor.close();
}
}
This one for my DisplayAdapter
public class DisplayAdapterTrans extends BaseAdapter {
private Context mContext;
private ArrayList<String> NoteName;
public DisplayAdapterTrans(Context c, ArrayList<String> noteName) {
this.mContext = c;
this.NoteName = noteName;
}
public int getCount() {
// TODO Auto-generated method stub
return NoteName.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.notename, null);
mHolder = new Holder();
mHolder.noteName= (TextView) child.findViewById(R.id.notenameTxt);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.noteName.setText(NoteName.get(pos));
return child;
}
public class Holder {
TextView noteName;
}
}
I am using recyclerview adapter for my fragment, but my list is not getting shown as the onCreateViewHolder() and onBindViewHolder() are not getting called. Please let me know what is the issue with my code?
MyFragment code :
public class MyFragment extends Fragment {
private Integer mCurrentPage = 1;
private Integer mChosenOrder=0;
ArrayList<MyParcelableObject> mMyList;
private RecyclerView mRecyclerView;
MyAdapter mMyAdapter;
public MyFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mRecyclerView= (RecyclerView) rootView.findViewById(R.id.gridview_movies);
mRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
Log.e(LOG_TAG, "In oncreateview");
if (savedInstanceState != null && savedInstanceState.getParcelableArrayList(ConstantUtil.My_LIST_KEY) != null) {
mMyList = savedInstanceState.getParcelableArrayList(ConstantUtil.My_LIST_KEY);
} else {
mMyList = new ArrayList<>();
}
new MyTask(getActivity(), mMyList,mMyAdapter).execute(mChosenOrder);
mMyAdapter = new MyAdapter(getActivity(),mMyList);
Log.e(LOG_TAG,"Adapter size oncreateview"+mMyAdapter.getItemCount());
mRecyclerView.setAdapter(mMyAdapter);
Log.e(LOG_TAG, "In oncreateview after attaching adapter");
return rootView;
}
#Override
public void onStart() {
super.onStart();
populate();
}
private void populate() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (prefs != null) {
String order = prefs.getString(getString(R.string.sorting_order), getString(R.string.pref_defaultValue));
int order_value = Integer.parseInt(order);
if (order_value >= 0) {
Resources resources = getResources();
mChosenOrder = Integer.parseInt(resources.getStringArray(R.array.pref_sorting_values)[order_value]);
} else {
mChosenOrder = order_value;
}
} else {
mChosenOrder = Integer.parseInt(getString(R.string.pref_defaultValue));
}
new MyTask(getActivity(),mMyList,mMyAdapter).execute(mChosenOrder);
Log.e(LOG_TAG,"populate Adapter size "+mMyAdapter.getItemCount());
mRecyclerView.setAdapter(mMyAdapter);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(ConstantUtil.My_LIST_KEY, mMyList);
}
}
Async Task code
public class MyTask extends AsyncTask<Integer, Void, MyParcelableObject[]> {
private Context context;
private List<MyParcelableObject> mMyParcelableObjects;
private RecyclerView recyclerView;
MyAdapter myAdapter;
public MyTask(Context context, List<MyParcelableObject> myParcelableObjects,MyAdapter myAdapter) {
this.context = context;
mMyParcelableObjects = myParcelableObjects;
this.myAdapter = myAdapter;
//this.imageAdapter = imageAdapter;
this.recyclerView = recyclerView;
}
#Override
protected MyParcelableObject[] doInBackground(Integer... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String myStr[] = null;
// Will contain the raw JSON response as a string.
String myStrJsonStr = null;
Uri buildUri = null;
MyParcelableObject[] myParcelableObjects = null;
//try {
// Context context = getApplicationContext();
ArrayList<MyParcelableObject> myParcelableObjectArrayList = null;
String[] sortOrder = context.getResources().getStringArray(R.array.pref_sorting_values);
int sort = Integer.parseInt(sortOrder[0]);
myParcelableObjectArrayList = getJsonFromUri(params[0]); //correctly gets the json array
if (myParcelableObjectArrayList != null) {
myParcelableObjects = myParcelableObjectArrayList.toArray(new MyParcelableObject[myParcelableObjectArrayList.size()]);
return myParcelableObjects;
return null;
}
/**
* #param results
*/
#Override
protected void onPostExecute(MyParcelableObject[] results) {
Log.e(LOG_TAG, "In onPostExecute");
if (results != null) {
mMyParcelableObjects = Arrays.asList(results);
myAdapter = new MyAdapter(context,mMyParcelableObjects);
Log.e(LOG_TAG,"adapter size"+myAdapter.getItemCount());
myAdapter.notifyDataSetChanged();
}
}
Adapter code
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
List<MyParcelableObject> mParcelableObjects;
ViewHolder mViewHolder;
Context mContext;
public MyAdapter(Context context, List<MyParcelableObject> parcelableObjects) {
mParcelableObjects = parcelableObjects;
mContext=context;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public ViewHolder(View view) {
super(view);
mImageView = (ImageView) view.findViewById(R.id.movie_content_imageview);
}
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.e("LOG_TAG","in on onCreateViewHolder");
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.content_main, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
Log.e("LOG_TAG","in on onBindViewHolder");
String myPoster = null;
MyParcelableObject myParcelableObject = mParcelableObjects.get(position);
if (myParcelableObject.poster_path != null) {
myPoster = myParcelableObject.poster_path.replaceAll("/", "");
}
Uri uri = Uri.parse(ConstantUtil.POSTER_URL).buildUpon().
appendPath(ConstantUtil.W342_SIZE).
appendPath(myPoster).build();
Picasso.with(mContext).load(uri).placeholder(R.drawable.resource_notfound).error(R.drawable.resource_notfound).into(mViewHolder.mImageView);
}
#Override
public int getItemCount() {
return mParcelableObjects.size();
}
}
You are not getting value because your list is empty.
replace this
new MyTask(getActivity(), mMyList,mMyAdapter).execute(mChosenOrder);
to this
mMyList = new MyTask(getActivity(), mMyList,mMyAdapter).execute(mChosenOrder).get();
i have problem with listview... i'm trying to add OnClickListener but in still doesn't work. I want to display another activity after click. Can somebody help me? I know that there are many of example, but it's doesn't work for my appl or i don't know how to use it in my example...
This is my LocationAdapter class:
public class LocationAdapter extends ArrayAdapter<LocationModel> {
int resource;
String response;
Context context;
private LayoutInflater mInflater;
public LocationAdapter(Context context, int resource, List<LocationModel> objects) {
super(context, resource, objects);
this.resource = resource;
mInflater = LayoutInflater.from(context);
}
static class ViewHolder {
TextView titleGameName;
TextView distanceGame;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
//Get the current location object
LocationModel lm = (LocationModel) getItem(position);
//Inflate the view
if(convertView==null)
{
convertView = mInflater.inflate(R.layout.item, null);
holder = new ViewHolder();
holder.titleGameName = (TextView) convertView
.findViewById(R.id.it_location_title);
holder.distanceGame = (TextView) convertView
.findViewById(R.id.it_location_distance);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.titleGameName.setText(lm.getGameName());
holder.distanceGame.setText(lm.getGameDistance()+" km");
return convertView;
}
}
This is my mainListView class:
public class SelectGameActivity extends Activity {
LocationManager lm;
GeoPoint userLocation;
ArrayList<LocationModel> locationArray = null;
LocationAdapter locationAdapter;
LocationList list;
ListView lv;
TextView loadingText;
TextView sprawdz;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.selectgame);
lv = (ListView) findViewById(R.id.list_nearme);
locationArray = new ArrayList<LocationModel>();
locationAdapter = new LocationAdapter(SelectGameActivity.this, R.layout.item, locationArray);
lv.setTextFilterEnabled(true);
lv.setAdapter(locationAdapter);
lv.setItemsCanFocus(true);
String serverName = getResources().getString(R.string.serverAdress);
ApplicationController AC = (ApplicationController)getApplicationContext();
String idPlayer = AC.getIdPlayer();
int latitude = AC.getCurrentPositionLat();
int longitude = AC.getCurrentPositionLon();
int maxDistance = 99999999;
try {
new LocationSync().execute("myserverName");
} catch(Exception e) {}
}
//this is connection with json
private class LocationSync extends AsyncTask<String, Integer, LocationList> {
protected LocationList doInBackground(String... urls) {
LocationList list = null;
int count = urls.length;
for (int i = 0; i < count; i++) {
try {
// ntar diganti service
RestClient client = new RestClient(urls[i]);
try {
client.Execute(RequestMethod.GET);
} catch (Exception e) {
e.printStackTrace();
}
String json = client.getResponse();
list = new Gson().fromJson(json, LocationList.class);
//
} catch(Exception e) {}
}
return list;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(LocationList loclist) {
for(LocationModel lm : loclist.getLocations())
{
locationArray.add(lm);
}
locationAdapter.notifyDataSetChanged();
}
}
EDIT:: I have second problem... i want to get id from item (items are downloading from json url) This is my list:
I want to get for example: ID:159 for first item and send it to nextActivity.
I have also the controllerClass.java where i'm setting and getting selectedIdGame:
public String getIdGameSelected() {
return idGame;
}
public void setIdGameSelected(String idGame) {
this.idGame = idGame;
}
Is it good idea? Thanks for help.
Ok, it's done. i used:
public void onItemClick(AdapterView<?> a, View
v, int position, long id) {
String idGame = (String) ((TextView) v.findViewById(R.id.idGameSelected)).getText();
Thanks, Michal.
You could define an onItemClick on your adapter instance (i.e. in mainListView.java, just after lv.setAdapter):
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View
v, int position, long id) {
Intent i = new Intent(v.getContext(), NextActivity.class);
startActivity(i);
}
});
lv.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
Intent i = new Intent(view.getContext(), NextActivity.class);
startActivity(i);
}
});
I don't know why this wouldn't work, put it after the try{}catch{} block.