2014-02-21 25 views
0

我有一個帶有照片的名稱和CheckBox的ListView列表顯示。包含List的活動還包含一個搜索欄,我已經使用EditText和TextChangedListener實現了該列表,該列表也啓用了多選模式。通常,當搜索欄中沒有任何內容時,CheckBox會返回列表中項目的正確位置。但是,只要用戶在搜索欄中鍵入一些文本,ListView就會更新,現在如果某個特定的複選框與特定點擊列表中的行將返回錯誤的項目(不同的列表項目)。我不明白爲什麼會發生這種情況。我的代碼如下:在每個列表項和一個搜索欄中使用CheckBox的getView()方法在getView()方法中使用getItem(position)時出現錯誤的項目

FriendPicker活動(包含列表和搜索欄: - 所述onCreate方法的相關代碼):

  public class FriendPicker extends Activity 
      { 
       EditText inputSearch; 
       FriendListAdapter adapter; 
       ArrayList<Friend> friends, searchResults; 
       List<GraphUser> FriendList = null , selected = null; 
       ListView listView; 
       ImageView img = null; 
       @Override 
       protected void onCreate(Bundle savedInstanceState) 
       { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_friend_picker); 

        CliqueApplication application = (CliqueApplication) getApplication(); 
        FriendList = application.getSelectedUsers(); 

        friends = new ArrayList<Friend>(); 
        selected = new ArrayList<GraphUser>();searchResults = new ArrayList<Friend>(friends); 
        listView = (ListView) findViewById(R.id.friendlist); 
        adapter = new FriendListAdapter(this,R.layout.friend, searchResults); 
        listView.setAdapter(adapter); 
        inputSearch = (EditText) findViewById(R.id.inputSearch); 
        img = (ImageView) findViewById(R.id.done); 

        inputSearch.addTextChangedListener(new TextWatcher() 
        { 

         @Override 
         public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) 
         { 
          // When user changed the Text 
          //FriendPicker.this.adapter.getFilter().filter(cs); 
          String searchString=inputSearch.getText().toString(); 
           int textLength=searchString.length(); 

             //clear the initial data set 
           searchResults.clear(); 

           for(int i=0;i<friends.size();i++) 
           { 
            String playerName=friends.get(i).getName().toString(); 
            if(textLength<=playerName.length()) 
            { 
            //compare the String in EditText with Names in the ArrayList 
            if(searchString.equalsIgnoreCase(playerName.substring(0,textLength))) 
            searchResults.add(friends.get(i)); 
            } 
           } 
           //adapter.setData(searchResults); 
           adapter.notifyDataSetChanged(); 
           //adapter.setData(friends); 
         } 

       @Override 
       public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
         int arg3) 
       { 

       } 

       @Override 
       public void afterTextChanged(Editable arg0) 
       {       
       } 
       }); 
      } 

FriendListAdapter.java

   public class FriendListAdapter extends ArrayAdapter<Friend> 
    { 
     ArrayList<Friend> data = null; 
     Context context; 
     public FriendListAdapter(Context context, int resourceId,ArrayList<Friend> items) 
     { 
      super(context, resourceId, items); 
      this.context = context; 
      this.data = items; 

     } 
     private class ViewHolder 
     { 
      ImageView Photo; 
      TextView Name; 
      CheckBox box; 
     } 

     public View getView(int position, View convertView, ViewGroup parent) 
     { 
      ViewHolder holder = null; 
      final Friend friend = getItem(position); 
      //final Friend friend = (Friend)(parent.getItemAtPosition(position)); 
      LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
      if (convertView == null) 
      { 
       convertView = mInflater.inflate(R.layout.friend, null); 
       holder = new ViewHolder(); 
       holder.Photo = (ImageView) convertView.findViewById(R.id.fphoto); 
       holder.Name = (TextView) convertView.findViewById(R.id.fname); 
       holder.box = (CheckBox) convertView.findViewById(R.id.chkbx); 
       holder.box.setOnClickListener(new View.OnClickListener() 
       { 
        public void onClick(View v) 
        { 
        CheckBox cb = (CheckBox) v ; 
        //Friend friend = (Friend) cb.getTag(); 
        friend.setSelected(cb.isChecked()); 
        Log.i("Friend Adapter", friend.getName() + " checked is "+cb.isChecked()); 
        //friend.setSelected(true); 
        } 
        }); 
       convertView.setTag(holder); 
      } 
      else 
      holder = (ViewHolder) convertView.getTag(); 
      if (friend.getPhoto() != null) 
      { 
       holder.Photo.setImageBitmap(friend.getPhoto()); 
      } 
      else 
      { 
       holder.Photo.setImageResource(R.drawable.generic_profile_man); 
      } 
      holder.Name.setText(friend.getName()); 
      holder.box.setChecked(friend.isSelected()); 
      //holder.Name.setTag(friend); 
      return convertView; 
     } 
    } 

我還有一個疑問,當我在onTextChanged方法中調用adapter.notifyDataSetChanged()時,爲什麼FriendListAdapter中的數據未顯示使用期望的結果getView()方法中的getItem(position)?

回答

2

與列表中的某個特定行相關的複選框被點擊的時候,因爲你沒有在OnClickListener.onClick方法得到正確的朋友對象 返回錯誤的項目(不同的列表項)

convertView如果它不爲空,則不會虛增,因此您的實例爲OnClickListener。並且您將使用該實例的初始朋友實例來處理您的重用視圖。

要解決這個問題:

1)在getView方法的末尾設置當前的朋友對象爲您的複選框的標籤:

holder.box.setTag(friend); 
return convertView; 

2)你可以做你需要OnClickListener,但我更喜歡使用CheckBox的OnCheckedChangeListener:

holder.box.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

    @Override 
    public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) { 
     CheckBox cb = (CheckBox) buttonView ; 
     Friend friend = (Friend) cb.getTag(); 
     friend.setSelected(isChecked); 
     Log.i("Friend Adapter", friend.getName() + " checked is "+isChecked); 
    } 
} 
+0

我試過第一種方法,它的工作正常。但第二種方法工作不正常。無論如何非常感謝您的回答:)我的問題已修復。 – SlashGeek

+1

其實2個項目合併。它們不是彼此的替代品。你必須使用兩者。 – Devrim

相關問題