Improving performance on Custom ArrayAdapters and Objects - android

I have been trying to learn how to make custom ArrayAdapters to use in some of my Android apps by using this tutorial, but adapting it slightly so that I could fit it with my own application.
I've tested it a couple times now on my phone, but I've found the performance speed to be incredibly slow (when loading and scrolling through the listview). The other activities which do not use this custom ArrayAdapter have a normal performance speed.
I'm not really sure what the problem could be or where in my code it would be, so below, I've posted all of my custom ArrayAdapter class:
package com.mycompany.myapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomArrayAdapter extends ArrayAdapter<String> {
private static class ViewHolder {
TextView tv_Id;
TextView tv_Name;
TextView tv_Group;
}
private Context context;
private ArrayList<String> arr_items;
public CustomArrayAdapter(Context context, ArrayList<String> arr_items) {
super(context, R.layout.listview_advanced, arr_items);
this.context = context;
this.arr_items = arr_items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Person person = new Person(context, arr_items.get(position));
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // View lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.listview_advanced, parent, false);
viewHolder.tv_Id = (TextView) convertView.findViewById(R.id.lvAdv_text1);
viewHolder.tv_Name = (TextView) convertView.findViewById(R.id.lvAdv_text2);
viewHolder.tv_Group = (TextView) convertView.findViewById(R.id.lvAdv_text3);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
viewHolder.tv_Id.setText(person.getIDAsString());
viewHolder.tv_Name.setText(person.getName());
if (person.getGroup().equals("")) {
viewHolder.tv_Group.setText("");
} else {
viewHolder.tv_Group.setText("(" + person.getGroup() + ")");
}
// Return the completed view to render on screen
return convertView;
}
}
Any help would be much appreciated. Thanks.
UPDATE:
Also, before calling the CustomArrayAdapter, I add data to an ArrayList<String> by going through rows of a .csv file and getting that data. At the moment, when reading the .csv file, I have this:
...
ArrayList<String> arr_person = new ArrayList<>(); // Global variable
...
// In a method:
String data = inputStream.nextLine();
String[] line = data.split(",");
if (line.length >1) {
arr_person.add(line[1]);
}
...
CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(), arr_person);
lv_main.setAdapter(adapter);
How would I adapt this for objects?
UPDATE 2:
My Person object works like this:
private Context context;
private String person, group, someAttribute, ... ;
private int idNumber, scoreOne, scoreTwo, scoreThree, scoreFour, scoreFive, scoreSix, scoreTotal, ... ;
private double ... ;
public Person(Context context, String person) {
this.context = context;
this.person = person;
loadInformation();
}
private void loadInformation() {
InputStreamReader inputStreamReader;
try {
inputStreamReader = new InputStreamReader(context.getAssets().open("PersonsList.csv"));
Scanner inputStream = new Scanner(inputStreamReader);
inputStream.nextLine(); // Ignores the first line
while (inputStream.hasNext()) {
String data = inputStream.nextLine(); // Gets a whole line
String[] line = data.split(","); // Splits the line up into a string array
if (line.length > 1) {
if (line[1].equals(person)) {
idNumber = Integer.parseInt(line[0]);
person = line[1];
group = line[2];
someAttribute = line[3];
scoreOne = Integer.parseInt(line[4]);
scoreTwo = Integer.parseInt(line[5]);
scoreThree = Integer.parseInt(line[6]);
scoreFour= Integer.parseInt(line[7]);
scoreFive = Integer.parseInt(line[8]);
scoreSix = Integer.parseInt(line[9]);
scoreTotal = scoreOne + scoreTwo + scoreThree + scoreFour + scoreFive + scoreSix;
// Same code pattern for defining about 10 more attributes
}
}
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public int getID() {
return idNumber;
}
public String getIDAsString() {
return format(idNumber);
}
private String format(int number) {
String str_num = String.valueOf(number);
switch (str_num.length()) {
case 1:
str_num = "00" + str_num;
break;
case 2:
str_num = "0" + str_num;
break;
case 3:
// Leave it how it is;
break;
}
return str_num;
}
public String getName() {
return person;
}
public String getGroup() {
return group;
}
public String getSomeAttribute() {
return someAttribute;
}
public int getScoreOne() {
return scoreOne;
}
public int getScoreTwo() {
return scoreTwo;
}
...

Base your array and ArrayAdapter on Person instead of String and make a list of Persons before you set up the adapter. This way you only run the Person constructor once instead of every time you display its view.
ArrayList<Person> arr_person = new ArrayList<>(); // Global variable
...
String data = inputStream.nextLine();
String[] line = data.split(",");
if (line.length > 1) {
Person person = new Person(context, line[1]);
arr_person.add(person);
}
...
CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(), arr_person);
lv_main.setAdapter(adapter);
...
package com.mycompany.myapp;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomArrayAdapter extends ArrayAdapter<Person> {
private static class ViewHolder {
TextView tv_Id;
TextView tv_Name;
TextView tv_Group;
}
private Context context;
private ArrayList<Person> persons;
public CustomArrayAdapter(Context context, ArrayList<Person> persons) {
super(context, R.layout.listview_advanced, arr_items);
this.context = context;
this.persons = persons;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Person person = persons.get(position);
// Check if an existing view is being reused, otherwise inflate the view
ViewHolder viewHolder; // View lookup cache stored in tag
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.listview_advanced, parent, false);
viewHolder.tv_Id = (TextView) convertView.findViewById(R.id.lvAdv_text1);
viewHolder.tv_Name = (TextView) convertView.findViewById(R.id.lvAdv_text2);
viewHolder.tv_Group = (TextView) convertView.findViewById(R.id.lvAdv_text3);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// Populate the data into the template view using the data object
viewHolder.tv_Id.setText(person.getIDAsString());
viewHolder.tv_Name.setText(person.getName());
if (person.getGroup().equals("")) {
viewHolder.tv_Group.setText("");
} else {
viewHolder.tv_Group.setText("(" + person.getGroup() + ")");
}
// Return the completed view to render on screen
return convertView;
}
}

Related

List view with custom Layout

I have created a list with a custom row but I do not know what's wrong.
This is the main activity
package com.example.fahdmana.lest;
public class MainActivity extends AppCompatActivity{
ListView listView;
final int[] movie_poster_resouce = {
R.drawable.apple,
R.drawable.banana,
R.drawable.cherry,
R.drawable.mango,
R.drawable.orange,
R.drawable.strawberry,
R.drawable.tomato
};
String[]movies_title;
String[]movies_rating;
MovieAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView)findViewById(R.id.List1);
movies_title = getResources().getStringArray(R.array.Movies_names);
movies_rating = getResources().getStringArray(R.array.Ratings);
int i =0;
for (String titles : movies_title){
MovieDataProvider dataProvider =
new MovieDataProvider(movie_poster_resouce[i],titles,movies_rating[i]);
i++;
adapter = new MovieAdapter(getApplicationContext(),R.layout.row);
listView.setAdapter(adapter);
adapter.add(dataProvider);
}
}
}
And this is my adapter
package com.example.fahdmana.lest;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MovieAdapter extends ArrayAdapter {
final List list = new ArrayList();
public MovieAdapter( Context context, int resource) {
super(context, resource);
}
static class DataHandeler{
ImageView poster;
TextView title;
TextView rating;
}
#Nullable #Override
public void add( Object object) {
super.add(object);
list.add(object);
}
#Nullable #Override
public int getCount() {
return list.size();
}
#Nullable #Override
public Object getItem(int position) {
return this.list.get(position);
}
#Nullable #Override
public View getView (int position,
#NonNull View convertView,
#NonNull ViewGroup parent) {
View row;
row = convertView;
DataHandeler handler;
if (convertView ==null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.row, parent, false);
handler = new DataHandeler();
handler.poster = (ImageView) row.findViewById(R.id.image_view);
handler.title = (TextView) row.findViewById(R.id.movie_title);
handler.rating = (TextView) row.findViewById(R.id.movie_rating);
row.setTag(handler);
} else {
handler = (DataHandeler) row.getTag();
}
MovieDataProvider dataProvider;
dataProvider = (MovieDataProvider)this.getItem(position);
handler.poster.setImageResource(dataProvider.
getMovie_poster_resource());
//here i get some warning
handler.title.setText(dataProvider.getMovie_title());
handler.rating.setText(dataProvider.getMovie_rating());
return row;
}
}
And this is my data provider
package com.example.fahdmana.lest;
public class MovieDataProvider {
private int movie_poster_resource;
private String movie_title;
private String movie_rating;
public MovieDataProvider(int movie_poster_resource, String movie_title, String movie_rating){
this.setMovie_poster_resource(movie_poster_resource);
this.setMovie_title(movie_title);
this.setMovie_rating(movie_rating);
}
public int getMovie_poster_resource() {
return movie_poster_resource;
}
public void setMovie_poster_resource(int movie_poster_resource) {
this.movie_poster_resource = movie_poster_resource;
}
public String getMovie_title() {
return movie_title;
}
public void setMovie_title(String movie_title) {
this.movie_title = movie_title;
}
public String getMovie_rating() {
return movie_rating;
}
public void setMovie_rating(String movie_rating) {
this.movie_rating = movie_rating;
}
}
I am pretty sure this is your problem.
for (String titles : movies_title){
MovieDataProvider dataProvider =
new MovieDataProvider(movie_poster_resouce[i],titles,movies_rating[i]);
i++;
adapter = new MovieAdapter(getApplicationContext(),R.layout.row);
listView.setAdapter(adapter);
adapter.add(dataProvider);
}
You have this in your main activity. You really dont want to loop through your list and inside of that loop call your adapter.
You want to create a list of your objects and then call the adapter .... something like this...
ListViewAdapterResults adapter = new ListViewAdapterResults(listView.getContext(), scheduleModelList);
listView.setAdapter(adapter);
Where scheduleModelList is my list of objects. Hopefully that makes sense.
Happy coding.
Looking through your code, you may want to do something like this....
Put this at the top
List<MovieDataProvider> list;
Then this right after your setContentView
list = new ArrayList<>();
Replace that loop you have with this:
for (int i = 0; i < movie_title.length; i++) {
list.add(new MovieDataProvider(movie_poster_resouce[i],titles,movies_rating[i]));
}
MovieAdapter adapter = new MovieAdapter(listView.getContext(), list);
listView.setAdapter(adapter);
Let me know if you have any questions.
MovieAdapter (this is your adapter class)
listView.getContext() (this is the ID of your listview [you may have it named something else])
It's been a very long time since I have worked with Arrays.... you have have to +1 or -1 inside of the for loop. (i < movie_title.length [maybe +1 or -1])

