I have recently developed an android app, which is parsing the xml links, whenever i use the app it responds very slowly, because each time i open the app and navigate the pages on the app, it parse it then give the data,
is there any way so that i could speed up the app, i have searched for it on google, but have not got any idea, it stated to use the volley library, but no result as i am unable to use that,
plz help guys if anyone has any option , is there any way that i could parse the link and store it into the cache and then retrive from there..
package com.stepupup.pm;
import info.stepupup.tabswipe.R;
import java.util.ArrayList;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
public class Cricket extends ListFragment {
static final String URL = "http://www.statenewsonline.com/category/sports/cricket/feed";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_NAME = "title";
static final String KEY_COST = "link";
static final String KEY_DESC = "content:encoded";
static final String KEY_PUB = "pubDate";
Context context;
Typeface font;
String nam,cost,desc,ti,cdesc,lnk1;
TextView t1;;
TextView t2,t3,t5,t15;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.cricket, container, false);
font=Typeface.createFromAsset(getActivity().getAssets(), "DroidHindi.ttf");
return rootView;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_NAME, (parser.getValue(e, KEY_NAME)));
map.put(KEY_COST, parser.getValue(e, KEY_COST));
map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
map.put(KEY_PUB, parser.getValue(e, KEY_PUB));
// map.put(KEY_CDESC, parser.getValue(e, KEY_CDESC));
// adding HashList to ArrayList
menuItems.add(map);
}
ListAdapter adapter = new SimpleAdapter(getActivity(), menuItems,
R.layout.list_item,
new String[] { KEY_NAME, KEY_DESC,KEY_COST}, new int[] {
R.id.name1, R.id.description, R.id.link1}){
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewGroup view = (ViewGroup) super.getView(position, convertView, parent);
if(convertView == null) Cricket.setAppFont(view, font);
t1=(TextView)view.findViewById(R.id.name1);
t1.setTypeface(font);
t2=((TextView)view.findViewById(R.id.description));
t2.setTypeface(font);
t15=(TextView)view.findViewById(R.id.link1);
t15.setTypeface(font);
return view;
}
};
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
t1=(TextView)view.findViewById(R.id.name1);
nam=t1.getText().toString();
t2=((TextView)view.findViewById(R.id.description));
desc = t2.getText().toString();
t15=(TextView)view.findViewById(R.id.link1);
lnk1=t15.getText().toString();
// cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
ti = ((TextView) view.findViewById(R.id.time)).getText().toString();
// Starting new intent
Intent in = new Intent(getActivity(), SingleMenuItemActivity.class);
in.putExtra(KEY_NAME, nam);
in.putExtra(KEY_COST, lnk1);
in.putExtra(KEY_DESC, desc);
in.putExtra(KEY_PUB, ti);
startActivity(in);
}
});
}
protected static void setAppFont(ViewGroup view, Typeface font2) {
// TODO Auto-generated method stub
}
}
and the folllwing is my xml file..
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff" >
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
Android Documentation says,
We recommend XmlPullParser, which is an efficient and maintainable way
to parse XML on Android. Historically Android has had two
implementations of this interface:
KXmlParser via XmlPullParserFactory.newPullParser().
ExpatPullParser, via Xml.newPullParser().
You can find a good example in that page. Don't forget to use Async task and do that network related stuff in background. Good luck!
One obvious problem with your code is that you do network request on the UI thread, here:
public void onActivityCreated(Bundle savedInstanceState) {
...
String xml = parser.getXmlFromUrl(URL); // getting XML
...
}
I don't know where XMLParser is coming from, but, just from the method's name, it is downloading something from the network. You should never do such things on the UI thread. Instead, this should be done on the background thread, and the results should be delivered on the UI thread.
Now which exactly mechanism to use for that is up to you. There are lots of options, with different advantages and trade-offs. AsyncTask mechanism was already mentioned, and it indeed might be an appropriate solution (but not always). Other possibilities are RxJava, RoboSpice, Guava's ListenableFutures, etc.
Related
I am making a listview, which shows data from a server. I get no errors in LogCat, but my ListView doesn't appear. This is my code:
package com.imptmd.charliemacdonald.desleutelaar;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
public class SlotenFragment extends ListFragment {
private ProgressDialog nDialog;
// URL to get contacts JSON
private static String url = "http://charlenemacdonald.com/sloten.json";
// JSON Node names
private static final String TAG_SLOTEN = "slotenlijst";
private static final String TAG_SLOT = "Slot";
// contacts JSONArray
JSONArray sloten= null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> slotenLijst;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_sloten, container, false);
slotenLijst = new ArrayList<HashMap<String, String>>();
ListView lv = (ListView) rootView.findViewById(android.R.id.list);
// Listview on item click listener
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String Slot = ((TextView) rootView.findViewById(R.id.textviewslotnaam))
.getText().toString();
// Starting single contact activity
Intent in = new Intent(getActivity().getApplicationContext(),
SlotInfoScherm1.class);
in.putExtra(TAG_SLOT, Slot);
startActivity(in);
}
});
new GetSloten().execute();
// Calling async task to get json
return rootView;
}
/**
* Async task class to get json by making HTTP call
* */
private class GetSloten extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
nDialog = new ProgressDialog(getActivity());
nDialog.setMessage("Even geduld a.u.b., studenten worden geladen...");
nDialog.setCancelable(false);
nDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
sloten = jsonObj.getJSONArray(TAG_SLOTEN);
// looping through All Contacts
for (int i = 0; i < sloten.length(); i++) {
JSONObject c = sloten.getJSONObject(i);
String Slot = c.getString(TAG_SLOT);
// tmp hashmap for single contact
HashMap<String, String> sloten = new HashMap<String, String>();
// adding each child node to HashMap key => value
sloten.put(TAG_SLOT, Slot);
// adding contact to contact list
slotenLijst.add(sloten);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (nDialog.isShowing())
nDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(getActivity(), slotenLijst,
R.layout.sloten_info, new String[] { TAG_SLOT}, new int[] { R.id.textviewslotnaam});
setListAdapter(adapter);
}
}
}
The INTERNET permission is already added in the Manifest, just as WRITE EXTERNAL STORAGE and INTERNAL STORAGE. I get no errors in LogCat. The only error I get is in the ADB 'ADB rejected connection to client'. Is that why my ListView doesn't appear? Thanks in advance.
Hi can you update you code and test the below logic what you received.
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (nDialog.isShowing())
nDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
Log.d("DataSize: ",""+slotenLijst.size());
ListAdapter adapter = new SimpleAdapter(getActivity(), slotenLijst,
R.layout.sloten_info, new String[] { TAG_SLOT}, new int[] { R.id.textviewslotnaam});
setListAdapter(adapter);
}
Let us know what you get in log cat "DataSize".
Change your onCreateView(...) to be:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_sloten, container, false);
slotenLijst = new ArrayList<HashMap<String, String>>();
ListView lv = (ListView) rootView.findViewById(android.R.id.list);
new GetSloten().execute();
// Calling async task to get json
return rootView;
}
// ListFragment implement this in default
#Override
public void onListItemClick(ListView l, View v, int position, long id)
{
//getting values from selected ListItem
String Slot = ((TextView) rootView.findViewById(R.id.textviewslotnaam))
.getText().toString();
// Starting single contact activity
Intent in = new Intent(getActivity().getApplicationContext(),
SlotInfoScherm1.class);
in.putExtra(TAG_SLOT, Slot);
startActivity(in);
}
});
and your fragment layout fragment_sloten could be like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false"/>
... ...
</LinearLayout>
Hope this help!
I have a custom list adapter that reads in data from a xml file that is hosted online, each one is for a different article. My question is how do I make each list item open a different corresponding article? The articles will be hosted online.
Thank you in advance.
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.HashMap;
public class CustomizedListView extends Fragment { // All static variables
// XML node keys
static final String KEY_SONG = "song"; // parent node
static final String KEY_ID = "id";
static final String KEY_ARTIST = "artist";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";
ListView list;
LazyAdapter adapter;
ArrayList<HashMap<String, String>> songsList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.news, container, false);
songsList = new ArrayList<HashMap<String, String>>();
list=(ListView) rootView.findViewById(R.id.list);
new RetrieveXML().execute(URL);
// Getting adapter by passing xml data ArrayList
// Click event for single list row XMLParser parser = new XMLParser();
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
return rootView;
}
class RetrieveXML extends AsyncTask<String, Void, String> {
private Exception exception;
XMLParser parser = new XMLParser();
protected String doInBackground(String... urls) {
try {
return parser.getXmlFromUrl(urls[0]);
} catch (Exception e) {
this.exception = e;
return null;
}
}
protected void onPostExecute(String xml) {
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_SONG);
// looping through all song nodes <song>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
map.put(KEY_THUMB_URL, parser.getValue(e, KEY_ID));
map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));
// adding HashList to ArrayList
songsList.add(map);
}
adapter=new LazyAdapter(getActivity(), songsList);
list.setAdapter(adapter);
}
}
}
You have implemented:
onItemClick()
In this you get the position of item in the list as parameter. here you can write a switch case to accomplish your task. This function gets triggered when any listitem is clicked.
Something like this you can do:
private string[] mArticles={
"abc",
"def",
"ghi",
"jkl"
};
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
openArticle(mArticles[position]);
}
While creating the string array keep appropriate artile link for each item position.
I've been attempting to create a ListView in a fragment that gets data from a server, but so far have been unsuccessful. I've been using the following site: Vogella for learning on how to implement ListView in a fragment, but I am having difficulties when trying to populate data from a server.
package com.example.ips_alpha;
import java.util.ArrayList;
import java.util.HashMap;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TableLayout;
public class Gold_Visitors2 extends ListFragment{
//JSON Node names (level, sensorID, value)
String SPACES = "spaces"; //String array name of php
String LEVEL = "level";
String SENSORID = "sensorID";
String VALUE = "value";
//pspace JSONArray
JSONArray pspace = null;
String[] levels = new String[]{LEVEL, SENSORID, VALUE};
int [] ids = new int[]{};
private static String url = "http://www.example.com/getUsers12.php";
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = inflater.inflate(R.layout.fragment_gold_visitors, null);
new MyAsyncTask().execute();
return view;
}
class MyAsyncTask extends AsyncTask<String, Integer, ArrayList<HashMap<String, String>> > {
//Hashmap for ListView
ArrayList<HashMap<String, String>> levelList = new ArrayList<HashMap<String, String>>();
#Override
protected ArrayList<HashMap<String, String>>doInBackground(String... params) {
//Creating JSON Parser instance
JSONParser jParser = new JSONParser();
//getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
//Getting Array of spaces
pspace = json.getJSONArray(SPACES);
//looping through all spaces
for(int i = 0; i < pspace.length(); i++){
JSONObject p = pspace.getJSONObject(i);
//Storing each json item in variable
String level = p.getString(LEVEL);
String sensorID = p.getString(SENSORID);
String value = p.getString(VALUE);
//creating new HashMap
HashMap<String, String> map = new HashMap <String, String>();
//adding each child node to HashMap Key =>
map.put(LEVEL, level);
map.put(SENSORID, sensorID);
map.put(VALUE, value);
//adding HashList to ArrayList
}
}catch(JSONException e){
e.printStackTrace();
}
return levelList;
}
#Override
protected void onPostExecute(ArrayList<HashMap<String, String>> levelList) {
ListAdapter adapter = new SimpleAdapter(getActivity(), levelList, R.layout.fragment_gold_visitors, levels, ids);
setListAdapter(adapter);
}
}
}
The following is the layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
Currently my app is compiling and does not crash, but when accessing the fragment that is supposed to display the ListView, it's blank. I believe I'm messing up in the ASyncTask and the adapter, any help would greatly be appreciated.
You return levelList in doInBackground, but you never added any items to it from the retrieved JSON. All you have is an empty ArrayList, so the ListView is empty.
Long story short im trying to add the clickable functionality from the top half of the code below to the custom adapter below.
I found this tut(modified version of the source in the top part of the code below-currently not working):
http://wiresareobsolete.com/wordpress/2011/08/clickable-zones-in-listview-items/
but, my entire project uses the custom adapter from this tut(custom adapter at the bottom of the code below):
http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
All I would like to do is maintain my ability to use my existing data structure(ArrayList w. hash maps ) via a listview that will allow me to click on
*The thumbnail imageview
*The bold title text(in the image its the textview that reads "someone like you"
*the list row ( all the area besides the imageview & textview)
I would prefer to keep my custom adapter from the second link and just add the functionality from the first link, but if that complicates things im cool with suggestions to anything that allows me to plug in my existing data set ( Arraylist>) while providing the described functionality.
import java.util.ArrayList;
import java.util.HashMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class MyActivity extends Activity implements AdapterView.OnItemClickListener, View.OnClickListener
{
// All static variables
// XML node keys
static final String KEY_FEED = "feed";
// parent node
static final String KEY_UID_FK = "uid_fk";
static final String KEY_FIRST_NAME = "first_name";
static final String KEY_LAST_NAME = "last_name";
static final String KEY_NAME = "name";
static final String KEY_MESSAGE = "message";
static final String KEY_CREATED = "created";
static final String KEY_THUMB_URL = "thumb_img";
private static final String TAG = "MyApp";
ListView list;
LazyAdapter adapter;
JSONArray feed = null;
Button add;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView list = new ListView(this);
setContentView(list);
ArrayList<HashMap<String, String>> feedList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(URL);
try {
// Getting Array of Contacts
feed = json.getJSONArray(KEY_FEED);
// looping through All Contacts
for(int i = 0; i < feed.length(); i++){
JSONObject c = feed.getJSONObject(i);
// Storing each json item in variable
String uid = c.getString(KEY_UID_FK);
String first_name = c.getString(KEY_FIRST_NAME);
String last_name = c.getString(KEY_LAST_NAME);
String name = first_name + last_name;
String http = "http://10.0.2.2/CI_BUHZ/IMGS/";
String base_url = c.getString(KEY_THUMB_URL);
String thumb_url = http + base_url;
String message = c.getString(KEY_MESSAGE);
String created = c.getString(KEY_CREATED);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(KEY_UID_FK, uid);
map.put(KEY_NAME, name);
map.put(KEY_MESSAGE, message);
map.put(KEY_CREATED, created);
map.put(KEY_THUMB_URL, thumb_url);
// adding HashList to ArrayList
feedList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
Log.i(TAG, "I am logging something informational!");
//Supply this adapter with either R.layout.row_button, R.layout.row_view, or R.layout.row_view_noparent
ArrayAdapter<HashMap<String, String>> adapter = new ArrayAdapter<HashMap<String,String>>(this, R.layout.row_view,
feedList) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
View left = row.findViewById(R.id.left);
left.setTag(position);
left.setOnClickListener(MyActivity.this);
View text = row.findViewById(R.id.text);
text.setTag(position);
text.setOnClickListener(MyActivity.this);
return row;
}
};
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.left:
Toast.makeText(this, "Left Accessory "+v.getTag(), Toast.LENGTH_SHORT).show();
break;
case R.id.text:
Toast.makeText(this, "text Accessory "+v.getTag(), Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(this, "Item Click "+position, Toast.LENGTH_SHORT).show();
} }
//previously I was using this custom adapter that extends base adapter:
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
TextView name = (TextView)vi.findViewById(R.id.name); // title
TextView message = (TextView)vi.findViewById(R.id.message); // artist name
TextView created = (TextView)vi.findViewById(R.id.created); // duration
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
// Setting all values in listview
name.setText(update.get("name"));
message.setText(update.get("message"));
created.setText(update.get("created"));
imageLoader.DisplayImage(update.get("thumb_url"), thumb_image);
return vi;
}
}
from this tutorial : http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
Ruware was nice enough to do a Google Hangout with me to help me solve my problem. Extremely embarrassed I couldn't manage to figure this out myself:
Step 1. Import dl the project from link 2 in my original description & import it into Eclipse.
Step 2. LazyAdapter Class w. Clickable Imageview & Textview - Simply replace the lazy adapter from link 2 in my original description with the code below:
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
TextView name = (TextView)vi.findViewById(R.id.name); // title
TextView message = (TextView)vi.findViewById(R.id.message); // artist name
TextView created = (TextView)vi.findViewById(R.id.created); // duration
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
// Setting all values in listview
name.setText(update.get("name"));
message.setText(update.get("message"));
name.setOnClickListener(new myOnClickListener(position));
created.setText(update.get("created"));
imageLoader.DisplayImage(update.get("thumb_url"), thumb_image);
thumb_image.setOnClickListener(new myOnClickListener(position));
return vi;
}
public class myOnClickListener implements OnClickListener{
private int position;
public myOnClickListener(int position){
this.position=position;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
HashMap<String, String> update = new HashMap<String, String>();
update = data.get(position);
Log.d("Testing Click", update.get("message"));
}
}
}
Step 3. list_row.xml - Replace the list_row layout w. the XML below:
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip">
android:layout_width="50dip"
android:layout_height="50dip"
android:src="#drawable/default_thumb"/>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:text="Chuck Kelly"
android:textColor="#040404"
android:typeface="sans"
android:textSize="15dip"
android:textStyle="bold"/>
<TextView
android:id="#+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/name"
android:textColor="#343434"
android:textSize="10dip"
android:layout_marginTop="1dip"
android:layout_toRightOf="#+id/thumbnail"
android:text="This is a status Update" />
<TextView
android:id="#+id/created"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/message"
android:layout_below="#+id/message"
android:layout_marginRight="5dip"
android:text="5:45"
android:textColor="#10bcc9"
android:textSize="10dip"
android:textStyle="bold" />
<ImageView
android:id="#+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="#drawable/closeicon"
android:visibility="invisible" />
You now have a listview w. click-able views in each row that also allows you to set the value of multiple views in each row similar to many of the popular social networks ( facebook , twitter , path ) Thanks again to Ruware for taking the time to help me with this.
If you set your parts of row as focusable (android:focusable="true") (default) than OnItemClickListener for ListView does not respond.
Try setting them all to false
I am trying to create a tab using fragments which will display a list of entries after parsing a xml page. But I am unable to extend listactivity int the tab class as it already extends fragments.I have tried implementing listfragments but it is giving me an error on ListAdapter adapter = new SimpleAdapter saying "The constructor SimpleAdapter(Protab1, ArrayList>, int, String[], int[]) is undefined".Could you please help me out.
package com.example.pro1;
import java.util.ArrayList;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SimpleAdapter;
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Protab1 extends ListFragment {
// All static variables
static final String URL = "http://api.androidhive.info/pizza/?format=xml";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_ID = "id";
static final String KEY_NAME = "name";
static final String KEY_COST = "cost";
static final String KEY_DESC = "description";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.protab1, container, false);
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
// looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// adding each child node to HashMap key => value
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
// adding HashList to ArrayList
menuItems.add(map);
}
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(this, menuItems,
R.layout.list_item,
new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
R.id.name, R.id.desciption, R.id.cost });
setListAdapter(adapter);
}
}
Try using this.getActivity() instead of this as first parameter of the SimpleAdapter. The first parameter takes a Context object, but since a ListFragment (or any Fragment) does not extend Context, it will not work.