The list view is not updating data when the notifyDataChanged() method called.
In onCreate() method i initialized the the listview with no data.
ListView videoList = (ListView)findViewById(R.id.videos_list);
videoList.setOnItemClickListener(listener);
listAdapter = new PHVideosListAdapter(PHVideosActivity.this, videos);
videoList.setAdapter(listAdapter);
After this I started fetching list of video using new VideosCategoryFetchTask().execute();
in the post execute method I called
#Override
protected void onPostExecute(Boolean success) {
if(success) {
listAdapter.notifyDataSetChanged();
} else {
//show dialog
}
}
but nothing is displayed on the list. If anybody knew the solution please help...
private class VideosDetailsFetchTask extends AsyncTask<String, Void, Boolean> {
#Override
public void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... params) {
Boolean success = false;
try {
if (params.length >= 0) {
videos = (Videos)videoAPI.videosForCategoryId(params[0],new VideosParser());
success = true;
}
} catch (Exception e) {
// TODO: handle exception
}
return success;
}
#Override
protected void onPostExecute(Boolean success) {
if(success) {
progressBar.setVisibility(View.INVISIBLE);
onFinishVideoFetch();
} else {
//show dialog
}
}
}
here using two Async classes sec one is called on the onPostExecute() of first one..
private void onFinishVideoFetch() {
if(videos != null) {
listAdapter.notifyDataSetChanged();
}
}
I 'm not fetching videos one by one.. here a list of videos is returned....
After getting the list of videos i wanted to refresh the list.
#Override
protected void onProgressUpdate(Videos... values) {
videos = values[0];
//add published object to list which holds
listAdapter.notifyDataSetChanged();
}
I tried this but no luck please help..
this is the adapter class used
public class PHVideosListAdapter extends BaseAdapter{
private Videos videoTitles;
private LayoutInflater inflater;
public PHVideosListAdapter(Context context, Videos videoTitles) {
inflater = LayoutInflater.from(context);
this.videoTitles = videoTitles;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
if(videoTitles != null) {
return videoTitles.size();
}
else {
return 0;
}
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return videoTitles.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
VideoListViewHolder holder = null;
if (convertView == null) {
holder = new VideoListViewHolder();
convertView = inflater.inflate(R.layout.videos_list, null);
holder.videoTitle = (TextView) convertView.findViewById(R.id.video_title);
holder.videoImage = (ImageView) convertView.findViewById(R.id.video_image);
holder.videoDuration = (TextView) convertView.findViewById(R.id.video_duration);
convertView.setTag(holder);
} else {
holder = (VideoListViewHolder)convertView.getTag();
}
holder.videoImage.setImageResource(R.drawable.icon);
holder.videoDuration.setText("00:10");
holder.videoTitle.setText(videoTitles.get(position).getVideoTitle());
return convertView;
}
private class VideoListViewHolder {
ImageView videoImage;
TextView videoTitle;
TextView videoDuration;
}
}
When you first create your PHVideosListAdapter, it is holding a reference to the Videos list that I assume is a member of your Activity. In your doInBackground method, the call to videoAPI.videosForCategoryId is updating the Videos reference in your Activity, but the adapter is still holding the original reference that was passed in to the constructor for PHVideosListAdapter. You need to either recreate the PHVideosListAdapter in onPostExecute or add a set method in PHVideosListAdapter to change the private variable videoTitles.
I ran into the same issue with using the ArrayAdapter provided by Google. You can only set the underlying List in the constructor, so you must recreate the ArrayAdapter or create your own class that allows changing of the underlying data for notifyDataSetChanged to work.
You need to override onProgressUpdate() of AsynTask class
Heres an example of AsyncTask assuming your list is videos which holds Objects of type Video and your extended adapter is VideosAdapter
private class VideosDetailsFetchTask extends AsyncTask<String, Video, Boolean> {
#Override
public void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(String... params) {
//utilize string you are passing otherwise use Void as first generic param.
Boolean success = false;
try {
if (params.length >= 0) {
Videos videoFetched = (Videos)PrimeraHoraAPI.videosForCategoryId(params[0],new VideosParser());
success = true;
publishProgress(videoFetched);
}
} catch (Exception e) {
// TODO: handle exception
}
return success;
}
#Override
protected void onPostExecute(Boolean success) {
if(success) {
progressBar.setVisibility(View.INVISIBLE);
onFinishVideoFetch();
} else {
//show dialog
}
}
#Override
protected void onProgressUpdate(Video... values) {
videos.add(values[0]);//add published object to list which holds
((VideosAdapter)getListAdapter()).notifyDataSetChanged();
}
}
It's not very good descript anywhere but what you do when u call
listAdapter.notifyDataSetChanged();
u tell your machine "oke, your code is not legit" and now u stop! so basically ur machine has no clue what 2 do next! My solution is:
create a private void setupData()
private void setupData() {
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
final List<Table_Follow> data = db.getAllData(); // from database
HashMap<String,String> item;
for(Table_Data td : data){
item = new HashMap<String,String>();
item.put("name1", td.getName_One());
item.put("name2", td.getName_Two());
item.put("date", td.getDate());
list.add(item);
};
my_data = new SimpleAdapter(this, list, R.layout.my_listview_row, new String[] { "name1","name2", "date" }, new int[] {R.id.lv_line_a, R.id.lv_line_b, R.id.lv_line_c});
listview.setAdapter(my_data);
}
I have a custom layout with 3 textviews (line a > title, line b > subtitle, line c > time see bottom page for xml). So basicly i ll use this private void to tell my machine what 2 do next by using setupData() after calling > notifydatasetchanged() in my main thread
my_data.notifyDataSetChanged();
setupData();
One last thing! I use the android listview id for my listview in my main xml file! Oh and if you have trouble using your 'onItemClickListener' (not giving u the right id, just text me! I faced that problem and solved it pretty shitty but it works :p)
My xml file for my listview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/lv_line_c"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="15sp" />
<LinearLayout
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/lv_line_a"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="#+id/lv_line_b"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
Related
I am working on an Application in Android where I shut down all of my servers. Therefore, I use an ArrayAdapter and a Listview.
In a background process, I iterate over the IP - Addresses and shutdown all of my servers.
Now, I want when iterating over my servers to color each row in the ListView in Green ( means still working on it to shut it down ) or Red as soon as the server is shut down.
I am able to color each row in a different color when extending the ArrayAdapter and then in the getView method coloring them all differently.
But how can I do that when iterating over each row during the background process?
My adapter is being set during the call of my Activity class.
Do I have to put the setAdapter method in my backgroundprocess, too, or something like that?
Here is my code:
protected void onCreate(Bundle savedInstanceState) {
initComponents();
}
private void initComponents() {
model = new SharedPreferenceModel(getBaseContext());
mydb = new DatabaseHelper(this);
array_list = mydb.getAllCotacts();
hostsOnline = new ArrayList<String>();
btnShutdown = findViewById(R.id.btnShutdown);
lv = (ListView) findViewById(R.id.listView);
CustomArrayAdapter custom = new CustomArrayAdapter(this, android.R.layout.simple_list_item_1, array_list);
lv.setAdapter(custom);
}
private void addListeners(final ShutdownServers shutdownServers) {
btnShutdown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new AsyncTask<Integer, String, Void>() {
#Override
protected Void doInBackground(Integer... params) {
try {
for(int i = 0; i<array_list.size(); i++){
posInArray++;
String host = array_list.get(i);
if(host.equals("192.168.1.1"))
publishProgress("Shutdown " + host);
else
executeRemoteCommand(getBaseContext(), host);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(String... values) {
hostsOnline.add(values[0]);
custom.setNotifyOnChange(true);
custom.notifyDataSetChanged();
}
}.execute(1);
}
});
}
Thanks for your help!
You can use setNotifyOnChange(boolean) method and corresponding add(), remove etc. methods to control list state (adding, removing, changing items). Keep in mind, that changing state of backing array field won't trigger UI changes automatically without that. If you want to control changes manually, you can use notifyDataSetChanged() method of ArrayAdapter.
It's all because ArrayAdapter tries to instantiate views only once and reuse them for different array elements when scrolling down. View's state should be only modified in getView() which normally would be called only once per array element, when it's about to be rendered on screen first time. However, you can force 'redraw' using notifyDataSetChanged() at any time to keep UI state consistent with backing array field.
lv.setBackgroundResource(R.drawable.your file)// from drawable
lv.setBackgroundResource(Color.BLACK)// from color by default
Now I was able to solve the colouring problem. Here is my solution:
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
// Get the current item from ListView
View view = super.getView(position,convertView,parent);
if(notifyCalling==1 && position == getPos()){
Log.d("getView - if - position", String.valueOf(position));
view.setBackgroundColor(Color.GREEN);
}else if(notifyCalling ==1 && position < getPos()){
Log.d("getView - elseif - position", String.valueOf(position));
view.setBackgroundColor(Color.RED);
}else if (position % 2 == 1) {
view.setBackgroundColor(Color.LTGRAY);
} else {
view.setBackgroundColor(Color.WHITE);
}
return view;
}
private void addListeners(final ShutdownServers shutdownServers) {
btnShutdown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btnShutdown.setClickable(false);
new AsyncTask<Integer, String, Void>() {
#Override
protected Void doInBackground(Integer... params) {
try {
for(int i = 0; i<array_list.size(); i++){
String host = array_list.get(i);
publishProgress(host);
executeRemoteCommand(getBaseContext(), host);
setIndex(i+1);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(String... values) {
custom.setNotifyOnChange(true);
custom.notifyDataSetChanged(getIndex());
}
}.execute(1);
}
});
}
I have an activity whose only purpose is to display a list view. There is a custom adapter to serve up the views for each element in the array.
I have break points all over and when I debug, it stops in "count" a number of times - the first few times the return value is zero, then it changes to 3 (the correct value in this case). Then we stop in "getView" - all the right stuff happens, and after we're through with all the break points, then presto magico all three records display on the screen. Yea!
So then I try to run the app outside of the debugger. I get the log message that it's visited "count", and the log message displays the return value so I know it's correct - but "getView" never gets called!!
I'm not sure which bits of code are relevant to this question & don't want to pollute the question with the entire project; please let me know if there's a specific section that would be helpful. I've researched all the "getView not called" questions but those consistently are for a case where getView never gets called, which clearly mine can beā¦sometimes :(
EDIT: Adapter code
public class DivisionAdapter extends BaseAdapter {
private static final String TAG = "DIV_ADAPT";
private ArrayList<Division> divisionList;
private Context context;
public DivisionAdapter(Context c, ArrayList<Division> divList) {
divisionList = divList;
context = c;
}
#Override
public int getCount() {
Integer count = 0;
if (divisionList != null) count = divisionList.size();
Log.v(TAG,count.toString());
return count;
}
#Override
public Object getItem(int position) {
Object o = null;
if (divisionList != null)
o = divisionList.get(position);
return o;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.v(TAG,"getView");
if (divisionList == null)
return null;
LinearLayout divisionView = null;
Division thisDiv = divisionList.get(position);
if (convertView == null) {
divisionView = new LinearLayout(context);
LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
li.inflate(R.layout.division_item, divisionView, true);
} else {
divisionView = (LinearLayout) convertView;
}
Log.v(TAG,thisDiv.name());
TextView v = (TextView) divisionView.findViewById(R.id.divisionName);
v.setText(thisDiv.name());
v = (TextView) divisionView.findViewById(R.id.divisionRegion);
v.setText(thisDiv.region());
return divisionView;
}
public void setList(ArrayList<Division> newList) {
divisionList = null;
divisionList = newList;
}
}
And just in case it's useful, some snippets from the activity class:
#Override
public void onResume() {
super.onResume();
refreshList();
}
private void refreshList() {
// use the class static query method to get the list of divisions
Division.query(Division.class,
new StackMobQuery().fieldIsEqualTo("status", "ACTIVE"),
new StackMobQueryCallback<Division>() {
#Override
public void failure(StackMobException arg0) {
// TODO Auto-generated method stub
Log.v(TAG, "query fail");
}
#Override
public void success(List<Division> arg0) {
Log.v(TAG, "query success");
divAdapt.setList((ArrayList<Division>) arg0);
divAdapt.notifyDataSetChanged();
}
});
}
EDIT 2/11:
I found this question: Markers not showing on map after stackmob query which reveals the hitherto unknown fact that stack mob queries run on a background thread. I'm starting to research the relationship between threads and adapters and thought I'd share this clue in case it helps anyone else figure out what's going on here faster than I can. TIA.
idk why this EVER worked in the debugger - that turned out to be a red herring.
As discovered, the StackMobModel static query method does run in a background thread, from which calling NotifyDataSetChanged() is completely ineffectual.
I ended up replacing the success method in the StackMobQueryCallback as follows:
#Override
public void success(final List<Division> arg0) {
Log.v(TAG, "query success");
runOnUiThread(new Runnable() {
public void run() {
updateList((ArrayList<Division>) arg0);
}
});
}
and then added this new method
private void updateList(ArrayList<Division> newList) {
divAdapt.setList(newList);
divAdapt.notifyDataSetChanged();
}
now, when the query returns, the adapter update is directed to run on the proper thread, and hooray, everything looks stitched together just fine and dandy.
whew!
i want to show an circle before updating the listview , everything is working fine, while doinbackground of async task fetch the data from server it shows the progressbar but while updating the listview it freezes for sometime and then listview is shown, i want to remove that freezing of progressbar before updating, here is my code
public class feeds extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>>{
protected void onPreExecute() {
// SHOW THE SPINNER WHILE LOADING FEEDS
linlaHeaderProgress.setVisibility(View.VISIBLE);
}
#Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
new_request_feeds(); //here i am fetching data from server
return fetch;
}
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
// HIDE THE SPINNER AFTER LOADING FEEDS
linlaHeaderProgress.setVisibility(View.GONE);
if(result.size()!=0)
{
adapter=new CustomListAdapter(getActivity(), R.id.list_ongoing, result);
list.setAdapter(adapter);
}
else
{
Toast.makeText(getActivity(), "no feeds", 3000).show();
}// Here if you wish to do future process for ex. move to another activity do here
}
my getview()
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int pos=position;
System.out.println(position);
View v = convertView;
final ViewHolder holder;
if (v == null) {
LayoutInflater vi =
(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.feed_row, null);
holder = new ViewHolder();
holder.like=(ImageButton) v.findViewById(R.id.like);
holder.share=(ImageButton) v.findViewById(R.id.share);
holder.report=(ImageButton) v.findViewById(R.id.report);
holder.headline_text = (TextView) v.findViewById(R.id.lar);
holder.topic_text = (TextView) v.findViewById(R.id.mt);
holder.count_likes = (TextView) v.findViewById(R.id.count_likes);
holder.count_shares = (TextView) v.findViewById(R.id.count_shares);
holder.image = (ImageView) v.findViewById(R.id.img1);
holder.image2 = (ImageView) v.findViewById(R.id.img2);
v.setTag(holder);
}
else
holder=(ViewHolder)v.getTag();
mSharedPreferences= v.getContext().getSharedPreferences("mypref", 0);
holder.headline_text.setText(" "+entries.get(pos).get(TAG_FFN)+" had a chance with "+entries.get(pos).get(TAG_IFN)+"! ");
holder.topic_text.setText(entries.get(pos).get(TAG_TOPIC));
holder.image.setTag(entries.get(pos).get(TAG_FTID));
holder.image2.setTag(entries.get(pos).get(TAG_ITID));
holder.count_likes.setText(entries.get(pos).get(TAG_LIKERS)+" likes");
holder.count_shares.setText(entries.get(pos).get(TAG_SHARERS)+" shares");
if(entries.get(pos).get(TAG_LIKED).equals("True"))
{
holder.like.setImageResource(R.drawable.like);
holder.like.setTag("True");
}
else
{
holder.like.setTag("False");
}
if(entries.get(pos).get(TAG_SHARED).equals("True"))
{
holder.share.setImageResource(R.drawable.share);
holder.share.setEnabled(false);
}
//=======================setting image of user==========================================//
// Loader image - will be shown before loading image
// whenever you want to load an image from url
// call DisplayImage function
// url - image url to load
// loader - loader image, will be displayed before getting image
// image - ImageView
imgLoader.DisplayImage((image_url.getimage(Long.parseLong(entries.get(pos).get(TAG_FTID))))[0],loader, holder.image);
imgLoader.DisplayImage((image_url.getimage(Long.parseLong(entries.get(pos).get(TAG_ITID))))[0],loader, holder.image2);
//====================================================================================//
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if((holder.image.getTag()).equals(mSharedPreferences.getString("USERID", null)))
{
Toast.makeText(v.getContext(), "Your profile", Toast.LENGTH_LONG).show();
}
else
{
Intent i=new Intent(v.getContext(),OtherProfilePage.class);
i.putExtra("Image_id",entries.get(pos).get(TAG_FTID));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
(v.getContext()).startActivity(i);
}
}
});
holder.image2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.image2.getTag().equals(mSharedPreferences.getString("USERID", null)))
{
Toast.makeText(v.getContext(), "Your profile", Toast.LENGTH_LONG).show();
}
else
{
Intent i=new Intent(v.getContext(),OtherProfilePage.class);
i.putExtra("Image_id", entries.get(pos).get(TAG_ITID));
(v.getContext()).startActivity(i);
}
}
});
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.like.getTag()=="True")
{
holder.like.setImageResource(R.drawable.like_pressed);
holder.like.setTag("False");
new sendlikes().execute("link");
}
else
{ holder.like.setImageResource(R.drawable.like);
holder.like.setTag("True");
new sendlikes().execute("link");
}
}
});
holder.share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
holder.share.setImageResource(R.drawable.share);
holder.share.setEnabled(false);
new sendlikes().execute("http://gangster.cloudapp.net/share/",entries.get(pos).get(TAG_CID),mSharedPreferences.getString("person_id",null));
}
});
return v;
}
imageloader is a class that i used for caching the images.
Try to put this line linlaHeaderProgress.setVisibility(View.GONE); after if and else blocks. Hope this will work for you.
I think the issue could lie in a couple places:
1) You're doing a good deal of pre-processing of data in you Adapter's constructor.
Remember that everything in onPostExecute() runs on the application UI thread, so if your constructor for your adapter does some heavy processing, it could lock up the UI thread.
Creating an adapter can be done in doInBackground and then passed as the result to onPostExecute so that the setAdapter call is the only call there.
2) Your getView() method in your adapter isn't very efficient.
When you call setAdapter, the AdapterView must call getView for every cell that's going to be shown on screen. If there are a lot of cells and you're doing a lot of expensive operations like inflating views or findingViewsById, you could be locking up the UI thread for that initial load.
How's your scrolling performance? If it's lacking, the getView() would be the first place to start and I would watch Romain Guy's great talk on ListView performance for recommendations on how to create a good, efficient adapter.
http://www.youtube.com/watch?v=wDBM6wVEO70
add a listener when onpostexecute is completed in listener onsuccess method in your activity set adpater and then dismiss progress it will work
in you activity add this interface
public interface asyncListener{
public void onSucess(Object object);
public void onFailure(Exception exception);
}
and add a varible
asyncListener as= new asyncListener() {
#Override
public void onSucess(Object object) {
// TODO Auto-generated method stub
}
#Override
public void onFailure(Exception exception) {
// TODO Auto-generated method stub
}
};
send this varible(listenr) in construtor in your asynctask contruct asign this to yourlistener in onpostexecute write yourlistener.onSucess(result);
I am unable to refresh my listview. I know there are lots of help available for this. But I am unable to get my listview refreshed.
Lemme edit my code a little bit showing the AsyncTask
There are two Activities. The first Activity is having the list view to see what is being shared and the second activity has an edit text box (to input inorder to share) and a button. On clicking the button, it returns me the string which is the json response and I need to add this in the previous activity.
Now the problem is, when I refresh the first page fully hitting the server it gets the response but this is not what I want. It should not go back to the server. It should simply add in the list view adapter.
I have commented the code in the PostExecute(). I have tried the everyway but it is not reflecting.
public class ShareAsyncTask extends AsyncTask<String, Void, ArrayList<EventsStreamBean>> {
public ProgressDialog pd = new ProgressDialog(EventStreamActivity.this);
String success_share_val;
#Override
protected ArrayList<EventsStreamBean> doInBackground(
String... result) {
// TODO Auto-generated method stub
JSONObject jsonobj = new JSONObject(result[0].toString());
success_share_val = jsonobj.getString(Constants.SUCCESS);
//checks the success value
if(success_share_val.equalsIgnoreCase("1")) {
JSONArray events_stream_share_array = jsonobj.getJSONArray("streamArray");
if(events_stream_share_array.length() > 0) {
for(int i=0; i<events_stream_share_array.length(); i++) {
EventsStreamBean events_stream_bean = new EventsStreamBean();
JSONObject events_stream_object = events_stream_share_array.getJSONObject(i);
events_stream_bean.setStreamId(events_stream_object.getString(Constants.STREAM_ID));
events_stream_bean.setStreamType(events_stream_object.getString(Constants.STREAM_TYPE));
events_stream_bean.setUserId(events_stream_object.getString(Constants.USER_ID));
events_stream_bean.setUserName(events_stream_object.getString(Constants.USER_NAME));
events_stream_bean.setUserType(events_stream_object.getString(Constants.USER_TYPE));
events_stream_bean.setUserAvatar(events_stream_object.getString(Constants.USER_AVATAR));
arraylist_events_stream.add(events_stream_bean);
}
}else {
Log.i("Test", "No Events Streams Available");
}
}
}catch(Exception e) {}
return arraylist_events_stream;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
this.pd.setMessage("Loading....");
pd.setCanceledOnTouchOutside(false);
pd.setCancelable(false);
this.pd.show();
}
#Override
protected void onPostExecute(final ArrayList<EventsStreamBean> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(this.pd.isShowing()) {
this.pd.dismiss();
}
Toast.makeText(EventStreamActivity.this, "Post shared successfully", Toast.LENGTH_SHORT).show();
new EventsStreamAsyncTask().execute(temp_val);
/*runOnUiThread(new Runnable() {
public void run() {
//EventStream_Customadapter adapter = (EventStream_Customadapter) list_view.getAdapter();
//adapter.clearData();
adapter.updateData(result);
//adapter = new EventStream_Customadapter(EventStreamActivity.this, arraylist_events_stream);
//list_view.setAdapter(adapter);
//adapter.notifyDataSetChanged();
}
});*/
}
}
You should call setAdapter() only once in your entire code.
Then add a method in your adapter that adds more data when you want to add more data or sets adapter item.
public void addMoreData(List<String> newItems) {
this.list.addAll(newItems);
}
public void setList(List<String> newList) {
this.list = newList;
}
Call notifyDataSetChanged() after you set new list or add more data.
as per what you want to achieve there is no need for you to use threads
have a look at the following link it shows how to do it in the same activity
http://wptrafficanalyzer.in/blog/dynamically-add-items-to-listview-in-android/
In this they have done it in a single activity. if you want to do it with 2 activities let me know i will tell you how to do it.
Hi There I am very new to the android platform ..off late I was trying my hands on parsing rss feed using xml pull parser..My code works perfectly when I use the standard listview layout of android..but when I try to implement the same code using a customized list view and adapter ..no data is been shown..I tested my customized adapter with raw data (not the one fetch from the feed) and it works perfectly..But when I try to use the information fetched from the feed the list view doesn't show any data..Have been trying for quite some time now yet am unable to get it done..Can anyone please help me in identifying the mistakes I am committing...Mind you my app functions perfectly with non internet data but not with the ones fetch from the feed..I am trying to extract the title tag from the feed..any help will be highly appreciated...the codes are as follows
MainActivity.java
public class MainActivity extends Activity {
ArrayList<FeedData> headlines;
List <String>title;
FeedData data = new FeedData();
List links;
String msg =null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = new ArrayList<String>();
links = new ArrayList();
headlines = new ArrayList<FeedData>();
DownloadTask runner =new DownloadTask();
runner.execute();
for(int i=0;i<title.size();i++){
msg=title.get(i).toString();
data.setTitle(msg);
headlines.add(data);
}
FeedAdapter adapter= new FeedAdapter(MainActivity.this,R.layout.imagefeed,headlines);
ListView list = (ListView)findViewById(R.id.lvMyFeed);
list.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class DownloadTask extends AsyncTask<String,Integer,String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try{ URL url = new URL("http://www.pcworld.com/index.rss ");
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
// We will get the XML from an input stream
xpp.setInput(getInputStream(url), "UTF_8");
boolean insideItem = false;
// Returns the type of current event: START_TAG, END_TAG, etc..
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equalsIgnoreCase("item")) {
insideItem = true;
} else if (xpp.getName().equalsIgnoreCase("title")) {
if (insideItem)
title.add(xpp.nextText()); //extract the headline
} else if (xpp.getName().equalsIgnoreCase("link")) {
if (insideItem)
links.add(xpp.nextText()); //extract the link of article
}
}else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
insideItem=false;
}
eventType = xpp.next(); //move to next element
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
public InputStream getInputStream(URL url) {
try {
return url.openConnection().getInputStream();
} catch (IOException e) {
return null;
}
}
}// end of DownloadTask class
}`
FeedData.java
public class FeedData {
String headlines;
public FeedData()
{
}
public FeedData(String title) {
this.headlines=title;
}
public void setTitle(String title){
this.headlines=title;
}
public String getTitle(){
return headlines;
}
}`
`FeedData.java
public class FeedData {
String headlines;
public FeedData()
{
}
public FeedData(String title) {
this.headlines=title;
}
public void setTitle(String title){
this.headlines=title;
}
public String getTitle(){
return headlines;
}
}
activity_main.xml
<ListView
android:id="#+id/lvMyFeed"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
imagefeed.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/ivImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="28dp"
android:layout_marginTop="38dp"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/tvFeed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/ivImg"
android:layout_marginLeft="78dp"
android:layout_marginTop="14dp"
android:layout_toRightOf="#+id/ivImg"
android:text="Headlines" />
</RelativeLayout>
display or set your adapter. ListView after completed DownloadTask means call
FeedAdapter adapter= new FeedAdapter(MainActivity.this,R.layout.imagefeed,headlines);
ListView list = (ListView)findViewById(R.id.lvMyFeed);
list.setAdapter(adapter);
in onPostExecute.
The behaviour of AsynchTask is different thread so, your headlines title ArrayList is having no data that why your data is not displaying on ListView. So after finishing the DownloadTask set your adapter. Hope this will help you.