Xml pull parsing with customised adapter - android

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.

Related

loading data from the list when android app open

Hi I just created app for loading data from the website once the button is clicked in android.I want to change the app for loading data when the application open.How will I do it?
Here is my code..
public class PrimaryActivity extends Activity {
private static final String URL = "http://livechennai.com/powershutdown_news_chennai.asp";
ProgressDialog mProgressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_primary);
Button btnFetchData = (Button) findViewById(R.id.btnData);
btnFetchData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
new FetchWebsiteData().execute();
}
});
}
private class FetchWebsiteData extends AsyncTask<Void, Void, String[]> {
String websiteTitle, websiteDescription,websiteDescription1,websiteDescription2,websiteDescription3,listValue,listValue1;
ProgressDialog progress;
#Override
protected void onPreExecute() {
super.onPreExecute();
//some code here
}
#Override
protected String[] doInBackground(Void... params) {
ArrayList<String> hrefs=new ArrayList<String>();
try {
// parsing here
}
} catch (IOException e) {
e.printStackTrace();
}
//get the array list values
for(String s:hrefs)
{
//website data
}
//parsing first URL
} catch (IOException e) {
e.printStackTrace();
}
//parsing second URL
} catch (IOException e) {
e.printStackTrace();
}
try{
List<String> listString = new ArrayList<String>(Arrays.asList(resultArray));
listString.addAll(Arrays.asList(resultArray1));
String [] outResult= new String[listString.size()];
int i=0;
for(String str: listString){
outResult[i]=str;
i++;
}
return outResult;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String[] result) {
ListView list=(ListView)findViewById(R.id.listShow);
ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(getBaseContext(),android.R.layout.simple_list_item_1,result);
list.setAdapter(arrayAdapter);
mProgressDialog.dismiss();
}
}
}
How to load the list view when we open the app? help me to get the exact answer?
Just load it in onCreate. This is what will be called when the app is opened first. Then read about other events like onResume.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_primary);
new FetchWebsiteData().execute();
}
Call FetchWebsiteData().execute() from one of the activity lifecycle methods such as onStart, onCreate, or onResume - please refer to docs to determine which fits in your case.
Put the method which does the fetching i.e. new FetchWebsiteData().execute(); outside of the code of button click and in the activity.onResume() method.
onResume is called everytime an app comes to foreground, if you put it oncreate(), the method will be called only when the activity is created.

how to use runOnUiThread for Update Adapter

following code, I try update Adapter. Code is properly done .But Mobile to goes Hong mode.After the loop ends. Data is displayed.
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
_adapter.notifyDataSetChanged();
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
_adapter.notifyDataSetChanged();
}
}
});
Update :
I changed my code like the following code.
Hong mode is still not resolved.How do I fix it?
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
_adapter.notifyDataSetChanged();
}
});
Update 2 :
public static Bitmap GetImageFromUrl(String url) {
URL urlForImage;
Bitmap imageNews=null;
try {
urlForImage = new URL(url);
URLConnection conn = urlForImage.openConnection();
imageNews= BitmapFactory.decodeStream(conn.getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageNews;
}
Update 3 :
again : I changed my code like the following code. Hong mode is still not resolved.
public class AsyncTaskReadImageNews extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("INDEX_ITEM", String.valueOf(currentIndex));
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
_adapter.notifyDataSetChanged();
}
}
}
This is all my code :
public class MainActivity extends Activity {
NewsAdapter _adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
#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;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
boolean result=true;
int id = item.getItemId();
switch (id) {
case R.id.action_transfer_news:
SharedVar.setCurrentTask(Taskes.GET_TRANSFER_NEWS);
new JsoupCommands().ConnectToWebsite(MainActivity.this);
break;
case R.id.action_settings:
break;
default:
result=super.onOptionsItemSelected(item);
break;
}
return result;
}
public class JsoupCommands {
private Dialog _dialog;
private RatingBar _loadingStar;
public void ConnectToWebsite(Context context) {
_dialog = new Dialog(context);
_dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
_dialog.setContentView(R.layout.loading_layout);
_loadingStar=(RatingBar) _dialog.findViewById(R.id.loading_RatingBar);
Helpers.ConfigRatingLoader(_loadingStar);
new AsyncTaskJsoup().execute();
}
public class AsyncTaskJsoup extends AsyncTask<Void, Void, String>{
boolean _startThread;
Element _NewsRegion;
Elements _links;
List<News> _LisOfNews;
int _step=0;
#Override
protected String doInBackground(Void... listviews) {
String result=null;
Document doc;
try {
threadLoading.start();
SharedVar.clearNews();
doc = Jsoup.connect(Helpers.getCurrentTaskLink()).get();
_NewsRegion = doc.getElementById("content-post");
_links = _NewsRegion.select("article div[class=arch_body]");
_LisOfNews = new ArrayList<News>();
for (Element element : _links) {
Element textNewsElement = element.select("div[class=arch_content] a").first();
Element imageNewsElement = element.select("div[class=arch_img] a img").first();
String imageSrcNews = imageNewsElement.attr("src").trim().replace("../../../..", Helpers.GetCurrentSite());
String titleNews = textNewsElement.text().trim();
String linkNews = textNewsElement.attr("href").trim().replace("../../..", Helpers.GetCurrentSite()+"/persian");
String dateNews=textNewsElement.nextSibling().toString().trim();
News news = new News();
news.setIndex(_LisOfNews.size());
news.setTitle(titleNews);
news.setLink(linkNews);
news.setDate(dateNews);
news.setImageNewsAddress(imageSrcNews);
_LisOfNews.add(news);
}
SharedVar.setCurrentNews(_LisOfNews);
result="Success";
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
Thread threadLoading = new Thread()
{
#Override
public void run() {
try {
while(_startThread) {
Helpers.SetRatingLoad(_loadingStar, _step);
if(_step++==3){
_step=0;
}
Log.d("DELAY", String.valueOf(_step));
sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
#Override
protected void onPostExecute(String result) {
_startThread=false;
_dialog.dismiss();
FillNewsinListView();
new AsyncTaskReadImageNews().execute();
}
private void FillNewsinListView() {
List<News> news=SharedVar.getCurrentNews();
if(news!=null&&news.size()>0){
Log.d("FILL_NEWS", "YES");
_adapter = new NewsAdapter(MainActivity.this, R.layout.rows_news, SharedVar.getCurrentNews());
((ListView)findViewById(R.id.news_listView)).setAdapter(_adapter);
}else{
Log.d("FILL_NEWS", "NO");
}
}
#Override
protected void onPreExecute() {
_startThread=true;
_dialog.show();
}
}
public class AsyncTaskReadImageNews extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... arg0) {
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("INDEX_ITEM", String.valueOf(currentIndex));
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
_adapter.notifyDataSetChanged();
}
}
}
}
Your app hangs because you're doing the image downloading on the UI Thread. You'll need to do the image downloading off the UI thread.
What I'd suggest is to create an AsyncTask, add all the processing inside doInBackground() method and the _adapter.notifyDataSetChanged() inside onPostExecute() since this is the only thing that you need to call on the UI Thread.
change this:
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
_adapter.notifyDataSetChanged();
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
_adapter.notifyDataSetChanged();
}
}
});
to this:
(MainActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
for(News news : SharedVar.getCurrentNews()){
int currentIndex=news.getIndex();
Log.d("SRC_IMAGE_ADDRESS", news.getImageNewsAddress());
News replaceNews=new News();
News oldNews =_adapter.getItem(currentIndex);
replaceNews.setTitle(oldNews.getTitle()+" ( "+String.valueOf(currentIndex)+" )");
replaceNews.setImageNews(Helpers.GetImageFromUrl(news.getImageNewsAddress()));
SharedVar.getCurrentNews().set(currentIndex, replaceNews);
}
_adapter.notifyDataSetChanged();
}
});
explanation : calling notifyDataSetChanged many times in a row, is a bad idea.
make your updates to the data, and then call it once!
your code was calling it twice for every news item.
Your are calling notifyDataSetChanged() in your for loop which is a bad practice and that to you are calling it twice. So remove notifyDataSetChanged() from your for loop. A better approach would be to move your code to an AsyncTask inside doInBackground() and then call notifyDataSetChanged() in your onPostexecute().

Passing data between activities from listview to another activity

I am trying to pass the data from this main activity to another activity
I am successful in sending data between activities .... Like the data from Edit-text to next activity through putExtra and GetExtra methods and passing as intents
But i am facing challenge in this particular task where it involves
sending data from listview to an ordinary activity
data is populated in the list view from JSON so when on click of a
row how can i send the data from that row to a new activity
Any Ideas,
ativity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/listViewID"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center">
</ListView>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
// url to make request
private static String url = "http://54.218.73.244:7002/";
List<Item> yourData = new ArrayList<Item>();
ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Instantiating ProgressDialog with onCreate method
progressDialog=new ProgressDialog(MainActivity.this);
new ParsingAsync().execute();
}
private class ParsingAsync extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog=ProgressDialog.show(MainActivity.this, "", "Please Wait", true, false);
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
// Creating JSON Parser instance
JSONObjParser jParser = new JSONObjParser();
// getting JSON string from URL
JSONArray json = jParser.getJSONFromUrl(url);
try {
for (int i = 0; i < json.length(); i++) {
JSONObject c = json.getJSONObject(i);
// Storing each json item in variable
String NAME=c.getString("restaurantNAME");
yourData.add(new Item(NAME));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
progressDialog.dismiss();
ListView yourListView = (ListView) findViewById(R.id.listViewID);
ListAdapter customAdapter = new ListAdapter(MainActivity.this, R.layout.itemlistrow, yourData);
yourListView.setAdapter(customAdapter);
yourListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
if(position == 0)
{
//code specific to first list item
Intent myIntent = new Intent(MainActivity.this,CopperChimneyDesc.class);
startActivity(myIntent);
}else if(position == 1)
{
//Intent myIntent = new Intent(MainActivity.this,AroyDesc.class);
//startActivity(myIntent);
}
}
});
}
}
}
item.java
public class Item{
private String Name;
public Item(String name){
this.Name = name;
}
public String getName(){
return Name;
}
}
Thanks,
Ok so you would do
String item = yourData.get(position).getName();
Then you can add the string to intent using:
intent.putExtra("restaurent", item);
On the other end if its textview you would do
textView.setText(getIntent().getExtras().getString("restaurent"));
intent.putExtra("City Name", String.valueOf(lvCity.getSelectedItem()));
try this one to cast.
you can parcle data and send it to other activity with putxtera method.please see How to store values in onSaveInstanceState() and retrive?
Since you have the index of the item in the listview the user has clicked you can get the item value from the adapter:
String value = (String)customAdapter.getItem(position);
Intent myIntent = new Intent(MainActivity.this,CopperChimneyDesc.class);
intent.putExtra("restaurant_name", value);
startActivity(myIntent);
You can save the data in sharedPreferences and can access it from other activity. Just an idea :)

