AsyncTask breaks custom listview

2019-07-08 08:16发布

问题:

Hey I have a listview which I load from a resource using asynctask and show progress bar before loading list.

Currently, the progress bar doesn't show up at the start and it breaks the list as well. Any help would be appreciated, by breaking the list I mean it loads elements on top of each other like this instead of 10 elements at once which was working fine before including async task.

Code for activity:

public class MovieRatingsActivity extends ListActivity
{
 private ArrayList<Movie> movies = new ArrayList<Movie>();
 private LayoutInflater mInflater;


/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    initializeUI();
}

private void initializeUI()
{
    new LoadList().execute();
}

public class LoadList extends AsyncTask<Void,Void,ArrayList<Movie>>{
    ProgressDialog loading = null;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        try {
            loading = new ProgressDialog(getApplicationContext());
            loading.setCancelable(true);
            loading.setMessage("Loading Data...");
            loading.setIndeterminate(true);
            loading.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            loading.show();
        }
        catch(Exception e){
        Log.d(TAG, "Exception: >> "+e.toString());
        }
    }

    @Override
    protected ArrayList<Movie> doInBackground(Void... aVoid){
        InputStream inputStream = getResources().openRawResource(
                R.raw.ratings);
        movies = Movie.loadFromFile(inputStream);

        return movies;
    }
    @Override
    protected void onPostExecute(ArrayList<Movie> movies) {
        super.onPostExecute(movies);
        loading.hide();
        mInflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        setListAdapter(new RowIconAdapter(getApplicationContext(), R.layout.listrow, R.id.row_label, movies));
    }
}

//declare a static holder class
public static class ViewHolder{
    ImageView icon;
    TextView movieText,votesText;
}

/** Custom row adatper -- that displays an icon next to the movie name */
class RowIconAdapter extends ArrayAdapter<Movie> 
{
    private ArrayList<Movie> movies;        
    public RowIconAdapter(Context c, int rowResourceId, int textViewResourceId, 
            ArrayList<Movie> items)
    {
        super(c, rowResourceId, textViewResourceId, items);
        movies  = items;
    }

    public View getView(int pos, View convertView, ViewGroup parent)
    {

        //declare a holder object
        ViewHolder holder;
        Movie currMovie = movies.get(pos);

        //nly inflate view once and get all the views once
        if (convertView == null)
        {
            convertView = mInflater.inflate(R.layout.listrow, parent, false);
            holder = new ViewHolder();
            holder.icon = (ImageView) convertView.findViewById(R.id.row_icon);
            holder.movieText = (TextView) convertView.findViewById(R.id.row_label);
            holder.votesText= (TextView) convertView.findViewById(R.id.row_subtext);

            //set the holder class
            convertView.setTag(holder);
        }

        else{
            //get all the views once done
            holder = (ViewHolder) convertView.getTag();
        }

        //set all the values in the list
        holder.movieText.setText(currMovie.getName());
        String votesStr = currMovie.getVotes()+" votes";
        holder.votesText.setText(votesStr);
        Bitmap movieIcon = getMovieIcon(currMovie.getName(), currMovie.getRating());
        holder.icon.setImageBitmap(movieIcon);

        return convertView;
    }
}

    /** Creates a unique movie icon based on name and rating */
private Bitmap getMovieIcon(String movieName, String movieRating)
{
    int bgColor = getColor(movieName);
    Bitmap b = Bitmap.createBitmap(48, 48, Bitmap.Config.ARGB_8888);
    b.eraseColor(bgColor); // fill bitmap with the color
    Canvas c = new Canvas(b);
    Paint p = new Paint();
    p.setAntiAlias(true);
    p.setColor(getTextColor(bgColor));
    p.setTextSize(24.0f);
    c.drawText(movieRating, 8, 32, p);
    return b;
}

/** Construct a color from a movie name */
private int getColor(String name)
{
    String hex = toHexString(name);
    String red = "#"+hex.substring(0,2);
    String green = "#"+hex.substring(2,4);
    String blue = "#"+hex.substring(4,6);
    String alpha = "#"+hex.substring(6,8);
    int color = Color.argb(Integer.decode(alpha), Integer.decode(red), 
                            Integer.decode(green), Integer.decode(blue));
    return color;
}

/** Given a movie name -- generate a hex value from its hashcode */
private String toHexString(String name)
{
    int hc = name.hashCode();
    String hex = Integer.toHexString(hc);
    if (hex.length() < 8)
    {
        hex = hex+hex+hex;
        hex = hex.substring(0,8); // use default color value
    }
    return hex;
}

/** Crude optimization to obtain a contrasting color -- does not work well yet */
private int getTextColor(int bg)
{

    int r = Color.red(bg);
    int g = Color.green(bg);
    int b = Color.blue(bg);
    String hex = Integer.toHexString(r)+Integer.toHexString(g);
    hex += Integer.toHexString(b);

    int cDec = Integer.decode("#"+hex);
    if (cDec > 0xFFFFFF/2)  // go dark for lighter shades
        return Color.rgb(0, 0, 0);
    else
    {
        r = (r+128)%256;
        g = (g+128)%256;
        b = (b+128)%256;
        return Color.rgb(r,g,b);
    }
}


}

My layout :

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
    android:id="@android:id/list" 
    android:layout_height="fill_parent"  
    android:layout_width="match_parent" />
</LinearLayout>

ListRow layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:id="@+id/row_icon" android:padding="2dip"
    android:cacheColorHint="#00000000"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:src="@drawable/icon" />
<LinearLayout android:id="@+id/linearLayout1"
            android:orientation="vertical" 
            android:layout_height="match_parent" 
            android:layout_width="wrap_content">
    <TextView android:id="@+id/row_label" 
 android:layout_width="wrap_content"
        android:layout_height="match_parent" 
        android:text="Terminator 2"
        android:textSize="22sp" />
    <TextView android:id="@+id/row_subtext" 
  android:layout_width="wrap_content"
        android:layout_height="match_parent" 
        android:text="Rating: 5.5, 2340 votes"
        android:textSize="14sp" />          
</LinearLayout>

</LinearLayout>

THis is how it looks: