I have a problem to update a listview, but doesn't work. Gives the NullPointerException on ".SetAdapter", does anyone know what can be?
Complete code: http://pastebin.com/AZdMi4sc
//Get filter from another fragment, using Interface, works fine.
public void setFilter(String tag) {
getFeedFilter(tag);
}
//Get only itens
private void getFeedFilter(String filter) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("FeedPost");
query.whereContains("Type", filter);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> responseList, ParseException e) {
if (e == null) {
List<Feed> items = new ArrayList<Feed>();
for(int i = 0; i < responseList.size(); i++) {
items.add(new Feed(responseList.get(i).getString("objectId"),
responseList.get(i).getString("Title"));
}
adapter = new FeedAdapter(getActivity(), items);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter); // The error occurs here.
} else {
System.out.println("error: "+ e);
}
}
});
}
Logcat log:
04-27 03:52:23.175 4415-4415/com.fatos.application.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.fatos.application.app.fragment.FeedFragment$6.done(FeedFragment.java:256)
at com.parse.FindCallback.internalDone(FindCallback.java:45)
at com.parse.FindCallback.internalDone(FindCallback.java:31)
at com.parse.Parse$5$1.run(Parse.java:853)
.....
1) you should check if the adapter isn't null.this will fix your crash.
if(adapter!=null)
listView.setAdapter(adapter);
2) you should check if the items returned from response are ok, your problem might be there.
3) your code mixed up, you should init your views and set listeners on one method,
I always call init in fragment - OnCreateView ...
4) The problem might be with your listView, when you are using custom view make sure you give the full location of the custom listview class as your view instead of ListView.
Also, if you just update your adapter, you should not re create your adapter every time. create method in your adapter which set the new data. and just call adapter.notifyDataSetChanged();
For example:
In your adapter code add this:
public void setData(ArrayList<object> newData) {
this.data = newData;
}
then, in your activity notify adapter :
if(items!=null && items.size()>0) {
if(adapter==null){
adapter = new FeedAdapter(getActivity(), items);
}
else {
adapter.setData(yourArrayList);
adapter.notifyDataSetChanged();
}
else {
make toast for us or log to notice items are null...
}
if(adapter!=null)
listView.setAdapter(adapter);
I also think you should init your view and set listeners on your onCreateView method,
because everything is split in your code.
Related
I am making an android app and it allows user to enter the keywords in a editText and when they hit submit the recyclerview down below will show the result from an API request.
I have a updateList() method inside my recyclerView adapter class
list = savedInfo.getResult(); // get updated list from a singleton class
notifyDataSetChanged(); // update the recyclerView
I call this method after making the API Request successfully. However, it is now working, the recyclerView is not updated.
mSearchBox is the editText allows users to enter keywords and here is the onEditorAction, it will make an API call and if it called successfully, it will call UpdateList(), then the adapter will get the updated list and do notifyDataSetChanged()
mSearchBox.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_DONE) {
HttpRequest httpRequest = new HttpRequest();
mHomeText.setText(textView.getText());
try {
if (httpRequest.makeCall(textView.getText().toString())){
adapter.updateList();
}
else {
// showing error message
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
return false;
}
});
Also, here is the steps to set my adapter
final ResultListAdapteradapter = new ResultListAdapter();
mResult.setAdapter(adapter);
mResult.setLayoutManager(new LinearLayoutManager(getContext()));
Debugging Steps: I tried to set break points and found out the API Request and my Singleton class are both working, the issue is just the RecyclerView.
Thank you so much!
When you do
list = savedInfo.getResult();
notifyDataSetChanged();
It is every time creating new list instance and the old one is not referenced anywhere. So instead of assigning to list you should do
list.clear()
list.addAll(savedInfo.getResult());
notifyDataSetChanged();
Don't forget to initialize list if not done before.
This is my code, when I debugging then code work properly means list item show in Listview but without debugging list item not showing in this code Listview empty
ImageView cancl1e = convertView1.findViewById(R.id.btncance);
if (jsonArray.length() > 0) {
listView = convertView1.findViewById(R.id.Benificiarylist);
adapter = new Recipient_ListAdapter(MoneyTransferFragment.this,value);
listView.setAdapter(adapter);
cancl1e.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alertDialog1.dismiss();
}
});
alertDialog1.setView(convertView1);
alertDialog1.show();
} else {
Nodatafound.setVisibility(View.VISIBLE);
}
Kindly handle dialog separately. It's working while debugging because while debugging its getting time between display data dialog I guess. Please specify if wrong.
I have two classes , the first one is for the GUI , where I declared my listview and the adapter , and the setters , to call them from my second class .
public class AndroidGUIModifier implements IMyComponentGUIModifier, IFragmentEvents {
private transient ListView lv;
List<String> mydeviceslist;
ArrayAdapter<String> adapter ;
public void setAdapter(ArrayAdapter<String> adapter) {
this.adapter = adapter;
adapter.notifyDataSetChanged();
}
public void setMydeviceslist(List<String> mydeviceslist) {
this.mydeviceslist = mydeviceslist;
}
#Override
public void onCreateView() {
lv=(ListView) fragment.findViewById("xdevices") ;
mydeviceslist = new ArrayList<String>();
adapter = new ArrayAdapter<String>(fragment.getContext(),android.R.layout.simple_list_item_1,mydeviceslist);
lv.setAdapter(adapter);
In my second class I'll wait an event to receive the list that I want to load it in my listview , then I'll call the list setter to set the new received list and the adapter setter to update it , but it didn't work , nothing was displayed despite I receieved the list of devices in my log .
public class triprincipal extends BCModel {
public List<String> mydevices ;
BCEvent bcEvent;
final ArrayAdapter<String> adapter =guiModifier.getAdapter();
while (isRunning()) {
bcEvent = waitForBCEvent();
if (bcEvent.getID() == checkevent) {
mydevices = bcCommandSenderPlugin.getDevicesNames(); // here I get a list of my devices
Log.i("devices", mydevices.toString());
guiModifier.getFragment().getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
guiModifier.setMydeviceslist(mydevices);
guiModifier.setAdapter(adapter);
}
} );
In setMydeviceslist() do it like:
this.mydeviceslist.addAll(mydeviceslist);
adapter.notifyDataSetChanged();
Hope it will help you out.
adapter.notifyDataSetChanged() will not work in this case, as the value of the reference you have passed to the adapter doesn't actually change.
You will need to create a new Adapter and set it to the ListView to make it work. Change your setAdapter() to this :
public void setAdapter() {
this.adapter = new ArrayAdapter<String>(fragment.getContext(), android.R.layout.simple_list_item_1, mydeviceslist);
lv.setAdapter(adapter);
}
try to update the list in same fragment/activity and after update call notifyDataSetChanged() both in same activity/fragment ....donot set adapter on list repetedly......hope it helps
am trying to update my adapter after adding some data in it but its not updating , when i switch through other activities and come back the adapter got updated this time my code :
void updateAdapter(){
adapter.setData(getData());
adapter.notifyDataSetChanged();
Log.d("TAG"," DATA SIZE AFTER UPDATE : "+getData().size() +" items : "+adapter.getItemCount());
}
my adapter :
private void createAdapter(final RecyclerView recyclerView , final List<Information> data) {
List<Information> content = new ArrayList<>();
Log.d("TAG","createAdapter Called");
final int[] currentRowPosition = {0};
content = data;
final List<Information> finalContent = content;
adapter = new ParallaxRecyclerAdapter<Information>(finalContent) {
/// my onBindViewHolder
#Override
public void onBindViewHolderImpl(final RecyclerView.ViewHolder viewHolder, final ParallaxRecyclerAdapter<Information> adapter, final int i) {
currentRowPosition[0] = i;
if ( i <= finalContent.size() -1 ){
((ViewHolder) viewHolder).linearLayout.setVisibility(View.GONE);
final Information current = finalContent.get(i);
((ViewHolder) viewHolder).DESCRIPTION.setText(current.description);
}else {
// this is my loadMore button which stays at the last row of recyclerView
((ViewHolder) viewHolder).setIsRecyclable(false);
((ViewHolder) viewHolder).linearLayout.setVisibility(View.VISIBLE);
((ViewHolder) viewHolder).itemView.getLayoutParams().height = 100;
((ViewHolder) viewHolder).LOADMORE.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fetchNext();
}
});
}
}
//my on create View Holder
#Override
public RecyclerView.ViewHolder onCreateViewHolderImpl(ViewGroup viewGroup, final ParallaxRecyclerAdapter<Information> adapter, int i) {
return new ViewHolder(getActivity().getLayoutInflater().inflate(R.layout.custom_row, viewGroup, false));
}
#Override
public int getItemCountImpl(ParallaxRecyclerAdapter<Information> adapter) {
return finalContent.size()+1;
}
});
// adding header to recyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
View header = getActivity().getLayoutInflater().inflate(R.layout.header, recyclerView, false);
headerImageView = (ImageView) header.findViewById(R.id.headerImageView);
//setting CoverImage
adapter.setParallaxHeader(header, recyclerView);
adapter.setData(content);
recyclerView.setAdapter(adapter);
}
any idea how can i add new items with realtime updation on my RecyclerView ?? any guidance will be so helpful for me
I am assuming that when you run the Activity (which has RecyclerView) for the first time it loads everything from the adapter properly.
But when you change to other activities which would change items to your adapter and come back to your Activity which has RecyclerView in it can't get the proper updated information as adapter is not updated.
This may be because you are not refreshing your adapter when your activity resumes in onResume(), something like this. you may have to make other changes to your onResume method as required,
onResume(){
if(adapter != null){
adapter.notifyDataSetChanged();
}
}
Kindly check the lifecycle of an Activity
Example:
This does not directly addresses your issue but help you understand as you come back to activity you should refresh the adapter.
There is a NoteListActivity, with ListView in it, you may Add or edit items to the Adapter in it in NoteEditActivity and as soon as you come back you have to refresh the adapter in the activity where you have your listview
Adapter.class
public void add(List<Information> informations){
try{
finalContent.addAll(informations);
}catch(Exception e){
e.printstacktrace();
}
notifyDataSetChanged();
}
well i ended up with this :
int offset = adapter.getItemCount();
for(int l=0; l<= 4 ; l++){
Log.d("TAG","getData : "+getData().size());
if ((offset - 2) + l < getData().size()){
adapter.addItem(getData().get((offset - 2 ) + l) , adapter.getItemCount() - 2);
adapter.notifyDataSetChanged();
}
}
what i needed was adapter.addItem(item , position) and adapter.notifyDataSetChanged(); the above example is loading 5 images at a time
I have a ListView in a ListFragment that is populated via a database query. It loads all the data just fine when it first populates the list in onCreate(). But when I requery the database, assign the return value to assignmentsCursor, and call notifyDataSetChanged(), it doesn't update adapter.mCursor. If I go into the Debugging mode in Eclipse I can see that assignmentsCursor.mCount has changed, but when I look at adapter.mCursor.mCount, it's the same as before. (Yes, I'm checking after notifyDataSetChanged() has been called.)
The relevant parts of my code:
SimpleCursorAdapter adapter;
Cursor assignmentsCursor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
course = savedInstanceState.getShort(Values.ASSIGNMENT_KEY_COURSE);
}
setRetainInstance(true);
// Create and array to specify the fields we want
String[] from = new String[] { Values.KEY_TITLE, Values.ASSIGNMENT_KEY_COURSE };
// and an array of the fields we want to bind in the view
int[] to = new int[] { R.id.assignment_list_title, R.id.assignment_list_course };
// Need to give assignmentsCursor a value -- null will make it not work
updateAdapter();
adapter = new SimpleCursorAdapter(context, R.layout.assignment_list_item, assignmentsCursor, from, to);
setListAdapter(adapter);
}
public void onResume() {
super.onResume();
updateAdapter();
refresh();
}
/**
* Updates the content in the adapter.
*/
public void updateAdapter() {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean showingCompleted = sharedPrefs.getBoolean(Values.ASSIGNMENT_KEY_SHOWING_COMPLETED, false);
if (course < 0) // Showing assignments from all courses
if (showingCompleted)
assignmentsCursor = DbUtils.fetchAllAssignments(context, Values.ASSIGNMENT_LIST_FETCH, null, true);
else
assignmentsCursor = DbUtils.fetchIncompleteAssignments(context, Values.ASSIGNMENT_LIST_FETCH, null, true);
else // Showing assignments from specified course
if (showingCompleted)
assignmentsCursor = DbUtils.fetchAllAssignments(context, Values.ASSIGNMENT_LIST_FETCH, course, true);
else
assignmentsCursor = DbUtils.fetchIncompleteAssignments(context, Values.ASSIGNMENT_LIST_FETCH, course, true);
}
private void refresh() {
updateAdapter();
adapter.notifyDataSetChanged();
}
Help me!! ;)
P.S. If you need any more details/code, just let me know. I am positive that the database is querying correctly though.
Thanks to Deucalion, I have determined that I incorrectly assumed that the adapter was referencing the assignmentsCursor variable as opposed to creating a copy of the Cursor for itself. What I needed to do was just call adapter.changeCursor(assignmentsCursor) so that it updated its local copy. Thanks again Deucalion!