Android ListView:如何解决ListView显示错位的内容

时间:2014-08-09 02:14:32

标签: android listview android-listview android-volley

在ListView适配器的getView方法中,我通过Volley加载userIcon,但是当我滚动listview时,userIcon已经错位,我认为由于加载网络资源耗时,我该如何解决呢?这是代码:

public class DictationResultAdapter extends BaseAdapter {
public DictationResultAdapter( Context context, ArrayList<UserScoreInfo> userInfoList, Typeface typeface, String userId ){
    mUserInfoList = userInfoList;
    mTypeface = typeface;
    mUserId = userId;
    mContext = context;

    mLayoutInflater = ( LayoutInflater )context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
    mQueue = Volley.newRequestQueue(context);  
    mImageLoader = new ImageLoader(mQueue, new UserIconBitmapCache());
}

@Override
public int getCount() {
    if( ListUtils.isEmpty( mUserInfoList ) ){
        return 0;
    }

    return mUserInfoList.size( );
}

@Override
public Object getItem(int position) {
    if( ListUtils.isEmpty( mUserInfoList ) ){
        return null;
    }

    return mUserInfoList.get( position );
}

@Override
public long getItemId(int position) {
    if( ListUtils.isEmpty( mUserInfoList ) ){
        return 0;
    }

    return position;
}

public int getPosition( ){
    return mMyPosition;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    mViewHolder = new ViewHolder( );

    convertView = mLayoutInflater.inflate( R.layout.adapter_score_list_layout, null );
    mViewHolder.mScoreLayout = ( RelativeLayout )convertView.findViewById( R.id.scoreLayoutId );
    mViewHolder.mScoreLayout.setClickable( false );
    mViewHolder.mPositionTxt = ( TextView )convertView.findViewById( R.id.positionTxtId );
    mViewHolder.mUserNameTxt = ( TextView )convertView.findViewById( R.id.userNameTxtId );
    mViewHolder.mUserNameTxt.setTypeface( mTypeface );
    mViewHolder.mUserIconImg = ( ImageView )convertView.findViewById( R.id.userIconImgId );
    mViewHolder.mUserScoreTxt = ( TextView )convertView.findViewById( R.id.userScoreTxtId );

    showContent( position, mUserInfoList.get( position ) );
    return convertView;
}

private void showContent( int index, UserScoreInfo userInfo ){
    switch( index ){
    case 0:{
        mViewHolder.mUserIconImg.setBackgroundResource( R.drawable.chinese_dictation_score_1 );
        mViewHolder.mPositionTxt.setVisibility(TextView.GONE);
    }
    break;
    case 1:{
        mViewHolder.mUserIconImg.setBackgroundResource( R.drawable.chinese_dictation_score_2 );
        mViewHolder.mPositionTxt.setVisibility(TextView.GONE);
    }
    break;
    case 2:{
        mViewHolder.mUserIconImg.setBackgroundResource( R.drawable.chinese_dictation_score_3 );
        mViewHolder.mPositionTxt.setVisibility(TextView.GONE);
    }
    break;
    default:{
        handleUserIcon( mImageLoader, userInfo, mUserId );

        mViewHolder.mPositionTxt.setVisibility(TextView.VISIBLE);
        mViewHolder.mPositionTxt.setText( "第" + userInfo.getScoreRank( ) + "名" );
    }
    break;
    }

    if( mUserId.equals( userInfo.getUserId( ) ) ){
        mMyPosition = index;
        mViewHolder.mScoreLayout.setBackgroundResource( R.drawable.chinese_dictation_score_list_select );
    }else{
        mViewHolder.mScoreLayout.setBackgroundResource( R.drawable.chinese_dictation_score_list_normal );
    }

    String userName = userInfo.getNickName( );
    if( !TextUtils.isEmpty( userName ) ){
        userName = ( userName.length( ) > 10 )?( userName.substring(0, 7) + "..." ):userName;
    }else{
        userName = "匿名";
    }

    if( mUserId.equals( userInfo.getUserId( ) ) ){
        String localUserName = PersonalInfo.getCurrentUserName( mContext );
        mMyPosition = index;
        mViewHolder.mScoreLayout.setBackgroundResource( R.drawable.chinese_dictation_score_list_select );
        if( TextUtils.isEmpty( userName ) || ( !localUserName.equals( userName ) ) ){
            mViewHolder.mUserNameTxt.setText( localUserName  );
        }else{
            mViewHolder.mUserNameTxt.setText( userName  );
        }

    }else{
        mViewHolder.mScoreLayout.setBackgroundResource( R.drawable.chinese_dictation_score_list_normal );
        mViewHolder.mUserNameTxt.setText( userName );
    }

    mViewHolder.mUserScoreTxt.setText( StringUtils.getSplitByComma( userInfo.getScore( ) + "" ) );
}

public void handleUserIcon(ImageLoader imageLoader, final UserScoreInfo userInfo, final String userId ){
    if(!TextUtils.isEmpty( userInfo.getPictureUrl( ) )){
        imageLoader.get(userInfo.getPictureUrl( ), new ImageListener() {
           @Override
           public void onErrorResponse(VolleyError error) {
               mViewHolder.mUserIconImg.setImageResource(R.drawable.user_icon);
           }

           @Override
           public void onResponse(ImageContainer response, boolean isImmediate) {
               Bitmap bitmap = null;
               if( TextUtils.isEmpty( userId ) || !userId.equals( userInfo.getUserId( ) ) ){
                   bitmap = response.getBitmap();
               }else{
                   bitmap = PersonalInfo.getCurrentUserIcon( mContext );
               }

               if (bitmap != null) {
                   Matrix matrix = new Matrix();  
                   matrix.postScale( 50.0f/bitmap.getWidth( ), 50.0f/bitmap.getHeight( ) );
                   Bitmap cutBitmap = Bitmap.createBitmap( bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight( ), matrix, true); 

                   mViewHolder.mUserIconImg.setImageBitmap(BitmapUtils.toRoundBitmap( cutBitmap ));

                   if( null != cutBitmap && !cutBitmap.isRecycled( ) ){
                       cutBitmap.recycle( );
                   }

               } else {
                   mViewHolder.mUserIconImg.setImageResource(R.drawable.user_icon);
               }
           }
       }); 
    }else{
        mViewHolder.mUserIconImg.setImageResource(R.drawable.user_icon);
    }}

class ViewHolder{
    private RelativeLayout mScoreLayout = null;
    public TextView mPositionTxt = null;
    public TextView mUserNameTxt = null;
    public ImageView mUserIconImg = null;
    public TextView mUserScoreTxt = null;
}

private RequestQueue mQueue = null;  
private ImageLoader mImageLoader = null;
private Context mContext = null;
private String mUserId = null;
private Typeface mTypeface = null;
private ArrayList<UserScoreInfo> mUserInfoList = null;
private LayoutInflater mLayoutInflater = null;
private ViewHolder mViewHolder = null;
private int mMyPosition = -1;}

1 个答案:

答案 0 :(得分:1)

首先我不认为你的程序有任何问题,我认为这是因为图像还没有从互联网上完全下载。为了确认这一点,你可以滚动列表并突然停止它,看看错误的图像是否被正确替换一个或不!您可以通过在请求中使用占位符图像和错误图像来解决此问题,如下所示:

imageLoader.get(URL_IMAGE, ImageLoader.getImageListener(
                imageView, R.drawable.ico_loading, R.drawable.ico_error));

我的建议是将ImageLoader和NetworkImageView一起用于图像请求。有关更多信息,请查看:http://developer.android.com/training/volley/request.html

与您的问题无关的另一个问题是您使用ViewHolder。你正在错误地使用这种设计模式,并没有给你任何表现。使用它的概念是消除对findViewByID的不必要的调用,但对于每一行,您为每个视图调用此函数。搜索网了解更多信息。