ListView with buttons OnClickListener? - android

I am working on app with ListView with buttons on list item.
It's working fine but I can't find way to make buttons on items clickable.
I want to make this Silver arrows clickable. How can I do that?
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow"
android:layout_alignParentRight="true"
android:onClick="btnclick"
android:layout_centerVertical="true"/>
How can I make this to be different, like ItemClickListener with position?
Here is my Adapter
class DAdapter extends ArrayAdapter<String>{
Context context;
int [] images;
String[] titleArray;
DAdapter(Context c, String [] titles, int imgs[])
{
super(c,R.layout.single_row, R.id.title,titles);
this.context=c;
this.images=imgs;
this.titleArray=titles;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
if (row==null) { LayoutInflater inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row=inflater.inflate(R.layout.single_row, parent,false);
}
ImageView myImage=(ImageView) row.findViewById(R.id.list_image);
TextView myTitle=(TextView) row.findViewById(R.id.title);
myImage.setImageResource(images[position]);
myTitle.setText(titleArray[position]);
return row;
I'm not sure if I should add whole code but if its needed please tell me.
single_row.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<LinearLayout android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:background="#drawable/image_bg"
android:layout_marginRight="5dip">
<ImageView
android:id="#+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="#drawable/ic_launcher"/>
</LinearLayout>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:text=""
android:textColor="#040404"
android:typeface="sans"
android:textSize="15sp"
android:textStyle="bold"/>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow"
android:layout_alignParentRight="true"
android:onClick="btnclick"
android:layout_centerVertical="true"/>
</RelativeLayout>

First add id to your ImageView like..
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/arrow"
android:layout_alignParentRight="true"
android:id="#+id/arrowImage"
android:onClick="btnclick"
android:layout_centerVertical="true"/>
then get the ImageView and write listener ..change your getView like..
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.single_row, parent, false);
}
ImageView myImage = (ImageView) row.findViewById(R.id.list_image);
TextView myTitle = (TextView) row.findViewById(R.id.title);
myImage.setImageResource(images[position]);
myTitle.setText(titleArray[position]);
ImageView arrowImage = (ImageView) row.findViewById(R.id.arrowImage);
arrowImage.setTag(position);
arrowImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int clickedposition=(Integer) v.getTag();
//Write your Activity launch code here..
}
});
return row;
}

You should set a general onclick handler for the image view. Then while doing the job in the onclick listener just check its parent to know the parent of this button. And if you want some custom style for this arrow to be shown, you can use a button instead of imageButton and set its background to an xml file to make it dynamic.
Is this enough?

Related

Row in listview not preserve the makeover and appears repeated