ListView : List Item are repeating on scroll

I have a ListView in which i am showing some data. I am requesting the data from the server which is in the form of JSON. Also, the data is paginated.
When the API is called for the first time it is loading n items.
I have implemented the logic that after the list end is reached API would be call again to fetch n more data.
API Calls are working fine as I have seen the result in the Logcat.
The Issue is the ListView is not updating properly on scroll after the API has been called for the second time.
Eg: Suppose I am calling API to fetch 7 items at a time. Then in the ListView i would see something like this:
Item1
Item2
..
Item7
Item1
Item2
....
JsonObjectRequest jo = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
pDialog.dismiss();
pDialog = null;
try {
JSONArray ja = jsonObject.getJSONArray("resultset"); // id, title, content, guid
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = ja.getJSONObject(i);
SearchListItem ri = new SearchListItem();
ri.setId(jo.getInt("id"));
ri.setTitle(jo.getString("title"));
ri.setContent(jo.getString("content"));
listy.add(ri);
}
} catch (JSONException ex) {
Toast.makeText(getApplicationContext(), "json ex" + ex.getMessage(), Toast.LENGTH_SHORT).show();
ex.printStackTrace();
}
searchAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
pDialog.dismiss();
pDialog = null;
Log.d(TAG, "!!!! ERROR " + volleyError.getMessage());
}
});
//Toast.makeText(ListActivity.this, jo.toString().toCharArray(), Toast.LENGTH_SHORT).show();
AppController.getInstance().addToRequestQueue(jo);
//Adapter
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.TextView;
import android.widget.Toast;
import com.o.R;
import com.o.SearchListItem;
import java.util.List;
public class SearchListAdapter extends BaseAdapter {
Context context;
List<SearchListItem> items;
//ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public SearchListAdapter(Context context, List<SearchListItem> items)
{
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return items.indexOf(getItem(position));
}
class ViewHolder
{
TextView txtTitle;
TextView txtContent;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);// creates the objects of all views
if(convertView == null)
{
convertView = inflater.inflate(R.layout.style_row, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtAbout);
holder.txtContent = (TextView) convertView.findViewById(R.id.txtDetail);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
try {
SearchListItem rowItem = (SearchListItem) getItem(position);
holder.txtTitle.setText(rowItem.getTitle());
holder.txtContent.setText(rowItem.getContent().substring(0,20));
}
catch (Exception e){
//Toast.makeText(SearchListAdapter.this,e.printStackTrace(),Toast.LENGTH_SHORT).show();
}
return convertView;
}
}
You have not set the tag on the view , do convertview.setTag(holder) ...
if(convertView == null)
{
convertView = inflater.inflate(R.layout.style_row, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.txtAbout);
holder.txtContent = (TextView) convertView.findViewById(R.id.txtDetail);
convertView.setTag(holder)
}
Your code seems fine , problem might be that you are requesting multiple times from your code on the server and ArrayList listy getting filled multiple times in the onResponse method of jsonRequest or your server might be returning multiple entries , seems nothing wrong with the posted code.

error in ListView with image

I'm trying to build a ListView in android, where each item of ListView is composed for one ImgeView and 4 TexView. The getView of my class extended BaseAdapter is defined as follows:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
ViewHolder holder;
if(vi == null) {
LayoutInflater inflater = (LayoutInflater) Activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
vi = inflater.inflate(R.layout.item_lista_restaurantes, null);
holder = new ViewHolder();
holder.nombreRestaurante= (TextView) vi.findViewById(R.id.etiquetaNombreResItemRes);
holder.direccionRestaurante = (TextView) vi.findViewById(R.id.etiquetaDireccionResItemRes);
holder.ciudadRestaurante = (TextView) vi.findViewById(R.id.etiquetaCiudadResItemRes);
holder.telefonoRestaurante = (TextView) vi.findViewById(R.id.etiquetaTelResItemRes);
holder.lineaLogo = (TextView) vi.findViewById(R.id.etiquetaLineaLogo);
vi.setTag(holder);
}
else
{
holder = (ViewHolder)vi.getTag();
}
itemRestaurante item= this.itemR.get(position);
ImageView image = (ImageView) vi.findViewById(R.id.imageLogoItemRestaurante);
int imageResource = this.Activity.getResources().getIdentifier(item.getRutaImaLogo(), null, this.Activity.getPackageName());
image.setImageDrawable(this.Activity.getResources().getDrawable(imageResource));
holder.nombreRestaurante.setText(item.getNombreR());
holder.direccionRestaurante.setText(item.getDireccionR());
holder.ciudadRestaurante.setText(item.getCiudadR());
holder.telefonoRestaurante.setText(item.getTelR());
holder.lineaLogo.setText(item.getDireccionR());
return vi;
}
the code line on getView:
ImageView image = (ImageView) vi.findViewById(R.id.imageLogoItemRestaurante);
int imageResource = this.Activity.getResources().getIdentifier(item.getRutaImaLogo(), null, this.Activity.getPackageName());
image.setImageDrawable(this.Activity.getResources().getDrawable(imageResource));
this is the itemRestaurantes class where i return the rutaImagenLogo value
package clasesExtras;
public class itemRestaurante {
private long idRestaurante;
private String nombreRestaurante;
private String direccionRestaurante;
private String ciudadRestaurante;
private String telefonoRestaurante;
private String rutaImagenLogo;
//private String rutaImagenGo;
//private String rutaImagenLineaLogo;
/*Constructor*/
public itemRestaurante(long id, String nombre, String direccion, String ciudad,
String telefono, String rutaLogo){
this.idRestaurante= id;
this.nombreRestaurante= nombre;
this.direccionRestaurante= direccion;
this.ciudadRestaurante= ciudad;
this.telefonoRestaurante= telefono;
this.rutaImagenLogo= rutaLogo;
//this.rutaImagenGo= rutaGo;
//this.rutaImagenLineaLogo = rutaLineaLogo;
}
public long getId(){
return this.idRestaurante;
}
public void setId(long id){
this.idRestaurante= id;
}
public String getNombreR(){
return this.nombreRestaurante;
}
public void setNombreR(String nombre){
this.nombreRestaurante=nombre;
}
public String getDireccionR(){
return this.direccionRestaurante;
}
public void setDireccionR(String direccion){
this.direccionRestaurante=direccion;
}
public String getCiudadR(){
return this.ciudadRestaurante;
}
public void setCiudadR(String ciudad){
this.ciudadRestaurante= ciudad;
}
public String getTelR(){
return this.telefonoRestaurante;
}
public void setTelR(String telefono){
this.telefonoRestaurante= telefono;
}
public String getRutaImaLogo(){
return this.rutaImagenLogo;
}
public void setRutaImaLogo(String imagenLogo){
this.rutaImagenLogo= imagenLogo;
}
this is the activity class where i fill the ArrayList with the information of each item of ListView
package appetite.apptitud;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;
import clasesExtras.ArrayAdapterRestaurantes;
import clasesExtras.itemRestaurante;
public class ListaRestaurantes extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.lista_restaurantes);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); //forza a android a ocultar el teclado virtual
ListView lista = (ListView)findViewById(R.id.listaRestaurantes);
ArrayList<itemRestaurante> itemRestaurante = obtenerItems();
ArrayAdapterRestaurantes adapter = new ArrayAdapterRestaurantes(this, itemRestaurante);
lista.setAdapter(adapter);
}
//Método para llenar la lista de los restaurantes.
private ArrayList<itemRestaurante> obtenerItems(){
ArrayList<itemRestaurante> items = new ArrayList<itemRestaurante>();
items.add(new itemRestaurante(1, "Frisby", "Cra. 7a 24-74", "Pereira", "3168899", "drawable/frisby_logo"));
items.add(new itemRestaurante(2, "Big Pollo", "Cra. 5a 34-12", "Pereira", "3147152", "drawable/bigpollo"));
items.add(new itemRestaurante(3, "Wingz", "Cra. 8a 18-62", "Pereira", "3391000", "drawale/wingz"));
items.add(new itemRestaurante(4, "Sir Pollo", "Cra. 7a 20-04", "Pereira", "3357913", "drawable/sirpollo"));
return items;
}
the code shown above make reference a the image path where it is stored (drawable folder), and i want to show this image in each item of listview, but this jumps to the following error:
FATAL EXCEPTION: main
android.content.res.Resources$NotFoundException:Resource ID #0x0
at android.content.res.Resources.getValue(Resources.java:1014)
at android.content.res.Resources.getDrawable(Resources.java:659)
at clasesExtras.ArrayAdapterRestaurantes.getView(ArrayAdapterRestaurantes.java:56)
Some people tell me that the imageResource value is 0. And 0 is not a valid resource ID.
how can i do to fix this value?
Help me please, i don't understand it
I think that imageResource is 0. Check this value.
getIdentifier Returns int The associated resource identifier. Returns 0 if no such resource was found. (0 is not a valid resource ID.)
You will have to create a custom adapter for the list View
this would be Restaurant.java
public class Restaurant{
public int icon;
public String someText;
public String moreText;
public String someMoreText;
public String evenMoreText;
public Restaurant(int icon, String someText, String moreText, String somMoreText, String evenMoreText)
super.();
this.someText = someText;
this.moreText = moreText;
this.someMoreText = someMoreText;
this.evenMoreText = evenMoreText;
this.icon = icon;
}
Here is the custom adapter RestaurantAdapter.java
public class RestaurantAdapter extends<Restaurant> }
Context context;
int layoutResourceId;
Restaurant data[] = null;
public RestaurantAdapter(Context context, int layoutResourceId, Restaurant[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
RestaurantHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new RestaurantHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon);
holder.txtID1 = (TextView)row.findViewById(R.id.txtID1);
holder.txtID2 = (TextView)row.findViewById(R.id.txtID2);
holder.txtID3 = (TextView)row.findViewById(R.id.txtID3);
holder.txtID4 = (TextView)row.findViewById(R.id.txtID4);
row.setTag(holder);
}
else
{
holder = (RestauantHolder)row.getTag();
}
Restaurant restaurant = data[position];
holder.txtID1.setText(restaurant.someText);
holder.txtID1.setText(restaurant.moreText);
holder.txtID1.setText(restaurant.someMoreText);
holder.txtID1.setText(restaurant.evenMoreText);
holder.imgIcon.setImageResource(restarant.icon);
return row;
}
}
static class RestaurantHolder
{
ImageView imgIcon;
TextView txtID1;
TextView txtID2;
TextView txtID3;
TextView txtID4;
}
Now in your activity it will be a call like this
Restaurant restaurant_data[] = new Restaurant[]
{
new Restaurant(R.drawable.pic1, "some text", "more text", "some more text". "even more text"),
new Restaurant(R.drawable.pic2, "text", "more", "some more", "blah"),
new Restaurant(R.drawable.pic3, "blah1", "blah2", "blah3" "blah3"),
new Restaurant(R.drawable.pic4, "you get the idea", "blah", "blah", "blah"),
};
RestaurantAdapter adapter = new RestaurantAdapter(this,
R.layout.listview_item_row, restaurant_data);
listView1 = (ListView)findViewById(R.id.listView1);
Credit goes to http://www.ezzylearning.com/tutorial.aspx?tid=1763429
You will just have to change around some of the names.

Android-Listview ClickListener

I have a list in which each object is of type Task. I have created a list that sows all the task details in the row of the list.
My code is given below:
lv=this.getListView();
if(createtaskSubList().size() != 0)
{
//createTaskSubList gives me the List of taskObjects
MyCustomAdapter adapter = new MyCustomAdapter(this,createtaskSubList());
lv.setAdapter(adapter);
lv.setDividerHeight(2);
lv.invalidateViews();
}
}
private ArrayList<Task> createtaskSubList() {
// TODO Auto-generated method stub
ArrayList<Task> taskSubList= new ArrayList<Task>();
String[] values={ Integer.toString(userId),Integer.toString(number),Integer.toString(page)};
String taskList = Helper.getfromUrl(taskDataFetch,values);
if(taskList.length()!=0)
{
String delims = ("[|]");
String[] tasks = taskList.split(delims);
int i=0;
//Splitting Task series into individual items
for (i = 0; i < tasks.length; i++) {
String limit = ("','");
String[] taskItem = tasks[i].split(limit);
taskSubList.add(new Task(taskItem[1],Integer.parseInt(taskItem[2]),Integer.parseInt(removeCharAt(taskItem[0],0)),Integer.parseInt(taskItem[4]),Integer.parseInt(taskItem[5]),taskItem[6],Integer.parseInt(taskItem[3])));
}
}
return taskSubList;
}
Now my arrayadpter class is:
import java.util.ArrayList;
import android.app.Activity;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MyCustomAdapter extends ArrayAdapter<Task> {
private final Activity context;
ArrayList<Task> taskSubList =new ArrayList<Task>();
public MyCustomAdapter(Activity context,ArrayList<Task> taskSubList) {
super(context, R.layout.teammember, taskSubList);
this.context = context;
this.taskSubList=taskSubList;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.teammember, null, true);
final TextView text = (TextView) rowView.findViewById(R.id.label);
final TextView status = (TextView) rowView.findViewById(R.id.status);
final TextView time = (TextView) rowView.findViewById(R.id.time);
//time.setText(formatTime(taskSubList.get(position).getTimeSpent()));
text.setText(taskSubList.get(position).getName());
if(taskSubList.get(position).isCompleted()==0)
{
status.setText("Not Completed");
status.setTextColor(Color.RED);
}
else
{
status.setText("Completed");
status.setTextColor(Color.parseColor("#468765"));
}
return rowView;
}
I need to change it such a way that list should contain only names and when I click on these names an intent has to be called which gives a layout showing the details of that particular TaskObject.Details here means the properties of that task object which should be shown in the form of text views in new layout.Not a dialog or Toast..
In your getView()
status.setOnClickListener(new MyClickListener(position));
public class MyClickListener implements OnClickListener {
private int posi;
public MyClickListener(int position) {
this.posi = position;
}
public void onClick(View v) {
CustomDialog customDialog = new CustomDialog(ViewDetials.this);
customDialog.show();
// Toast.makeText(getBaseContext(), "text view clicked",Toast.LENGTH_SHORT).show();
}
}
}