android html parsing with jsoup

Trying to parse an html pages like http://www.ts.kg/serials/ on android. Tried to do it with htmlcleaner, but it didnot work. Trying to do it with jsoup. In the begining was my code to complex. Here is the shortest code. The same thing works on java Please help. My Logs http://smartpics.kz/imgs/1361209668WW5O.JPG
Here is my class:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] names= {};
String url = "http://www.ts.kg/mults/";
try {
Document doc = Jsoup.connect(url).get();
Element e = doc.body();
Elements ggg = e.getElementsByAttributeValue("class", "categoryblocks");
for (int i =0;i<ggg.size();i++) {
Element linkk = ggg.get(i);
if(linkk.getElementsByTag("a")!=null){
Element atom = linkk.getElementsByTag("a").first();
String n = atom.getElementsByTag("span").first().text();
names[i] = n;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ListView lvMain = (ListView) findViewById(R.id.listViewData);
// создаем адаптер
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names);
// присваиваем адаптер списку
lvMain.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.activity_main, menu);
return true;
}
}
posted 20.feb.2013:
tryed to do it as it was proposed by Shoshy (thanks for your answer), but it didn't work (perhaps because of my not-from-right-place-growing hands). Here is my modified code:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
url = "http://www.ts.kg/mults/";
pd = ProgressDialog.show(MainActivity.this, "Working...", "request to server", true, false);
//Запускаем парсинг
new AsyncExecution().execute();
}
private ProgressDialog pd;
String url;;
String names[];
private class AsyncExecution extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// here your task will be done in seperate thread from UI thread
// and if you want to use the variables (that will be modifed here)
// from anywhere in MainActivity, then you should declare them as global
// variable in MainActivity. remember you cannot update UI from here , like
// Toast message. if you want to do that you can use OnPostExecute
// method bellow .
try {
ArrayList<String> array = new ArrayList<String>();
Document doc = Jsoup.connect(url).get();
Element e = doc.body();
Elements ggg = e.getElementsByAttributeValue("class", "categoryblocks");
for (int i =0;i<ggg.size();i++) {
Element linkk = ggg.get(i);
if(linkk.getElementsByTag("a")!=null){
Element atom = linkk.getElementsByTag("a").first();
String n = atom.getElementsByTag("span").first().text();
array.add(n);
}
}
for (int i = 0;i<array.size();i++){
names[i]=array.get(i);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
//Убираем диалог загрузки
pd.dismiss();
//Находим ListView
ListView listview = (ListView) findViewById(R.id.listViewData);
//Загружаем в него результат работы doInBackground
listview.setAdapter(new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1, names));
}
}
}
you have to make the request for getting the page in another thread from UI thread. you can use AsyncTask. i am giving some example by editing your code :
the link about AsyncTask is : about AsynckTask
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//the class is defined bellow
new AsyncExecution().execute();
//other codes.....
.......................
}
/// your other codes .....
// you need to add this class
private class AsyncExecution extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
// here your task will be done in seperate thread from UI thread
// and if you want to use the variables (that will be modifed here)
// from anywhere in MainActivity, then you should declare them as global
// variable in MainActivity. remember you cannot update UI from here , like
// Toast message. if you want to do that you can use OnPostExecute
// method bellow .
try {
Document doc = Jsoup.connect(url).get();
Element e = doc.body();
Elements ggg = e.getElementsByAttributeValue("class", "categoryblocks");
for (int i =0;i<ggg.size();i++) {
Element linkk = ggg.get(i);
if(linkk.getElementsByTag("a")!=null){
Element atom = linkk.getElementsByTag("a").first();
String n = atom.getElementsByTag("span").first().text();
names[i] = n;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onPostExecute(Void result) {
}
}

notifyDataSetChanged not working in android

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>

Categories

Resources