List of TextViews in Listview - android

I have a question about List in Listview,
what I want to achieve is to create a listView with multiple TextViews in each item(like another listview)
I don't know how many elements would be in each items
From what I know creating listview in listview is a bad idea
So I want to create a normal listview (with item1 / item 2 / item 3..)
inside each row add linearlayout and populate it with textviews
I made this, but in every iteration it adds new linearlayout, how to change that? I want to add only textviews inside custom LinearLayout (R.layout.suplerowlist)
Or maybe is a better way to achieve that?
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
String menu_opcja = getItem(position);
if (convertView==null){
convertView = inflater.inflate(R.layout.suplementacja_row, null);
holder = new ViewHolder();
holder.suplement = (TextView) convertView.findViewById(R.id.nazwa_suplementu);
convertView.setTag(holder);
}
else{
holder = (ViewHolder) convertView.getTag();
((LinearLayout) convertView).removeAllViews();
}
holder.suplement.setText(menu_opcja);
for (int i = 0; i < menu.length; i++) {
View holders = inflater.inflate(R.layout.suplerowlist, parent, false);
TextView textViewTitles = (TextView) holders.findViewById(R.id.nazwa_supla);
textViewTitles.setText(menu[i]);
((LinearLayout) convertView).addView(holders);
}
return convertView;
}

Using ExpandableListView would be the best solution for this type of situation see this tutorial on how to use expandable list view.

Related

How to add GridView to ListView

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);
}
}
I'd suggest to use a LinearLayout with ImageViews instead of a GridView to hold the letters.
While technically is possible to have a GridView inside a ListView, GridViews 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 LinearLayouts
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.

Items being added to a list item multiple times. How do I fix this?

I am trying to create a listview with each list item is different and their layouts are created by code. The initial layouts look fine, but when i scroll out and in, all the layout items added programatically are added again, resulting duplicate items. How can I solve that problem?
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
MyHolder holder;
if (v == null) {
LayoutInflater li = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.empty_item, null);
holder = new MyHolder(v);
v.setTag(holder);
} else {
holder = (MyHolder) v.getTag();
}
TextView textView = new TextView(activity);
textView.setText(items.get(position).getItems().get(i).getText());
textView.setLayoutParams(params);
holder.linearLayout.addView(textView);
return v;
}
class MyHolder{
public TextView tvTitle;
public LinearLayout linearLayout;
public CardView cardView;
public MyHolder(View base){
tvTitle = (TextView)base.findViewById(R.id.tvTitle);
cardView = (CardView)base.findViewById(R.id.card_view2);
linearLayout = (LinearLayout)base.findViewById(R.id.linearLayoutCard);
}
}
I'm not even sure how this code is running, because you have no return statement in your getView() method. But you need to return the convertView in getView() so that the ListView can reuse those when it needs to. Otherwise, it'll just keep asking for new views every time it needs them. So you would just put return v; at the end of getView().
Additionally, you are creating and adding new TextViews to your MyHolder objects outside of the if (v == null) block. Normally you would instantiate new views like this if the convertView is null. If it isn't, you just pass it through to the ListView or make updates to it before passing it back. So what's happening is, the convertView is available (not null), but instead of using it, you're adding a brand new TextView instead, which is why you are getting duplicates.

Adding multiple items in a single list view row