Android unsorted List

I have created a listActivity with my own ListAdapter. The problem is that the list is viewed in order once launched. But When I scroll down, or go back from another activity, the listView is completely out of order.
I thought the problem was in ArrayList but no, the list is sorted and i'm sure of it because when I loop over all elements in the ArrayList they are printed in the log the same way I inserted them.
I pasted the adapter code below in case anyone would like to check it.
package com.anubis.mail;
import java.util.ArrayList;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
public class EmailAdapter extends BaseAdapter {
private ArrayList<EmailModel> elements;
private Context c;
public EmailAdapter(Context c, ArrayList<EmailModel> Emails) {
this.elements = Emails;
this.c = c;
}
public int getCount() {
return elements.size();
}
public Object getItem(int position) {
return elements.get(position);
}
public long getItemId(int id) {
return id;
}
public void Remove(int id) {
notifyDataSetChanged();
}
public void Add(EmailModel email) {
this.elements.add(email);
for (EmailModel e : elements){
Log.v("EmailAdapter", e.getSubject());
}
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout rowLayout;
EmailModel email = elements.get(position);
if (convertView == null) {
rowLayout = (LinearLayout) LayoutInflater.from(c).inflate (R.layout.inbox_item, parent, false);
TextView subject_textview = (TextView)rowLayout.findViewById(R.id.subject_textview);
subject_textview.setText(email.getSubject());
String body_hint = " - " + email.getBodyHint();
TextView bodyhint_textview = (TextView)rowLayout.findViewById(R.id.body_hint_textview);
bodyhint_textview.setText(body_hint);
String sender_name = get_sender_name(email.getSender());
TextView sender_name_textview = (TextView)rowLayout.findViewById(R.id.sender_textview);
sender_name_textview.setText(sender_name);
TextView date_time_textview = (TextView)rowLayout.findViewById(R.id.date_time_textview);
date_time_textview.setText(email.getTime());
} else {
rowLayout = (LinearLayout) convertView;
}
return rowLayout;
}
private String get_sender_name(String from) {
String[] sender = from.split("<");
String sender_name;
try {
sender_name = sender[0];
} catch (Exception e) {
sender_name = sender[1];
}
return sender_name;
}
}
You need to move code after the IF
if (convertView == null) {
rowLayout = (LinearLayout) LayoutInflater.from(c).inflate (R.layout.inbox_item, parent, false);
} else {
rowLayout = (LinearLayout) convertView;
}
TextView subject_textview = (TextView)rowLayout.findViewById(R.id.subject_textview);
subject_textview.setText(email.getSubject());
String body_hint = " - " + email.getBodyHint();
TextView bodyhint_textview = (TextView)rowLayout.findViewById(R.id.body_hint_textview);
bodyhint_textview.setText(body_hint);
String sender_name = get_sender_name(email.getSender());
TextView sender_name_textview = (TextView)rowLayout.findViewById(R.id.sender_textview);
sender_name_textview.setText(sender_name);
TextView date_time_textview = (TextView)rowLayout.findViewById(R.id.date_time_textview);
date_time_textview.setText(email.getTime());
return rowLayout;

Categories

Resources