Making ListView Scrolling Smooth position?

1.3k Views Asked by At

I read the article about "Making ListView Scrolling Smooth" on android.developer.com but there is one thing I don't understand : where to put or get the value of "position" because my eclipse says :"Cannot refer to a non-final variable position inside an inner class defined in a different method". I put this code in my adapter class in the getView method.

package com.example.filemanager;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Formatter.BigDecimalLayoutForm;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.DateSorter;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class ItemAdapter extends ArrayAdapter<Item> {
private final Context context;
private final ArrayList<Item> values;
public int position;

public ItemAdapter(Context context, ArrayList<Item> values) {
    super(context, R.layout.item, values);
    this.context = context;
    this.values = values;
}

@Override
public Item getItem(int position) {
    // TODO Auto-generated method stub
    return super.getItem(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub



    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.item, parent, false);
    TextView title = (TextView) rowView.findViewById(R.id.title);
    TextView info = (TextView) rowView.findViewById(R.id.info);
    ImageView icon = (ImageView) rowView.findViewById(R.id.icon);
    ImageView menu = (ImageView) rowView.findViewById(R.id.menu);

    title.setText(values.get(position).getName());
    info.setText(sizeString(position) + " " + dateString(position) + " "
            + rightsString(position));

    if (values.get(position).isisDir()) {
        icon.setImageResource(R.drawable.dir);
    } else if (!values.get(position).isisDir()) {

        if (values.get(position).getPath().endsWith(".jpg")
                || values.get(position).getPath().endsWith(".png")) {

            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 50;
            options.inDensity = 100;
            options.inScreenDensity = 1;

            Bitmap myBitmap = BitmapFactory.decodeFile(values.get(position).getPath(), options);                
            icon.setImageBitmap(myBitmap);
        }else{

            icon.setImageResource(R.drawable.file);
        }

    }

    menu.setImageResource(R.drawable.menu);



    ViewHolder holder = new ViewHolder();
    holder.icon = (ImageView) convertView.findViewById(R.id.icon);
    holder.menu = (ImageView) convertView.findViewById(R.id.menu);
    holder.title = (TextView) convertView.findViewById(R.id.title);
    holder.info = (TextView) convertView.findViewById(R.id.info);
    holder.progress = (ProgressBar) convertView.findViewById(R.id.progressSpinner);
    convertView.setTag(holder);



    // Using an AsyncTask to load the slow images in a background thread
            new AsyncTask<ViewHolder, Void, Bitmap>() {
                private ViewHolder v;

                @Override
                protected Bitmap doInBackground(ViewHolder... params) {
                    v = params[0];
                    //return mFakeImageLoader.getImage();



                    return null;
                }

                @Override
                protected void onPostExecute(Bitmap result) {
                    super.onPostExecute(result);
                    if (v.position == position) {
                        // If this item hasn't been recycled already, hide the
                        // progress and set and show the image
                        v.progress.setVisibility(View.GONE);
                        v.icon.setVisibility(View.VISIBLE);
                        v.icon.setImageBitmap(result);
                    }
                }
            }.execute(holder);






    return rowView;
}

private String rightsString(int position) {
    String temp = "";
    if (values.get(position).isReadable()) {
        temp += "r";
    } else {
        temp += "-";
    }
    if (values.get(position).isWritable()) {
        temp += "w";
    } else {
        temp += "-";
    }
    if (values.get(position).isExecutable()) {
        temp += "x";
    } else {
        temp += "-";
    }
    return temp;
}

private String dateString(int position) {
    DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    return df.format(values.get(position).getDate());
}

private String sizeString(int position) {

    long bytes = values.get(position).getSize();

    double kb = bytes / 1024.0;
    double mb = kb / 1024.0;
    double gb = mb / 1024.0;

    if (gb >= 1) {
        return gb + " GB";
    }
    if (mb >= 1) {
        return mb + " MB";
    }
    if (kb >= 1) {
        return kb + " KB";
    } else {
        return bytes + " bytes";
    }

}


static class ViewHolder {

    ImageView icon, menu;
    TextView title, info;
    ProgressBar progress;
    int position;

}

}

1

There are 1 best solutions below

0
On

Okay, so you need to understand a little bit about outer,inner and anonymous classes,etc. What's going on is that you are creating an anonymous class with the declaration of

new AsyncTask()....

and any variables inside of that class need to be final or not referencing the parent class.

So, what you need to do is this:

final int finalPosition = position;


// Using an AsyncTask to load the slow images in a background thread
    new AsyncTask() {
    private ViewHolder v;

    @Override
    protected Bitmap doInBackground(ViewHolder... params) {
       v = params[0];
       return null;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
       super.onPostExecute(result);
       if (v.position == finalPosition) {
           // If this item hasn't been recycled already, hide the
           // progress and set and show the image
           v.progress.setVisibility(View.GONE);
           v.icon.setVisibility(View.VISIBLE);
           v.icon.setImageBitmap(result);
           }
        }
    }.execute(holder);

Reference