I have a list that when you click on the row on the right side the layout with the icon is changed by other. This makes it well but when I scrolling in the list, I notice there are rows with the same icon without do click. Also, if I scroll quickly these same icons are lost and are built differently. I think it's on the reuse of cells but I can not find the solution. What I want is that the image stays active only in the row where clicka.
Thanks!!
Adapter class:
public class ListadoVotantesArrayAdapter extends ArrayAdapter<Votante> {
private Context context;
private LayoutInflater inflater;
private ArrayList<Votante> listaVotantes;
private int rowLayout;
private View mConverView;
public ListadoVotantesArrayAdapter(Context context, int resource, ArrayList<Votante> objects) {
super(context, resource,objects);
this.context = context;
this.inflater = LayoutInflater.from(context);
this.listaVotantes = objects;
this.rowLayout = resource;
}
public int getCount(){
return this.listaVotantes.size();
}
public Votante getVotante(int position){
return this.listaVotantes.get(position);
}
private static class ViewHolder {
public TextView lblName;
public TextView lblLastName;
public TextView lblDni;
public TextView lblVoterNumber;
public RelativeLayout lytVoted;
public RelativeLayout lytCanVote;
public RelativeLayout lytUndo;
}
public View getView(int position, View converView, ViewGroup parent) {
final ViewHolder viewHolder;
mConverView = converView;
if (mConverView == null){
viewHolder = new ViewHolder();
this.mConverView = inflater.inflate(this.rowLayout, parent, false);
if (mConverView != null){
viewHolder.lblName = (TextView) mConverView.findViewById(R.id.lblVoterName);
viewHolder.lblLastName = (TextView) mConverView.findViewById(R.id.lblVoterLastName);
viewHolder.lblDni = (TextView) mConverView.findViewById(R.id.lblDni);
viewHolder.lblVoterNumber = (TextView) mConverView.findViewById(R.id.lblNumber);
viewHolder.lytVoted = (RelativeLayout) mConverView.findViewById(R.id.lytVoted);
viewHolder.lytCanVote = (RelativeLayout) mConverView.findViewById(R.id.lytCanVote);
viewHolder.lytUndo = (RelativeLayout) mConverView.findViewById(R.id.lytUndo);
mConverView.setTag(viewHolder);
}
}else{
viewHolder = (ViewHolder) mConverView.getTag();
}
Votante votante = getVotante(position);
viewHolder.lblName.setText(votante.getNombre());
viewHolder.lblLastName.setText(votante.getApellidos());
viewHolder.lblDni.setText(votante.getDni());
viewHolder.lblVoterNumber.setText(""+votante.getNumVotante());
if (votante.getVotado()){
viewHolder.lytVoted.setVisibility(View.VISIBLE);
viewHolder.lytCanVote.setVisibility(View.GONE);
}else{
viewHolder.lytVoted.setVisibility(View.GONE);
viewHolder.lytCanVote.setVisibility(View.VISIBLE);
}
mConverView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.lytUndo.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});
return mConverView;
}
}
Layout Row:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lyt_voter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="1dp">
<RelativeLayout
android:id="#+id/lytVoterNumber"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentLeft="true"
android:background="#color/lightBlueItemList">
<TextView
android:id="#+id/lblNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="1999"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
<LinearLayout
android:id="#+id/lytVoterData"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/lytCanVote"
android:layout_toRightOf="#+id/lytVoterNumber"
android:layout_toStartOf="#+id/lytCanVote"
android:background="#color/whiteItemList"
android:orientation="vertical"
android:padding="5dp">
<TextView
android:id="#+id/lblVoterLastName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Suarez Garcia de la Serna"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblVoterName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="José Carlos"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/lblDni"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="44950962S"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<RelativeLayout
android:id="#+id/lytCanVote"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/yellowItemList"
android:minHeight="30dp"
android:minWidth="30dp">
<ImageView
android:id="#+id/imgVote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/flecha" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/lytVoted"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:background="#color/grrenAcceptList"
android:minHeight="30dp"
android:minWidth="30dp"
android:visibility="gone">
<ImageView
android:id="#+id/imgAccept"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/aceptar"
/>
</RelativeLayout>
<RelativeLayout
android:layout_width="70dp"
android:layout_height="70dp"
android:minHeight="30dp"
android:minWidth="30dp"
android:background="#color/redD3"
android:id="#+id/lytUndo"
android:layout_alignParentRight="true"
android:visibility="gone">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgUndo"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#drawable/undo"/>
</RelativeLayout>
</RelativeLayout>
You need to follow below Idea
1) this line of code mConverView = converView; doesn't makes sense. directly use converView(View from getView param). Remove mConvertView from the adapter.
2) Add some mechanism which can tell you which row is clicked and save that variable.
Example:- Have an boolean Array of size Rows.size . and set them in onClick.
Boolean[] array = new Boolean[getSize()];
in onClick that you already have in your getview set this.
public void onClick(View v) {
array[position] = !array[position];
viewHolder.lytUndo.setVisibility(View.VISIBLE);
//You do not need to call notifyDatasetChange.
3) in getView(), when you are setting data in to row items/or just before onClick. have a check like below.
if(array[position])// this will tell you if you need to show or hid lytUndo thing
viewHolder.lytUndo.setVisibility(View.VISIBLE); // Show it
else
viewHolder.lytUndo.setVisibility(View.GONE); // hide it or do whatever you want
You might need to set some params as final
I have written this as simple as possible, comment back with your result.

Remove excess whitespace at bottom of ListView item

