Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發經驗分享-GridView、ListView內容錯亂

Android開發經驗分享-GridView、ListView內容錯亂

編輯:關於Android編程

在使用GridView、ListView的過程中遇到內容錯亂的問題,費了較長時間才找到問題的根源,特地總結一下。

1、在自定義adapter中沒有給每一項都設置內容導致內容錯亂:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
	if( null == convertView ){
		mGridHolder = new GridHolder( );
        
    convertView = mLayoutInflater.inflate( R.layout.view_log_word_item_layout, null );
    
    mGridHolder.mBackTopLayout = (LinearLayout)convertView.findViewById( R.id.logItemTopLayoutId);
    mGridHolder.mBackBottomLayout = ( RelativeLayout )convertView.findViewById( R.id.logItemBottomLayoutId );
    mGridHolder.mRightWordTxt = ( TextView )convertView.findViewById( R.id.rightWordTxtId );
    mGridHolder.mUserWriteImg = ( ImageView )convertView.findViewById( R.id.userWordImgId );
    mGridHolder.mWriteResultImg = ( ImageView )convertView.findViewById( R.id.writeResultImgId );
    mGridHolder.mReasonTxt = ( TextView )convertView.findViewById( R.id.reasonTxtId );
    mGridHolder.mRightWordTxt.setTypeface( mTypeface );
	
	  convertView.setTag( mGridHolder );
  }else{
  	mGridHolder = ( GridHolder )convertView.getTag( );
  }
	
  showContent( mDictationInfoList.get( position ) );
    
  return convertView;
}

@SuppressWarnings("deprecation")
private void showContent( DictationInfo dictationInfo ){
    mGridHolder.mRightWordTxt.setText( dictationInfo.getmWord( ) );
    if( null != dictationInfo.getmDrawable( ) ){
    	mGridHolder.mUserWriteImg.setBackgroundDrawable( dictationInfo.getmDrawable( ) );
        
    	if( !TextUtils.isEmpty( dictationInfo.getDetailReason( ) ) ){
    		mGridHolder.mReasonTxt.setText( dictationInfo.getDetailReason( ) );
    	}else{
    		mGridHolder.mReasonTxt.setText( "" );
    	}
    	
      setWriteResult( dictationInfo.getmWriteResult( ) );
    }else{
        // 沒有為內容項為空的項設置內容
    }
}


上面是一個自定義adapter中的一段代碼,在getView中為每一項設置內容時只處理了有內容的項,沒有內容的項沒有賦值,導致在滑動內容時內容錯亂,分析發現這是由於使用了adapter的緩存機制導致的,正確的處理方式是需要為內容為空的項也要賦值,修改後的代碼如下:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
	if( null == convertView ){
		mGridHolder = new GridHolder( );
        
    convertView = mLayoutInflater.inflate( R.layout.view_log_word_item_layout, null );
    
    mGridHolder.mBackTopLayout = (LinearLayout)convertView.findViewById( R.id.logItemTopLayoutId);
    mGridHolder.mBackBottomLayout = ( RelativeLayout )convertView.findViewById( R.id.logItemBottomLayoutId );
    mGridHolder.mRightWordTxt = ( TextView )convertView.findViewById( R.id.rightWordTxtId );
    mGridHolder.mUserWriteImg = ( ImageView )convertView.findViewById( R.id.userWordImgId );
    mGridHolder.mWriteResultImg = ( ImageView )convertView.findViewById( R.id.writeResultImgId );
    mGridHolder.mReasonTxt = ( TextView )convertView.findViewById( R.id.reasonTxtId );
    mGridHolder.mRightWordTxt.setTypeface( mTypeface );
	
	  convertView.setTag( mGridHolder );
  }else{
  	mGridHolder = ( GridHolder )convertView.getTag( );
  }
	
  showContent( mDictationInfoList.get( position ) );
    
  return convertView;
}

@SuppressWarnings("deprecation")
private void showContent( DictationInfo dictationInfo ){
    mGridHolder.mRightWordTxt.setText( dictationInfo.getmWord( ) );
    if( null != dictationInfo.getmDrawable( ) ){
    	mGridHolder.mUserWriteImg.setBackgroundDrawable( dictationInfo.getmDrawable( ) );
        
    	if( !TextUtils.isEmpty( dictationInfo.getDetailReason( ) ) ){
    		mGridHolder.mReasonTxt.setText( dictationInfo.getDetailReason( ) );
    	}else{
    		mGridHolder.mReasonTxt.setText( "" );
    	}
    	
      setWriteResult( dictationInfo.getmWriteResult( ) );
    }else{
        mGridHolder.mUserWriteImg.setBackgroundResource( Color.TRANSPARENT );
        mGridHolder.mReasonTxt.setText( "" );
        mGridHolder.mWriteResultImg.setBackgroundResource( R.drawable.log_unknown );
        mGridHolder.mBackTopLayout.setBackgroundResource( R.drawable.log_item_wrong_top_background );
        mGridHolder.mBackBottomLayout.setBackgroundResource( R.drawable.log_item_wrong_bottom_background );
    }
}

2、在自定義adapter的getview方法中,每一項的內容加載時間過長導致內容錯亂。

@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 ){
    // 從網絡獲取頭像
    handleUserIcon( mImageLoader, userInfo, mUserId );
    mViewHolder.mPositionTxt.setVisibility(TextView.VISIBLE);
    mViewHolder.mPositionTxt.setText( "第" + userInfo.getScoreRank( ) + "名" );
    
    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( ) + "" ) );
}
上面是一個獲取用戶排名列表所自定義adapter中的一段代碼,handleUserIcon方法是從網絡獲取用戶頭像,在滑動排名列表的時候發現用戶頭像會錯亂,最後跟蹤找到具體的原因是由於從網絡獲取用戶頭像耗時,正確的做法應該是在獲取完成用戶頭像之後再通知adapter更新。


在使用gridview和listview的過程中,由於需要加載大量的內容,android建議我們采用viewholder的緩存機制,這樣能夠提高列表加載的效率,但是在使用的過程中一定要注意上面這兩個問題,否則可能會讓你很頭疼。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved