1

I am using a ListView to display some JSON data and want to display each result according to its type (Artist, Release, Label...).

I will be using an interface implemented by each type of result :

public interface Result {
    public Int getId();
    public String getThumb();
    // ...
} 

I would like to know which of these choices is the best solution (I am open to better things, that's just what I had on the top of my head):

  • creating an enum ResultType in the interace (so inherited class will have to return their own value like ResultType.ARTIST in a getType() method
  • checking the instance type using isInstance()

I would like to know what would be the best way to perform something equivalent to this C code (array of function pointer) as I would like to avoid using to many if/else statements.

typedef struct s_func {
   const char *type_name;
   void* (*func_pointer)(void *result_infos);
} t_func;

static t_func type_array[] = {
 {"artist", artist_function},
 {"label", label_function},
  // ....
 {NULL, NULL}
}

void check_type(const char *type_string)
{
  int i, j = 0;
  char *key_value;

  // compare string and array key
  while (type_array && type_array[i][0]) {
    key_value = type_array[i][0];
    // if key match
    if (type_string && strncmp(type_string, key_value, strlen(type_string)) == 0) {
       type_array[i][1](); // call appropriate function;
    }
    i++;    
  }
}

I guess it would be using a HashMap but (I might be wrong) it doesn't seem to have a litteral notation. Is there any easy way to build an HashMap of pairs ?

Thank you

rxdazn
  • 1,380
  • 1
  • 14
  • 30

1 Answers1

0

I think you can use an ArrayAdapter. Take a look at this tutorial to see what I mean.

It'll need some twiddling so that it can deal with the different kinds of items. Make an interface MyListItem

public interface MyListItem {
    public int getLayout();
    public void bindToView(View v);
}

Make different layouts for the display of Artist, Release, Label. Make classes Artist, Release, Label that implement MyListItem.

public class Artist implements MyListItem {
    private String Name;

    public Artist(String name){
        this.name = name;
    }

    public int getLayout() {
        return R.layout.artistlayout;
    }

    public void bindToView(View v) {
        TextView textView = (TextView) rowView.findViewById(R.id.artistLabel);
        textView.setText(name);
    }
}

Now the adapter only has to call the right methods to fill the view for the selected item.

public class MySimpleArrayAdapter extends ArrayAdapter<MyListItem> {
  private final Context context;
  private final MyListItem[] values;

  public MySimpleArrayAdapter(Context context, MyListItem[] values) {
    super(context, android.R.layout.simple_list_item_1, values);
    this.context = context;
    this.values = values;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    MyListItem item = values[position];

    LayoutInflater inflater = (LayoutInflater) context
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(item.getLayout(), parent, false);
    item.bindTo(view);
    return view;
  }
}
flup
  • 26,937
  • 7
  • 52
  • 74
  • You won't be able to re-use views for quick-quick scrolling through long lists. If this is needed, you can probably better make one layout that'll show them all and bind each type to the same layout. – flup Jan 18 '13 at 23:03
  • I see now that others are way ahead of me: http://stackoverflow.com/questions/4777272/android-listview-with-different-layout-for-each-row – flup Jan 18 '13 at 23:22