I've been having some troubles with excess whitespace at the bottom of ListView items. Example with white/negative space marked with red arrows at http://i.stack.imgur.com/wpm7a.png
Here's my layout XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.thereversecookbook.ResultsList" >
<ListView
android:id="#+id/results_list_lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" >
</ListView>
</RelativeLayout>
And my list item XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<!-- cooking time -->
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:clickable="false"
android:longClickable="false"
android:paddingBottom="50dp"
android:textColor="#CC0033"
android:textSize="16sp" />
<ImageView
android:id="#+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/title"
android:layout_centerVertical="true"
android:clickable="false"
android:longClickable="false"
android:maxHeight="50dp"
android:maxWidth="50dp"
android:src="#drawable/ic_clock" />
<TextView
android:id="#+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/icon"
android:layout_centerVertical="true"
android:clickable="false"
android:longClickable="false"
android:textColor="#3399FF"
android:textSize="14sp" />
<RatingBar
android:id="#+id/ratingBar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="false"
android:isIndicator="true"
android:longClickable="false"
android:scaleX="0.5"
android:scaleY="0.5"/>
</RelativeLayout>
And CustomListAdapter:
public class CustomListViewAdapter extends ArrayAdapter<RowItem> {
Context context;
public CustomListViewAdapter(Context context, int resourceId, List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
}
/*private view holder class*/
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtCookingTime;
RatingBar ratingBar;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
RowItem rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.txtCookingTime = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
holder.ratingBar = (RatingBar) convertView.findViewById(R.id.ratingBar1);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.txtCookingTime.setText(rowItem.getCookingTime());
holder.txtTitle.setText(rowItem.getTitle());
//holder.imageView.setImageResource(rowItem.getImageId());
holder.ratingBar.setRating(rowItem.getRating());
holder.ratingBar.setStepSize((float)0.5);
return convertView;
}
}
Anyone have any ideas what could be causing this? Many thanks!
convertView = mInflater.inflate(R.layout.list_item, null);
Bzzzt. Don't use that inflate() method. You want to use the three-parameter version, passing in your convertView ("the inflated widgets will eventually be a child of this...") and false ("...but don't make them be children of it right away"):
convertView = mInflater.inflate(R.layout.list_item, parent, false);
That's particularly important in your case, as RelativeLayout gets weird if it's the root container of your layout file and you don't use this version of the inflate() method.
You can read more about this in Dave Smith's "Layout Inflation as Intended" blog post.

android custom adapter dynamic row height

