My ListView populates correctly, but for some reason adding and removing is quirky and does not work properly! Am I doing something wrong?
Set things up in OnCreate()
listView = (ListView) findViewById(R.id.ListView);
registerForContextMenu(listView);
deserializeQuotes();
if(quotes == null || quotes.size() == 0){
quotes = new ArrayList<Quote>();
//populateDefaultQuotes();
//serializeQuotes();
//getQuotesFromYQL();
}
this.quotesAdapter = new QuoteAdapter(this, R.layout.mainrow, quotes);
listView.setAdapter(this.quotesAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
deserializeQuotes();
Quote myQuote = quotes.get(position);
Toast toast = Toast.makeText(getApplicationContext(), myQuote.getName(), Toast.LENGTH_SHORT);
toast.show();
}
});
Quote Adapter Private Class
private class QuoteAdapter extends ArrayAdapter<Quote> {
private ArrayList<Quote> items;
public QuoteAdapter(Context context, int textViewResourceId,
ArrayList<Quote> items) {
super(context, textViewResourceId, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.mainrow, null);
}
Quote q = items.get(position);
if (q != null) {
TextView nameText = (TextView) v.findViewById(R.id.nameText);
TextView priceText = (TextView) v.findViewById(R.id.priceText);
TextView changeText = (TextView) v.findViewById(R.id.changeText);
if (nameText != null) {
nameText.setText(q.getSymbol());
}
if (priceText != null) {
priceText.setText(q.getLastTradePriceOnly());
}
if (changeText != null) {
changeText.setText(q.getChange());
}
}
return v;
}
}
Remove an item from the list (THIS DOESNT WORK, DOES NOTHING)
#Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle()=="Remove"){
deserializeQuotes();
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
quotesAdapter.remove(quotes.get(info.position));
quotesAdapter.notifyDataSetChanged();
serializeQuotes();
}
else {
return false;
}
return true;
}
Add an item to the list (THIS WORKS)
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
deserializeQuotes();
this.quotesAdapter = new QuoteAdapter(this, R.layout.mainrow, quotes);
quotesAdapter.notifyDataSetChanged();
listView.setAdapter(quotesAdapter);
}
}
Here is how I serialize and deserialize
private void serializeQuotes(){
FileOutputStream fos;
try {
fos = openFileOutput(Constants.FILENAME, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(quotes);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
#SuppressWarnings("unchecked")
private void deserializeQuotes(){
try{
FileInputStream fis = openFileInput(Constants.FILENAME);
ObjectInputStream ois = new ObjectInputStream(fis);
quotes = (ArrayList<Quote>) ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
The code seems to be alright. Can you try using this in your remove?:
if("Remove".equals(item.getTitle())) {
//....
}
Edit:
I just noticed you are de-serializing "Quote" objects by calling deserializeQuotes(). Have you overridden the boolean equals(Object) method of Quote object? When you de-serialize, the object created are not the "same", i.e. they are new objects altogether and if you haven't overridden the equals method:
quotesAdapter.remove(quotes.get(info.position));
will fail because it won't find any Quote object to remove in the list.
Can you check that?
Related
I'm using a ListView inside a Fragment which downloads notes from Firebase storage and then displays them. However, the problem I'm running into is when it displays the notes its just a empty note layout, but when I switch activities and go back they're no longer blank, they're loaded. I'm not sure where exactly I'm going wrong, I've tried calling onDataSetChange to the Adapter Everywhere, also tried invalidate() and invalidateViews() on the ListView hoping it would just simply refresh the views, but unfortunately that didnt work either :/ the code is below, thank you in advanced for any help! :)
this is where I'm setting the Adapter in my Notes fragment
mNoteStorage = FirebaseStorage.getInstance().getReference().child("Notes").child(currentUser.getUid());
mNotesDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
my_notes.setAdapter(null);
Iterable<DataSnapshot> all_keys = dataSnapshot.getChildren();
filename_arrayList = new ArrayList<>();
na = null;
for (DataSnapshot each_key : all_keys) {
String each = each_key.getKey();
filename_arrayList.add(each);
}
for (String each_filename : filename_arrayList) {
downloadFile(each_filename);
Note each_note = Utilities.getNoteByName(getContext(), each_filename + Utilities.FileExtention);
each_note_array.add(each_note);
}
if (each_note_array == null || each_note_array.size() == 0) {
Toast.makeText(getActivity().getApplicationContext(), "No Notes!", Toast.LENGTH_LONG).show();
} else {
na = new MyNotesAdapter(getContext(), R.layout.item_note, each_note_array);
my_notes.setAdapter(na);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
and Here's my Adapter
class MyNotesAdapter extends ArrayAdapter<Note> {
Context ctx;
public MyNotesAdapter(#NonNull Context context, int resource, ArrayList<Note> note) {
super(context, resource, note);
this.ctx = context;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//return super.getView(position, convertView, parent);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_note, null);
}
Note note = getItem(position);
if(note != null) {
TextView title = (TextView) convertView.findViewById(R.id.list_note_title);
TextView content = (TextView) convertView.findViewById(R.id.list_note_content);
TextView date = (TextView) convertView.findViewById(R.id.list_note_date);
Typeface music_font = Typeface.createFromAsset(getContext().getAssets(), "fonts/melodymakernotesonly.ttf");
Typeface scribble_card = Typeface.createFromAsset(getContext().getAssets(), "fonts/the unseen.ttf");
if (getThemeCountInt() == 0) {
title.setTypeface(music_font);
} else if (getThemeCountInt() == 1) {
title.setTypeface(scribble_card);
}
content.setTypeface(scribble_card);
title.setText(note.getTitle());
date.setText(note.getDateTimeFormatted(getContext()));
if(note.getContent().length() > 25) {
content.setText(note.getContent().substring(0,25) + "...");
} else {
content.setText(note.getContent());
}
if(note.getContent().length() <= 0) {
content.setText("(Empty Note..)");
} else {
content.setText(note.getContent());
}
if (note.getTitle().length() <= 0) {
title.setText("(Untitled)");
} else {
title.setText(note.getTitle());
}
}
return convertView;
}
private int getThemeCountInt() {
SharedPreferences mSharedPreferences = this.getContext().getSharedPreferences("theme", MODE_PRIVATE);
int selectedTheme = mSharedPreferences.getInt("theme", 0);
return selectedTheme;
}
}
downloadFile
private void downloadFile(final String filenames) {
final String each_filename = filenames + Utilities.FileExtention;
final long file_size = 1024 * 1024;
mNoteStorage.child(each_filename).getBytes(file_size).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
FileOutputStream stream;
FileInputStream streamIn;
try {
File dir = getActivity().getApplication().getFilesDir();
File file = new File(dir, each_filename);
stream = new FileOutputStream(file);
stream.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
Utilities.getNoteByName
public static Note getNoteByName(Context context, String filename) {
File file = new File(context.getFilesDir(), filename);
Note note;
if (file.exists()) {
FileInputStream fis;
ObjectInputStream ois;
try {
fis = context.openFileInput(filename);
ois = new ObjectInputStream(fis);
note = (Note) ois.readObject();
fis.close();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
return note;
}
return null;
}
After you create MyNotesAdapter call notifyDataSetChanged() method to let ListView instance knows that underlying data has changed.
my_notes.setAdapter(na);
na.notifyDataSetChanged();
Personally I prefer to create and set adapter instance once and then use its add() method to manipulate its underlying data. Once I finished, I call adapter notifyDataSetChanged().
Recreating new adapter instance each time database change may trigger garbage collector to run more often.
I am working on a android project where I have to implement search view on the action bar . I am able to parse the JSON data into recycler view using volley. when I try to add a search view, and start typing the text the list is getting disappeared.
Activity:
public class Fragment_Church_News extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private ListView listView;
Context con;
private ChurchNewsFeedListAdapter listAdapter;
private List<ChurchNewsFeedItem> feedItemschurchnews;
int a = Keys.LANGUGAE_KEY;
public Fragment_Church_News() {
// Required empty public constructor
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_church_list);
con = this;
if(Keys.LANGUGAE_KEY == 0)
{
a = 2;
}
else
{
a=1;
}
Toast.makeText(this, "aaaaaaa"+a+"", Toast.LENGTH_SHORT).show();
listView = (ListView) findViewById(R.id.list);
feedItemschurchnews = new ArrayList<ChurchNewsFeedItem>();
listAdapter = new ChurchNewsFeedListAdapter(this, feedItemschurchnews,con);
listView.setAdapter(listAdapter);
Toast.makeText(this, "a", Toast.LENGTH_SHORT).show();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView c = (TextView) view.findViewById(R.id.news_details);
String idfromtextview = c.getText().toString().trim();
Intent testIntent = new Intent(Fragment_Church_News.this, MainColapse.class);
testIntent.putExtra("txtpersonid", idfromtextview);
startActivity(testIntent);
}
});
/////
// We first check for cached request
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Cache.Entry entry = cache.get("http://52.89.46.93/churchListAppDump/?methodName=church.list&app_language_name="+a+"");
if (entry != null) {
// fetch the data from cache
try {
String data = new String(entry.data, "UTF-8");
try {
parseJsonFeed(new JSONObject(data));
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
// making fresh volley request and getting json
JsonObjectRequest jsonReq = new JsonObjectRequest(Request.Method.GET,
"http://52.89.46.93/churchListAppDump/?methodName=church.list&app_language_name="+a+"", null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
VolleyLog.d(TAG, "Response: " + response.toString());
;
if (response != null) {
parseJsonFeed(response);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
// Adding request to volley request queue
AppController.getInstance().addToRequestQueue(jsonReq);
}
}
private void parseJsonFeed(JSONObject response) {
try {
JSONArray feedArray = response.getJSONArray("responseMsg");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
ChurchNewsFeedItem item = new ChurchNewsFeedItem();
item.setNews_title(feedObj.getString("church_name"));
String image = feedObj.isNull("church_image") ? null : feedObj
.getString("church_image");
item.setNews_image(image);
item.setNews_details(feedObj.getString("admin_id"));
// String priya = feedObj.getString("admin_id");
feedItemschurchnews.add(item);
}
// notify data changes to list adapater
listAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
public static void deleteCache(Context context) {
try {
File dir = context.getCacheDir();
deleteDir(dir);
} catch (Exception e) {
}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
return dir.delete();
} else if (dir != null && dir.isFile()) {
return dir.delete();
} else {
return false;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
//getMenuInflater().inflate(R.menu.menu_search, menu);
MenuInflater inflater = getMenuInflater();
// Inflate menu to add items to action bar if it is present.
inflater.inflate(R.menu.search_main, menu);
SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView search = (SearchView) menu.findItem(R.id.action_search).getActionView();
search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
PerfromSearch(newText);
return false;
}
});
return true;
}
void PerfromSearch(String query) {
listAdapter.filter(query);
}
}
Adapter:
public class ChurchNewsFeedListAdapter extends BaseAdapter
{
private Activity activity;
private LayoutInflater inflater;
Context mContext;
private List<ChurchNewsFeedItem> churhcnewsfeedItems, churchNewsFeedItemssearched=null;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
//List<ChurchNewsFeedItem> arraylist;
public ChurchNewsFeedListAdapter(Activity activity, List<ChurchNewsFeedItem> feedItems,Context context) {
this.activity = activity;
this.churhcnewsfeedItems = feedItems;
this.churchNewsFeedItemssearched = new ArrayList<ChurchNewsFeedItem>();
this.churchNewsFeedItemssearched.addAll(feedItems);
// mContext = this;
this.mContext = context;
}
#Override
public int getCount() {
return churhcnewsfeedItems.size();
}
#Override
public Object getItem(int location) {
return churhcnewsfeedItems.get(location);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.churchnews_feed_item, null);
if (imageLoader == null)
imageLoader = AppController.getInstance().getImageLoader();
TextView newstitle = (TextView) convertView.findViewById(R.id.news_title);
TextView newdetails = (TextView) convertView
.findViewById(R.id.news_details);
ChurchNewsFeedImageView feedImageView = (ChurchNewsFeedImageView) convertView
.findViewById(R.id.news_feedImage);
ChurchNewsFeedItem item = churhcnewsfeedItems.get(position);
newstitle.setText(item.getNews_title());
// Chcek for empty status message
if (!TextUtils.isEmpty(item.getNews_details())) {
newdetails.setText(item.getNews_details());
newdetails.setVisibility(View.VISIBLE);
} else {
// status is empty, remove from view
newdetails.setVisibility(View.GONE);
}
// Feed image
if (item.getNews_image() != null) {
feedImageView.setImageUrl(item.getNews_image(), imageLoader);
feedImageView.setVisibility(View.VISIBLE);
feedImageView
.setResponseObserver(new ChurchNewsFeedImageView.ResponseObserver() {
#Override
public void onError()
{
}
#Override
public void onSuccess() {
}
});
} else {
feedImageView.setVisibility(View.GONE);
}
return convertView;
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
Toast.makeText(mContext, "divakar"+churchNewsFeedItemssearched, Toast.LENGTH_SHORT).show();
churhcnewsfeedItems.clear();
if (charText.length() == 0) {
churhcnewsfeedItems.addAll(churchNewsFeedItemssearched);
} else {
for (ChurchNewsFeedItem wp : churchNewsFeedItemssearched) {
if (wp.getNews_title().toLowerCase(Locale.getDefault())
.contains(charText)) {
churhcnewsfeedItems.add(wp);
}
}
}
notifyDataSetChanged();
}
}
Seems your churchNewsFeedItemssearched list is NULL. Because when you initialize ChurchNewsFeedListAdapter you are passing feedItemschurchnews with 0 items:
listAdapter = new ChurchNewsFeedListAdapter(this, feedItemschurchnews, con);
So, for this your Adapter's constructor works like below:
public ChurchNewsFeedListAdapter(Activity activity, List<ChurchNewsFeedItem> feedItems,Context context) {
this.activity = activity;
this.churhcnewsfeedItems = feedItems; // SIZE 0
this.churchNewsFeedItemssearched = new ArrayList<ChurchNewsFeedItem>();
this.churchNewsFeedItemssearched.addAll(feedItems); // SIZE 0
}
SOLUTION:
You have to update list churchNewsFeedItemssearched.
Add method updateSearchedList() to your ChurchNewsFeedListAdapter class to update the churchNewsFeedItemssearched and call this method from parseJsonFeed() after adding all items to feedItemschurchnews.
Update your code as below:
ChurchNewsFeedListAdapter:
public void updateSearchedList() {
churchNewsFeedItemssearched.addAll(churhcnewsfeedItems);
}
Fragment_Church_News:
private void parseJsonFeed(JSONObject response) {
try {
JSONArray feedArray = response.getJSONArray("responseMsg");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
ChurchNewsFeedItem item = new ChurchNewsFeedItem();
item.setNews_title(feedObj.getString("church_name"));
String image = feedObj.isNull("church_image") ? null : feedObj
.getString("church_image");
item.setNews_image(image);
item.setNews_details(feedObj.getString("admin_id"));
// String priya = feedObj.getString("admin_id");
feedItemschurchnews.add(item);
}
// Update
listAdapter.updateSearchedList();
// notify data changes to list adapater
listAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
Hope this will work~
I'm developing an Android app but I'm a newbie and I got stuck...
My ListView single element has an ImageView and some TextViews, but sometimes (when I scroll the page and there are more than 7-8 elements) it doesn't display the right image in the right row.
I'm using a custom Image Loader to manage the downloaded images.
Here's my Adapter:
public class AddVideogameActivityAdapter extends BaseAdapter {
private ArrayList<Videogame> videogames;
private Typeface typefaceMedium;
private Typeface typefaceLight;
private ImageLoader loader;
private LayoutInflater mInflater;
public AddVideogameActivityAdapter(Context context, ArrayList<Videogame> results) {
videogames = results;
mInflater = LayoutInflater.from(context);
typefaceMedium = Typeface.createFromAsset(context.getAssets(), "Roboto-Medium.ttf");
typefaceLight = Typeface.createFromAsset(context.getAssets(), "Roboto-Light.ttf");
loader = new ImageLoader(context);
}
public int getCount() {
return videogames.size();
}
public Object getItem(int position) {
return videogames.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_element,null);
holder = new ViewHolder();
holder.imgView = (ImageView) convertView.findViewById(R.id.thumbView);
holder.txtName = (TextView) convertView.findViewById(R.id.elementView);
holder.txtPlatform = (TextView) convertView.findViewById(R.id.elementView2);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
try {
Videogame vgame = (Videogame) videogames.get(position);
holder.txtName.setText(vgame.getTitle());
holder.txtName.setTypeface(typefaceMedium);
holder.txtPlatform.setText(videogames.get(position).getPlatform());
holder.txtPlatform.setTypeface(typefaceLight);
holder.imgUrl = videogames.get(position).getImage();
loader.display(holder.imgUrl, holder.imgView, R.drawable.youtube_icon);
}
catch (Exception e) {
e.printStackTrace();
Log.e(com.example.ludos2_0.MainActivity.TAG,
"Exception: " + e.getLocalizedMessage());
}
return convertView;
}
static class ViewHolder {
TextView txtName;
TextView txtPlatform;
public String imgUrl;
ImageView imgView;
}
}
Sorry for my english and thank you for your help!
EDIT:
Here's also the Loader:
public class ImageLoader implements ComponentCallbacks2 {
private TCLruCache cache;
public ImageLoader(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
int memoryClass = am.getMemoryClass() * 1024 * 1024;
cache = new TCLruCache(memoryClass);
}
public void display(String url, ImageView imageview, int defaultresource) {
imageview.setImageResource(defaultresource);
Bitmap image = cache.get(url);
if (image != null) {
imageview.setImageBitmap(image);
}
else {
new SetImageTask(imageview).execute(url);
}
}
private class TCLruCache extends LruCache<String, Bitmap> {
public TCLruCache(int maxSize) {
super(maxSize);
}
}
private class SetImageTask extends AsyncTask<String, Void, Integer> {
private ImageView imageview;
private Bitmap bmp;
public SetImageTask(ImageView imageview) {
this.imageview = imageview;
}
#Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
bmp = getBitmapFromURL(url);
if (bmp != null) {
cache.put(url, bmp);
}
else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
return 0;
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (result == 1) {
imageview.setImageBitmap(bmp);
}
super.onPostExecute(result);
}
private Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}
RE-EDIT
Activity code:
public class AddVideogameActivity extends ListActivity {
private TextView searchField = null;
private final Handler handler = new Handler();
private ArrayList<Videogame> videogamesList = null;
private static AddVideogameActivity mContext = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_book);
mContext = this;
searchField = (TextView) findViewById(R.id.searchField);
searchField.setMaxLines(1);
searchField.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
searchField.setHint("");
}
});
// Setup the list view and its listener
getListView().setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Log.d(MainActivity.TAG,
"AddBookActivity ---> AddButton:onClick()");
// Sets typefaces for TextView
String videogameId = videogamesList.get(position).getId();
String videogameName = videogamesList.get(position).getTitle();
String thumbnail = videogamesList.get(position).getThumbnail();
String description = videogamesList.get(position)
.getDescription();
String image = videogamesList.get(position).getImage();
String platform = videogamesList.get(position).getPlatform();
if (videogameName != null && videogameName.length() > 0
&& thumbnail != null && thumbnail.length() > 0
&& description != null && description.length() > 0
&& image != null && image.length() > 0
&& platform != null && platform.length() > 0) {
if (ListsManager.getInstance().addVideogame(
new Videogame(videogameId, videogameName,
thumbnail, image, description, platform)) == 0) {
Log.d(MainActivity.TAG,
"AddBookActivity --> Videogame:[" + videogameId
+ "#" + videogameName + "]");
Toast toast = Toast.makeText(mContext, "["
+ videogameName + "] Saved !",
Toast.LENGTH_LONG);
toast.show();
} else {
Log.e(MainActivity.TAG,
"AddBookActivity --> Error ! Videogame already in the list ! ");
Toast toast = Toast.makeText(mContext,
"Error! Videogame already in the list!",
Toast.LENGTH_LONG);
toast.show();
}
} else {
Log.e(MainActivity.TAG,
"AddBookActivity --> Error ! Invalid Videogame Name or Thumbnail or Id or Deck");
Toast toast = Toast
.makeText(
mContext,
"Error ! Invalid Videogame Name or Thumbnail or Id or Deck",
Toast.LENGTH_LONG);
toast.show();
}
Intent newIntent = new Intent(getApplicationContext(),
MainActivity.class);
startActivity(newIntent);
}
});
// Setup the search button and its listener
Button searchButton = (Button) findViewById(R.id.searchButton);
searchButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d(com.example.ludos2_0.MainActivity.TAG, "Search Game ...");
String searchInputString = searchField.getText().toString();
if (searchInputString != null && searchInputString.length() > 0) {
try {
String requestURL = ("http://www.giantbomb.com/api/search/?api_key=fcf60d6d67b98b0d17b3905d1a90b3fd31ed1e8e&format=json&query="
+ Uri.encode(searchInputString) + "&resources=game");
// String requestURL =
// String.format("https://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc&category=Music&orderby=relevance&q=%s",Uri.encode(searchInputString));
Log.d(com.example.ludos2_0.MainActivity.TAG, requestURL);
DownloadGiantBombJSONData giantbombAsyncTask = new DownloadGiantBombJSONData();
giantbombAsyncTask.execute(new String[] { requestURL });
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
if (videogamesList == null)
videogamesList = new ArrayList<Videogame>();
else
updateVideogamesListView(videogamesList);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add_book, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
}
public void updateVideogamesListView(ArrayList<Videogame> values) {
AddVideogameActivityAdapter adapter = new AddVideogameActivityAdapter(this, values);
setListAdapter(adapter);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
The other classes involved in building the ListView are the REST classes and the AsyncTask class that downloads and parses the JSon files.
What does your ListView look like, does it look like this:
<ListView android:id="#id/android:list"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dip" ></ListView>
Especially the id of the ListView. Check your layout file, probably the bug exists there.
I am trying to parse the xml file and trying to load images and textviews and display it in a list view but whenever i try to load images in getView method in force closes the application even if try to scroll fast it also does the same. Iam tired of doing it in thread and asynctask for 5hours.please help if someone can solve it. Here are my two class files.
class NewsRowAdapter
public class NewsRowAdapter extends ArrayAdapter<Item>
{
LoadingImage loadingImage;
Bitmap bitmap = null;
private Activity activity;
private List<Item> items;
private Item objBean;
private int row;
public NewsRowAdapter(Activity act, int resource, List<Item> arrayList)
{
super(act, resource, arrayList);
this.activity = act;
this.row = resource;
this.items = arrayList;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
View view = convertView;
final ViewHolder holder;
if (view == null)
{
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(row, null);
holder = new ViewHolder();
view.setTag(holder);
} else
{
holder = (ViewHolder) view.getTag();
}
if ((items == null) || ((position + 1) > items.size()))
return view;
objBean = items.get(position);
holder.tvTitle = (TextView) view.findViewById(R.id.tvtitle);
holder.tvDesc = (TextView) view.findViewById(R.id.tvdesc);
holder.tvDate = (TextView) view.findViewById(R.id.tvdate);
holder.imgView = (ImageView) view.findViewById(R.id.image);
holder.pbar = (ProgressBar) view.findViewById(R.id.pbar);
if (holder.tvTitle != null && null != objBean.getTitle() && objBean.getTitle().trim().length() > 0)
{
holder.tvTitle.setText(Html.fromHtml(objBean.getTitle()));
}
if (holder.tvDesc != null && null != objBean.getDesc() && objBean.getDesc().trim().length() > 0)
{
holder.tvDesc.setText(Html.fromHtml(objBean.getDesc()));
}
if (holder.tvDate != null && null != objBean.getPubdate() && objBean.getPubdate().trim().length() > 0)
{
holder.tvDate.setText(Html.fromHtml(objBean.getPubdate()));
}
if (holder.imgView != null)
{
if (null != objBean.getLink() && objBean.getLink().trim().length() > 0)
{
final ProgressBar pbar = holder.pbar;
pbar.setVisibility(View.INVISIBLE);
//---------CHANGES MADE FOR LOADING IMAGE----------//
Log.d("IMAGE NULL----------", objBean.getLink());
//loadBitmap(objBean.getLink());
/*new Thread()
{
public void run()
{*/
try
{
URL linkurl = new URL(objBean.getLink());
bitmap = BitmapFactory.decodeStream(linkurl.openConnection().getInputStream());
holder.imgView.setImageBitmap(bitmap);
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
/*}
}.start();*/
} else
{
holder.imgView.setImageResource(R.drawable.ic_launcher);
}
}
return view;
}
//------LOADING IMAGE FROM URL------//
public static Bitmap loadBitmap(String url)
{
Bitmap bitmap = null;
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try
{
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK)
{
Log.d("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null)
{
InputStream inputStream = null;
try
{
inputStream = entity.getContent();
bitmap = BitmapFactory.decodeStream(inputStream);
} finally
{
if (inputStream != null)
{
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e)
{
// Could provide a more explicit error message for IOException or IllegalStateException
getRequest.abort();
Log.d("Error while retrieving bitmap from " + url, e.toString());
} finally
{
if (client != null)
{
client.close();
}
}
return bitmap;
}
public class ViewHolder
{
public TextView tvTitle, tvDesc, tvDate;
private ImageView imgView;
private ProgressBar pbar;
}
}
and the main class is :
class MainActivity
public class MainActivity extends Activity implements OnItemClickListener
{
private static final String rssFeed = /*"https://www.dropbox.com/s/t4o5wo6gdcnhgj8/imagelistview.xml?dl=1"*/"http://78.46.34.27/kapapps/newparsedtransaction.xml";
List<Item> arrayOfList;
ListView listView;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mainnewtransaction);
listView = (ListView) findViewById(R.id.listview);
listView.setOnItemClickListener(this);
if (Utils.isNetworkAvailable(NewTransactionActivity.this))
{
new MyTask().execute(rssFeed);
} else
{
showToast("No Network Connection!!!");
}
}
// My AsyncTask start...
class MyTask extends AsyncTask<String, Void, Void>
{
ProgressDialog pDialog;
#Override
protected void onPreExecute()
{
super.onPreExecute();
pDialog = new ProgressDialog(NewTransactionActivity.this);
pDialog.setTitle("Latest Transaction");
pDialog.setMessage("Loading... Please wait");
pDialog.show();
}
#Override
protected Void doInBackground(String... params)
{
arrayOfList = new NamesParser().getData(params[0]);
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
if (null == arrayOfList || arrayOfList.size() == 0)
{
showToast("No data found from web!!!");
NewTransactionActivity.this.finish();
} else
{
// check data...
/*
* for (int i = 0; i < arrayOfList.size(); i++)
* {
* Item item = arrayOfList.get(i); System.out.println(item.getId());
* System.out.println(item.getTitle());
* System.out.println(item.getDesc());
* System.out.println(item.getPubdate());
* System.out.println(item.getLink());
* }
*/
for(int i = 0 ; i < arrayOfList.size() ; i++)
{
Item item = arrayOfList.get(i);
Log.d("ID NEWTRANSACTION ACTIVITY ------>" , item.getId());
Log.d("TITLE NEWTRANSACTION ACTIVITY ------>" , item.getTitle());
Log.d("DESC NEWTRANSACTION ACTIVITY ------>", item.getDesc());
Log.d("LINK NEWTRANSACTION ACTIVITY ------>", item.getLink());
}
setAdapterToListview();
}
if (null != pDialog && pDialog.isShowing())
{
pDialog.dismiss();
}
}
}
#Override
public void onItemClick(AdapterView<?> parent , View view , int position , long id)
{
Item item = arrayOfList.get(position);
Intent intent = new Intent(NewTransactionActivity.this, DetailActivity.class);
intent.putExtra("url", item.getLink());
intent.putExtra("title", item.getTitle());
intent.putExtra("desc", item.getDesc());
Log.d("IMAGE_URL------>" , item.getLink());
startActivity(intent);
}
public void setAdapterToListview()
{
NewsRowAdapter objAdapter = new NewsRowAdapter(NewTransactionActivity.this , R.layout.row, arrayOfList);
listView.setAdapter(objAdapter);
}
public void showToast(String msg)
{
}
}
Do Image retrieving logic in another thread.It is taking too much time to load Images that's why you are getting ANR.
Use a single worker thread, and make it possible to stop in onPause() of activity.
Good way is to use a SingleThread Executor service to load images.
Here's an example https://stackoverflow.com/a/14579365/1366471
I recommend using the RemoteImageView from the Prime library. It reduces your work a lot.
In your layout, replace ImageView with com.handlerexploit.prime.widgets.RemoteImageView and in your code, change ImageView to RemoteImageView in your holder class.
In the getView method,
holder.imgView = (RemoteImageView) view.findViewById(R.id.image);
//...
holder.imgView.setImageURL(objBean.getLink());
i have to parse xml file to get country details like country name and country postal code.
how can i parse country names to spinner adapter and when i select perticular country using spinner i have to display particular country code in textview.
please help me.
Thanks in advance.
Here is a code to parse Xml file where you will have to pass inputstream of your local xml file.
public static ArrayList<Country> parseCountry(Context context, InputStream inputStream) {
String KEY = "";
String VALUE = null;
ArrayList<Country> arrCountires = new ArrayList<Country>();
Country country = null;
ArrayList<State> arrStates = null;
State state= null;
ArrayList<City> arrCities = null;
City city = null;
try {
InputStreamReader inputreader = null;
if(inputStream != null) {
inputreader = new InputStreamReader(inputStream);
}
if(inputreader != null) {
XmlPullParserFactory factory = null;
factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = null;
xpp = factory.newPullParser();
xpp.setInput(inputreader);
int eventType = 0;
eventType = xpp.getEventType();
eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_TAG) {
KEY = xpp.getName();
if(KEY.equalsIgnoreCase(TAGS.COUNTRIES)) {
arrCountires = new ArrayList<Country>();
}else if(KEY.equalsIgnoreCase(TAGS.COUNTRY)) {
country = new Country();
arrStates = new ArrayList<State>();
country.setCountryId(xpp.getAttributeValue(null, TAGS.ID));
}else if(KEY.equalsIgnoreCase(TAGS.STATE)) {
state = new State();
arrCities = new ArrayList<City>();
state.setStateId(xpp.getAttributeValue(null, TAGS.ID));
}else if(KEY.equalsIgnoreCase(TAGS.CITY)) {
city = new City();
city.setCityId(xpp.getAttributeValue(null, TAGS.ID));
}
}else if(eventType == XmlPullParser.END_TAG) {
KEY = xpp.getName();
if(KEY.equalsIgnoreCase(TAGS.COUNTRY)) {
country.setArrStates(arrStates);
arrCountires.add(country);
}else if(KEY.equalsIgnoreCase(TAGS.COUNTRY_NAME)) {
country.setCountryName(VALUE);
}else if(KEY.equalsIgnoreCase(TAGS.STATE_NAME)) {
state.setStateName(VALUE);
}else if(KEY.equalsIgnoreCase(TAGS.STATE)) {
state.setArrCities(arrCities);
arrStates.add(state);
}else if(KEY.equalsIgnoreCase(TAGS.CITY)) {
arrCities.add(city);
}else if(KEY.equalsIgnoreCase(TAGS.CITY_NAME)) {
city.setCityName(VALUE);
}
}else if(eventType == XmlPullParser.TEXT) {
VALUE = xpp.getText();
}
eventType = xpp.next();
}
}
}
catch (Exception e) {
e.printStackTrace();
}finally {
if(inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return arrCountires;
}
Here is a Country class with Getter and Setter methods.
public class Country {
String countryId;
String countryName;
ArrayList<State> arrStates;
public ArrayList<State> getArrStates() {
return arrStates;
}
public void setArrStates(ArrayList<State> arrStates) {
this.arrStates = arrStates;
}
public String getCountryId() {
return countryId;
}
public void setCountryId(String countryId) {
this.countryId = countryId;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
}
Here is a Adapter class to set country in the spinner.
private class CountryAdapter implements SpinnerAdapter{
ArrayList<Country> data;
public CountryAdapter(ArrayList<Country> data){
this.data = data;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return android.R.layout.simple_spinner_dropdown_item;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v = new TextView(getApplicationContext());
v.setTextColor(Color.BLACK);
v.setText(data.get(position).getName());
v.setTextSize(15);
v.setPadding(10, 10, 10, 10);
v.setSingleLine();
v.setEllipsize(TruncateAt.END);
return v;
}
#Override
public int getViewTypeCount() {
return android.R.layout.simple_spinner_item;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
#Override
public void registerDataSetObserver(DataSetObserver observer) {
}
#Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
#Override
public View getDropDownView(int position, View convertView,
ViewGroup parent) {
return this.getView(position, convertView, parent);
}
}
Here is a Interface by which you can get the selected country from the spinner
OnItemSelectedListener OnCountrySelected = new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View v, int position,
long id) {
if(position != AdapterView.INVALID_POSITION) {
System.out.println("Country name = " + arrCountries.get(position).getName());
//Here you can set this value to the textview
}
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
};
Here is a way how you can set the Listener to the spinner
spCountry.setOnItemSelectedListener(OnCountrySelected);
Here is a code to open file as inputstream from assets
try {
InputStream inputStream = v.getContext().getAssets().open("path of file");
ArrayList<Country> arrCountries = parseCountry(this, inputStream);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
When you get the response in the array of Country then set adapter to the spinner
CountryAdapter countryAdapter = new CountryAdapter(arrCountry);
spCountry.setAdapter(countryAdapter);