Edward van Raak
Edward van Raak

Reputation: 4910

Android: Get the position of a ListView from the actual top

I am using List.get(position) to get the position of a ListView. But this returns the position from the top of the current scrolling bounds. My ListView has 50 items but you can only see 10 at one time. So when you scroll down completely and call List.get(position) you get 10 for the list item and not 50. If you click the item in the exact middle of of the ListView you get 5 and not 25 etc.

How do I get the position of a ListView from the actual top of the ListView. The easiest way at least.

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = null;

if (convertView == null) {
  LayoutInflater inflator = context.getLayoutInflater();      
  view = inflator.inflate(R.layout.addtowatchlist, null);
  final ViewHolder viewHolder = new ViewHolder();
  viewHolder.text = (TextView) view.findViewById(R.id.label);      
  viewHolder.addbutton = (Button) view.findViewById(R.id.button);
  viewHolder.addbutton
      .setOnClickListener(new Button.OnClickListener() {
        @Override
        public void onClick(View buttonview) {
            //I need the correct ACTUAL position here, not the VISABLE position                 
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(list.get(position).getUrl()));
            context.startActivity(browserIntent);              
            list.get(position).getUrl();                
            Model element = (Model) viewHolder.addbutton
                      .getTag();
                  element.setSelected(true);
        }
      });
  view.setTag(viewHolder);
  viewHolder.addbutton.setTag(list.get(position));
} else {
  view = convertView;
  ((ViewHolder) view.getTag()).addbutton.setTag(list.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(list.get(position).getName());      
return view;

}

Edit: I think it has something to do with calling the onClickListener with a wrong viewHolder but I can't quite figure it out...

Upvotes: 0

Views: 2069

Answers (2)

Edward van Raak
Edward van Raak

Reputation: 4910

I fixed it myself after many painful attempts. It was a lack of understanding how ListView optimization operates and what the convertView parameter does ...

I moved my onClickListener outside the if (convertView == null) block and placed it right before getView returns its view. This way the location that is taken is not the recycled visable location but the ACTUAL location all the way from the top.

@Override
  public View getView(final int position, View convertView, ViewGroup parent) {
    View view = null;
    final AiringModel am = list.get(position);      
    am.setRealPosition(position, list.get(position).getUrl());    
    LayoutInflater inflator = context.getLayoutInflater();      
    view = inflator.inflate(R.layout.addtowatchlist, null);
    final ViewHolder viewHolder = new ViewHolder();
    viewHolder.text = (TextView) view.findViewById(R.id.label);
    if (convertView == null) {
        view.setTag(viewHolder);     
    } else {
      view = convertView;
      ((ViewHolder)view.getTag()).addbutton.setTag(list.get(position));      
    }
    ViewHolder holder = (ViewHolder) view.getTag();
    holder.text.setText(list.get(position).getName());       
    viewHolder.addbutton = (Button) view.findViewById(R.id.check);    
    viewHolder.addbutton.setTag((Integer)position);    
    viewHolder.addbutton
    .setOnClickListener(new Button.OnClickListener() {
        @Override
        public void onClick(View buttonview) {
            // TODO Auto-generated method stub                  
            int realPosition = am.getRealPosition();
            String realName = am.getRealName();
            Log.d("Pair created!", "Clicked button with position: "+ realPosition + " For item name: " + realName);
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(list.get(realPosition).getUrl()));
            context.startActivity(browserIntent);           
        }
    });
    return view;
  }

Upvotes: 0

Thommy
Thommy

Reputation: 5407

The variable position is already the position of the entry in your ListView.
I don't know what is inside your List.
Here is a tutorial how the BaseAdapter works and how you build your getView right: http://thinkandroid.wordpress.com/2010/01/13/custom-baseadapters/

Upvotes: 1

Related Questions