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.
Related
I have a custom layout for a Listview, each row item contains a button that when clicked it shows a small imageview in the item, however the actions i perform in one item, repeats for another item down the list, for example, if i click the button in item 1, the imageview will show up in item 1 and item 10, if i click the button in item 2, the Imageview will show up on item 2 and item 11 and while i scroll it will keep repeating in different items, heres the code for my custom adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
mparent = parent;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.places_item, parent, false);
holder = new ViewHolder();
holder.placeimage = (CircularImageView) convertView.findViewById(R.id.locationimage_pilayout);
holder.addbtn = (TextView) convertView.findViewById(R.id.addbtn_pilayout);
holder.delbtn = (TextView) convertView.findViewById(R.id.delbtn_pilayout);
holder.oribtn = (TextView) convertView.findViewById(R.id.oribtn_pilayout);
holder.placename = (TextView) convertView.findViewById(R.id.locationname_pilayout);
holder.selected = (ImageView) convertView.findViewById(R.id.selected_pilayout);
holder.origin = (ImageView) convertView.findViewById(R.id.origin_pilayout);
holder.swipeLayout = (SwipeRevealLayout) convertView.findViewById(R.id.swipe_pilayout);
holder.mainLayout = (LinearLayout) convertView.findViewById(R.id.main_pilayout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final Place item = getItem(position);
/*
my code assigning the button click listener and assigning the views
*/
return convertView;
}
Am i missing something? im sure this could be a simple fix, but i havent found it yet. any help would be kindly appreciated.
In ListView the individual views for rows, get reused. For example, let's say the window can show up to 10 rows inside the ListView. Now when you scroll down, the 1st view gets out of the window from the top, and a new 11th view comes into the window from the bottom. In order to save memory and CPU power, Android uses the same 1st view for the 11th view. That's the purpose of convertView and the if (convertView == null) {} else {} code.
So the reason why the image is being shown in the 1st item and also in the 11th item, is that they are exactly one view object. To tackle this issue, in the getView() method, you need to reset every attribute of every view and don't rely on the defaults.
So adding a line like the one below, will get rid of the mentioned problem:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// all your code ...
holder.placeImage.setImageResource(0); //<-- This clears any previously set image.
return convertView;
}
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.
I'm implementing custom adapter which handles multiple type of lines in a listview based on this (very useful) tutorial: http://logc.at/2011/10/10/handling-listviews-with-multiple-row-types/
Now, I thought I understood everything but one thing puzzles me.
In the getView method we receive the convertView which suppose to be the view (group) with specific layout to display in the specific line in the listview.
public View getView(int position, View convertView, ViewGroup parent) {
//first get the animal from our data model
Animal animal = animals.get(position);
//if we have an image so we setup an the view for an image row
if (animal.getImageId() != null) {
ImageRowViewHolder holder;
View view;
//don't have a convert view so we're going to have to create a new one
if (convertView == null) {
ViewGroup viewGroup = (ViewGroup)LayoutInflater.from(AnimalHome.this)
.inflate(R.layout.image_row, null);
//using the ViewHolder pattern to reduce lookups
holder = new ImageRowViewHolder((ImageView)viewGroup.findViewById(R.id.image),
(TextView)viewGroup.findViewById(R.id.title));
viewGroup.setTag(holder);
view = viewGroup;
}
//we have a convertView so we're just going to use it's content
else {
//get the holder so we can set the image
holder = (ImageRowViewHolder)convertView.getTag();
view = convertView;
}
//actually set the contents based on our animal
holder.imageView.setImageResource(animal.getImageId());
holder.titleView.setText(animal.getName());
return view;
}
//basically the same as above but for a layout with title and description
else {
DescriptionRowViewHolder holder;
View view;
if (convertView == null) {
ViewGroup viewGroup = (ViewGroup)LayoutInflater.from(AnimalHome.this)
.inflate(R.layout.text_row, null);
holder = new DescriptionRowViewHolder((TextView)viewGroup.findViewById(R.id.title),
(TextView)viewGroup.findViewById(R.id.description));
viewGroup.setTag(holder);
view = viewGroup;
} else {
view = convertView;
holder = (DescriptionRowViewHolder)convertView.getTag();
}
holder.descriptionView.setText(animal.getDescription());
holder.titleView.setText(animal.getName());
return view;
}
}
However, in the case of multiple types of lines in the listview (for example, list of animals with separators lines with titles like 'mamals','fish','birds') how does the listview know what convertView to send? it can be one of two completely different types. something is very unclear to me. can someone explain please?
From the tutorial you provided :)
The two additional methods android Adapters provide for managing different row types are:
getItemViewType(int position) and getViewTypeCount().
The list view uses these methods create different pools of views to reuse for different types of rows.
Good Luck :)
I've a custom adapter for my ListView where I send to it a List, and if the position is in the list then the imageview (that is in the custom row) change its src to another.. Here is the GetView method:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.start_row, null); // line
// 47
holder = new ViewHolder();
holder.tv_SuraName = (TextView) convertView.findViewById(R.id.Start_Name);
holder.tv_SuraName.setTypeface(Font);
holder.tv_PageNumber = (TextView) convertView.findViewById(R.id.Start_Numbering);
holder.im_Audio = (ImageView) convertView.findViewById(R.id.Start_ImageView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv_SuraName.setText(SuraList_SuraNamesCode[position]);
holder.tv_PageNumber.setText(Integer.toString(PageNumber[position]));
holder.im_Audio.setOnClickListener(new imageViewClickListener(position));
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
return convertView;
}
I send a List with 1 position.If I scroll the ListView slowly, this works good and only 1 imageview gets changed as it should be. But if I scroll fast, other imagesviews that are close to the correct position also gets changed!
Can anyone tell me why?
You don't ever set the imageResource to something else if position isn't contained in your list. When the view with the custom image leaves the screen it is probably getting placed at a lower position in the list and getting reused.
Try changing this:
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
To this:
if (TilawaAvailable.contains(position))
holder.im_Audio.setImageResource(R.drawable.quran_list_audioavailable);
else
holder.im_audio.setImageResource(r.drawable.SOME_THING_ELSE);
I am confused in changing the background colour of a particular row in an list view, below is the code I tried. Different rows gets highlighted as i scroll the list, I could like to understand the reason behind this. The logic seems to quite simple, but the results are unpredictable. How am I supposed to achieve this.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.rows_for_layout, null);
holder = new ViewHolder();
holder.name = (TextView)convertView.findViewById(R.id.name);
holder.rated=(ImageView)convertView.findViewById(R.id.rated);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
//selected_position is the position where the list has to be highlighted
if(position==selected_position){
holder.name.setText(elements.get(position).get("name"));
convertView.setBackgroundResource(R.drawable.highlight_this);
holder.rated.setBackgroundResource(R.drawable.star_image);
}else{
holder.name.setText(elements.get(position).get("name"));
}
return convertView;
}//getView ![alt text][1]
Your else statement does not reset the background color to its original. The getView method can recycle a view that was previously in your list but is not visible anymore. If the background was changed, then it will still be that background color from when it was originally created, which can depend on your state.
So, to "reset" that, add the following in your else:
if(position==selected_position){
holder.name.setText(elements.get(position).get("name"));
convertView.setBackgroundResource(R.drawable.highlight_this);
holder.rated.setBackgroundResource(R.drawable.star_image);
}else{
holder.name.setText(elements.get(position).get("name"));
//Add this
convertView.setBackgroundResource(R.drawable.not_highlighted);
}