I have list view which can have multiple items per row (same type but different values). Each List View item has left and right arrows with it. But I am unable to get that how to add multiple values per row, and how to switch them later.
Here is my get view:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.beer_list_item, parent,false);
holder.tv_brandTitle = (TextView)convertView.findViewById(R.id.tv_BrandName);
holder.tv_packSizeOption = (TextView)convertView.findViewById(R.id.tv_packSizeOption);
holder.img_manufacturerLogo = (ImageView)convertView.findViewById(R.id.img_brandBigLogo);
holder.img_canBeerLogo = (ImageView)convertView.findViewById(R.id.img_canBeerImg);
holder.tv_CanOrBottle = (TextView)convertView.findViewById(R.id.tv_CanOrBottle);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_brandTitle.setText(findBeerDataList.get(position).getBrandName());
int numOfProducts = findBeerDataList.get(position).getBeerProductList().size();
holder.tv_CanOrBottle.setText(findBeerDataList.get(position).getBeerProductList().get(0).getCanOrBottle());
if(findBeerDataList.get(position).getBeerProductList().get(0).getCanOrBottle().equalsIgnoreCase("can")){
imageLoader.DisplayImage(findBeerDataList.get(position).getCanImage(), holder.img_canBeerLogo);
}
else{
imageLoader.DisplayImage(findBeerDataList.get(position).getBottleImage(), holder.img_canBeerLogo);
}
imageLoader.DisplayImage(findBeerDataList.get(position).getBrandLogo(), holder.img_manufacturerLogo);
holder.tv_packSizeOption.setText(findBeerDataList.get(position).getBeerProductList().get(0).getPackOption()+"×"+findBeerDataList.get(position).getBeerProductList().get(0).getPackSize()+"ml");
return convertView;
}
Here numofproducts is the size of the views in LIst ROW.
Please suggest me a good means to do the same
Just make one combined view wrapped in i.e. RelativeLayout and hide some views with View.GONE. Once arrow is pressed you unveil next view and hide the previous.
On click of Right arrow, replace the content of the current view with new one i.e. the Next Item and on click of Left arrow replace it with the previous one.

how to change listview's row properties without layout?

Good time!
My Android app has so feature that I use ListView in the one of the page of TabHost without layout for ListView. Like that:
ListView lv = new ListView(this);
lv.setAdapter(myAdapter);
So I'd like to change some row's properties like text size in the row. So, how can I get access to the properties of the explicit row of ListView to change text size, for example?
Use BaseAdapter and modify font size in getView call.
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.custom_layout, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// Change text size
holder.text.setTextAppearance(context,R.style.customStyle);
return convertView;
}
static class ViewHolder {
TextView text;
}
And you can use position variable in getView call to change specific row. Hope this help!!!

Custom adapter getting wrong position on getView metod in ListView

I have list view with custom array adapter. I want to get items click position from getView method. I am getting a few list view items position but when i add more then 7 items into my list i get wrong position from getView method. I mean when i click 9th list item it returns 1.
Here is my code
#Override
public View getView(int pos, View convertView, ViewGroup parent) {
this.position = pos;
Log.v("View position", Integer.toString(pos));
lineView = convertView;
if(lineView==null)
{
adapterLine=new AdapterLine();
layoutInflater=context.getLayoutInflater();
lineView=layoutInflater.inflate(com.inomera.sanalmarket.main.R.layout.adapter, null,true);
adapterLine.sListText = (TextView) lineView.findViewById(R.id.sListText);
adapterLine.sListCheckbox = (CheckBox) lineView.findViewById(R.id.sListCheckbox);
adapterLine.sListImageView = (ImageView) lineView.findViewById(R.id.imageView1);
adapterLine.gestureOverlayView = (GestureOverlayView) lineView.findViewById(com.inomera.sanalmarket.main.R.id.gestureOverlayView1);
adapterLine.gestureOverlayView.setGestureVisible(false);
// To remember whitch tab is selected
adapterLine.sListImageView.setTag(pos);
adapterLine.sListCheckbox.setTag(pos);
adapterLine.sListText.setTag(pos);
Log.v("adapter", "position of adapter is " + Integer.toString(pos));
Thanks for any help!
The array adapter will only create one object per visible row in your list view. After this, the adapter will recycle that already created view. This is the purpose of the:
if(lineView==null)
line in your adapter.
You will want to put in an else section that sets up the row using the recycled view. This other article may be helpful:
How can I make my ArrayAdapter follow the ViewHolder pattern?
This implementation is incomplete add else section which sets value from data. here is implementation which worked for me
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflator = reportViewContext.getLayoutInflater();
convertView = inflator.inflate(R.layout.tabitems, null);
viewHolder.name= (TextView) convertView
.findViewById(R.id.user_reportTab_userName);
//set other values needed in viewHolder if any
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}
//data is list of Data model
if(data.size()<=0) {
//if data unavailable }
else {
/***** Get each Model object from Array list ********/
System.out.println("Position:"+position);
/************ Set Model values in Holder elements ***********/
viewHolder.name.setText(data.get(position).getName());
}
return convertView;
}
I know the question is very old, answered in case anyone stumbled on similar problem

Categories

Resources