I have just created my first custom adapter, which works great.
And with that, I created a rowlayout.xml for the adapter to fill.
But I have one issue, the row is not dynamic, so if I try to put a text that is longer than the row in, the row wont expand, but instead cut the text off. (see pic. here: http://tinyurl.com/paxdt3a)
Here is my rowLayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:padding="6dip" >
<!--The second line is used for the date of the post-->
<TextView
android:id="#+id/secondLine"
android:layout_width="fill_parent"
android:layout_height="26dip"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:ellipsize="marquee"
android:singleLine="true"
android:text="Time and date"
android:textSize="12sp" />
<!--The first line is used to the post-->
<TextView
android:id="#+id/firstLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#id/secondLine"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
android:text="Post"
android:textSize="16sp" />
</RelativeLayout>
And here is my Adapter:
public class MyAdapter extends ArrayAdapter<UserPost> {
private final Context context;
private final List<UserPost> posts;
public MyAdapter(Context context, List<UserPost> posts) {
super(context, R.layout.rowlayout, posts);
this.context = context;
this.posts = posts;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
TextView firstText = (TextView) rowView.findViewById(R.id.firstLine);
TextView secondText = (TextView) rowView.findViewById(R.id.secondLine);
//Insert the post
firstText.setText(posts.get(position).getMessage());
//Insert the time
secondText.setText(posts.get(position).getDate());
return rowView;
}
}
Does anyone have any idea on how to solve this?
Thanks!
UPDATE (SOLUTION):
Okay, so I made some changes in my rowlayout.xml, and I finally came up with this, which works!
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="6dip" >
<!--The first line is used to the post-->
<TextView
android:id="#+id/firstLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
android:text="Post"
android:textSize="16sp" />
<!--The second line is used for the date of the post-->
<TextView
android:id="#+id/secondLine"
android:layout_below="#+id/firstLine"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:ellipsize="marquee"
android:singleLine="false"
android:text="Time and date"
android:textSize="12sp" />
</RelativeLayout>
On your item layoutyou have android:layout_height="?android:attr/listPreferredItemHeight" meaning you are forcing a specific row height for all rows change to android:layout_height="wrap_content"
what simply you can do is to remove the singleLine property
android:singleLine="false"
or you can do like this
public class MyAdapter extends ArrayAdapter<UserPost> {
private final Context context;
private final List<UserPost> posts;
public MyAdapter(Context context, List<UserPost> posts) {
super(context, R.layout.rowlayout, posts);
this.context = context;
this.posts = posts;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(text.length>MAX_LENGTH){
View rowView = inflater.inflate(R.layout.rowlayout1, parent, false);
//....
}else{
View rowView = inflater.inflate(R.layout.rowlayout, parent, false);
TextView firstText = (TextView) rowView.findViewById(R.id.firstLine);
TextView secondText = (TextView) rowView.findViewById(R.id.secondLine);
//Insert the post
firstText.setText(posts.get(position).getMessage());
//Insert the time
secondText.setText(posts.get(position).getDate());
}
return rowView;
}
}

Android: ListView bug

I have a custom list view which has a Textview and an image. When I click on the textview a hidden layout will be expanded for that particular row. But what happening was, for eg., when I click on 2nd row, 10th row is also getting expanded. Here is my code,
CustomListAdapter.java
public View getView(final int position, View convertView, ViewGroup parent) {
holder = null;
DataFields rowItems = (DataFields) getItem(position);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.home_field_row, null);
holder = new ViewHolder();
holder.dataFields = items.get(position);
holder.mName = (TextView) convertView
.findViewById(R.id.hmFieldName);
holder.mDeleteImage = (ImageView) convertView
.findViewById(R.id.hmFieldDeleteImage);
holder.deleteMainRL = (RelativeLayout) convertView
.findViewById(R.id.hmdeleteMainRL);
holder.mDeleteImage.setTag(position);
holder.mName.setTag(position);
holder.deleteMainRL.setTag(position);
final View clickView = convertView;
holder.mName.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout displayAddInfo = (RelativeLayout)clickView.findViewById(R.id.displayRecordRL);
Animation expandAnim = expand(displayAddInfo,
true);
displayAddInfo
.startAnimation(expandAnim);
}
});
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.mName.setText(rowItems.getName());
return convertView;
}
How can I fix this? Any kind of help or suggestion is much appreciated. Thanks.
Update
list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/hmFieldMainRL"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/grid_shape" >
<TextView
android:id="#+id/hmFieldName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/displayRecordRL"
android:layout_alignParentLeft="true"
android:gravity="left"
android:padding="15dp"
android:shadowColor="#000000"
android:shadowDx="0"
android:shadowDy="0"
android:clickable="false"
android:shadowRadius="2"
android:text="#string/no_data"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#F2F2F2" />
<RelativeLayout
android:id="#+id/displayRecordRL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/hmFieldName"
android:layout_centerVertical="true"
android:layout_marginBottom="5dp"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:layout_marginTop="1dp"
android:background="#drawable/display_record_bg"
android:visibility="gone" >
<EditText
android:id="#+id/displayRecordName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_toLeftOf="#+id/displayRecordUpdate"
android:padding="10dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/displayRecordPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#id/displayRecordName"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:layout_toLeftOf="#+id/displayRecordShow"
android:inputType="textPassword"
android:paddingLeft="10dp"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="#+id/displayRecordAddInfoImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:layout_below="#id/displayRecordPwd"
android:contentDescription="#string/right_arrow"
android:visibility="gone"
android:src="#drawable/info" />
<EditText
android:id="#+id/displayRecordAddInfo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/displayRecordAddInfoImg"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="2dp"
android:hint="Additional Information"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<ImageView
android:id="#+id/displayRecordUpdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#drawable/display_record_img"
android:contentDescription="#string/right_arrow"
android:padding="10dp"
android:src="#drawable/update_rec" />
<ImageView
android:id="#+id/displayRecordShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/displayRecordUpdate"
android:layout_marginTop="10dp"
android:contentDescription="#string/right_arrow"
android:padding="10dp"
android:src="#drawable/eye" />
<ImageView
android:id="#+id/displayRecordShowRed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="#id/displayRecordUpdate"
android:layout_marginTop="10dp"
android:contentDescription="#string/right_arrow"
android:padding="10dp"
android:src="#drawable/redeye"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>
But what happening was, for eg., when I click on 2nd row, 10th row is also getting expanded.
You are fighting the way ListViews recycle the row layouts. But this is easy enough to deal with, first let's add a couple new class variables:
SparseBooleanArray expanded = new SparseBooleanArray();
LayoutInflater inflater; // initialize this in your constructor
Now we'll use expanded to check whether displayRecordRL should be visible:
public View getView(final int position, View convertView, ViewGroup parent) {
DataFields rowItems = (DataFields) getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.home_field_row, null);
holder = new ViewHolder();
holder.dataFields = items.get(position);
holder.mName = (TextView) convertView
.findViewById(R.id.hmFieldName);
holder.mDeleteImage = (ImageView) convertView
.findViewById(R.id.hmFieldDeleteImage);
holder.deleteMainRL = (RelativeLayout) convertView
.findViewById(R.id.hmdeleteMainRL);
// Add this to your holder
holder.mAddInfo = (RelativeLayout) convertView
.findViewById(R.id.displayRecordRL);
holder.mDeleteImage.setTag(position);
holder.mName.setTag(position);
holder.deleteMainRL.setTag(position);
holder.mName.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Get the ViewHolder
holder = (ViewHolder) ((View) v.getParent()).getTag();
Animation expandAnim = expand(holder.mAddInfo, true);
holder.mAddInfo.startAnimation(expandAnim);
// Remember that this View is expanded
int pos = (Integer) v.getTag();
expanded.put(pos, true);
}
});
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.mName.setText(rowItems.getName());
if(expanded.get(position, false))
holder2.mAddInfo.setVisibility(View.VISIBLE);
else
holder2.mAddInfo.setVisibility(View.GONE);
return convertView;
}
Notice how this tracks whether each row should be visible and uses a simple if statement to make sure the recycled layout correctly shows or hide the "Add Info" section.
You need to add a attribute to your adapter, a simple int. When you click on an item, update the current selected position. When you build the view, check if position equals the selected position.
public View getView(final int position, View convertView, ViewGroup parent) {
if(this.selectedPosition == position){
//add a holder
else{
//don't add a holder
return convertview;
}
What I'm saying is that you are encountering a View recycling problem. If you modify item n°2 and then the view of item n°10 is build from the View n°2, you end up with an item unwanted (that will look as it was clicked).
When an item of your list is clicked:
1) update the selected item (attribute of your adapter). Example, if you click on item 12 of your listview, selectedItem = 12;
2) call method notifyDataSetChanged(). This will refresh the view of the list.
3) When you build the view (getView() of adapter), check for each position if it corresponds to the selected item. If it does, build your special view (I don't know exactly what you want to do). If it doesn't correspond to the selected item, build your view "normally"
Try to put the R.id.displayRecordRL as part of the viewholder and on the OnClick method call it.
holder.displayAddInfo = (RelativeLayout)clickView.findViewById(R.id.displayRecordRL);
and on the OnclickMethod :
Animation expandAnim = expand(holder.displayAddInfo,
true);
holder.displayAddInfo
.startAnimation(expandAnim);
}
The problem you experience could be that you animate a View (converView) that is being re-used for another item in your list-view when scrolling.
Look at this YouTube video and you may get an idea on how to solve your problem.
Chet Haase (Google engineer) "DevBytes" series "ListView Animations" :
https://www.youtube.com/watch?v=8MIfSxgsHIs#!

