Reputation: 416
I have a list of words. I want the letters of each word in the list to display as images in a gridview.
I have implemented a working version of this by creating a custom adapter, WordListAdapter, for my list of words. For each word, WordListAdapter.getView, in turn, calls a custom adapter, LetterImageAdapter, to display the letters in the words. Since I'm new to Android programming, I'm wondering if this is a good approach. It sure seems like a lot of work. If it is a good approach, perhaps this will be helpful to someone else.
I've seen a number of other posts about gridviews inside listviews. Many of them touched on issues with scrolling and memory but I didn't see anything specific to this use case.
In my activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
ListView listView = (ListView) findViewById(R.id.wordList);
listView.setAdapter(new WordListAdapter(this, new String[]{"ABC", "DEF"}));
}
WordListAdapter.getView()
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.word_grid, null);
GridView gridView = (GridView) convertView.findViewById(R.id.word_grid_id);
holder = new ViewHolder();
holder.gridView = gridView;
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.gridView.setAdapter(new LetterImageAdapter(mContext, words[position]));
return convertView;
}
private static class ViewHolder {
GridView gridView;
}
LetterImageAdapter.getView()
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.letter_item, null);
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.list_item_letter_imageview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// resource for each letter is in lettersId array
holder.icon.setImageResource(letterIds[position]);
return convertView;
}
private static class ViewHolder {
ImageView icon;
}
// transform word into array of resources for each letter
private void buildResourceArray(String packageName) {
letterIds = new int[theWord.length()];
for (int index = 0; index < theWord.length(); index++) {
letterIds[index] = getResourceId(theWord.substring(index, index + 1).toLowerCase(), "drawable", packageName);
}
}
Upvotes: 0
Views: 918
Reputation: 9907
I'd suggest to use a LinearLayout
with ImageView
s instead of a GridView
to hold the letters.
While technically is possible to have a GridView
inside a ListView
, GridView
s are pretty complex objects, better suited to be a main list than a recyclable child item. You will run into complex issues when recycling the main items, as every GridView will have its own adapter.
So as the number of letters is pretty limited, a LinearLayout
(maybe inside a HorizontalScrollView
) is a far simpler approach. You can even cache the letter bitmaps, or include them as resources, so they are shared by all ImageViews
in the LinearLayout
s
To do something related to your intentions, you'd better look at RecyclerView, that is kind of an abstract item list container that you can setup to do all kinds of complex layouts. But being a beginner, I'd suggest to first master the simpler ListView
/ GridView
then move into RecyclerView
when you understand how View recycling works.
Upvotes: 1