How to bind YES image for multiple selectable custom list

I'm trying to create an imagelist in which i can select muliple items, I have one yes icon that I want to set visible for whatever items i select(like checkbox) and invisible on unselect... I have added image into xml file and set its visibility as GONE(as it should not be visible initially).. Please tell me possible solutions..
for the list I have set list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
And my custom BaseAdapter class contains,
public static class ViewHolder{
public TextView text;
public ImageView image,yesimage;
public TextView quantity;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
final ViewHolder holder;
if(convertView==null){
vi = inflater.inflate(R.layout.item, null);
holder=new ViewHolder();
holder.image=(ImageView)vi.findViewById(R.id.image);
holder.text=(TextView)vi.findViewById(R.id.text);
holder.quantity=(TextView)vi.findViewById(R.id.quantity);
holder.yesimage=(ImageView)vi.findViewById(R.id.selectedyes);
vi.setTag(holder);
}
else
holder=(ViewHolder)vi.getTag();
// Here I wanted to know how can i set visibility of yesimege for individual selected items on list
holder.text.setText(items[position]);
holder.image.setTag(data[position]);
holder.quantity.setText(Integer.toString(qty[position]).trim());
imageLoader.DisplayImage(data[position], activity, holder.image);
return vi;
}
xml snippet item.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/image"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="#drawable/stub"
android:scaleType="centerCrop"/>
<TextView
android:id="#+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="left|center_vertical"
android:textSize="15dip"
android:typeface="sans"
android:textColor="#000000"
android:layout_marginLeft="10dip"/>
<TextView
android:id="#+id/quantity"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="right|center_vertical"
android:gravity="right"
android:paddingRight="10dp"
android:textSize="18dip"
android:typeface="sans"
android:textColor="#000000"/>
<ImageView android:id="#+id/selectedyes"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="gone"
android:src="#drawable/itemselected"
android:layout_marginRight="8dip"
android:soundEffectsEnabled="false" ></ImageView>
</LinearLayout>
You have to save/store that your item is selected or not.
After that check if the item is selected or not and use one of the following:
holder.image.setVisibility(View.GONE); // to make it disappear
or
holder.image.setVisibility(View.VISIBLE); // to display it
I don't know exactly what's in your data array, but you can save the state there.
if (data[position].isVisible()) {
holder.image.setVisibility(View.VISIBLE); // to display it
else
holder.image.setVisibility(View.GONE); // to make it disappear
You can catch click events with setting an OnItemClickListener on your ListView.
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
// Put your custom code here
}
});
Does it answer your question?

Categories

Resources