2012-03-27 18 views
1

フランス語の開発者として、私は自分の英語について謝罪します。Android - ListViewの問題

私の目的は、Androidアプリケーション用の電話帳を作成することです。この電話帳はListViewで作成されています。私は、ユーザーが各行でいくつかのTextViewsを選択できるカスタムアダプタで私のListViewを実装しました。 私は、絵は千個の言葉よりも優れていると推定ので、ここにある:

enter image description here

あなたが見ることができるように赤い部分は、私が選択したTextViewsです。 私が直面しなければならない問題は以下の通りです:

行からTextViewを選択すると、4桁下の行にはTextViewも選択されています!これは共通の問題ですか、それとも私のコードによるのでしょうか?

クリックリスナーにログを追加しました。クリックしたTextViewごとに1つのログのみが表示されるため、私の仕事で問題が発生するとは思われません。

例えば、あなたの何人かが私が言ったことを理解していない場合、 2番目の行のdrawableLeft画像でTextViewを選択します。 logcatは私に次のエントリを返します: "Select:1"(私のコードで定義されているように)。 ListViewをスクロールすると、2番目の行(つまりTextView)が期待どおりに選択されていることがわかります。

public View getView(final int position, View convertView, ViewGroup parent) 
{ 
    selectedLocations.add(new Boolean(false)); 
    selectedAvailabilities.add(new Boolean(false)); 

    if (convertView == null) convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false); 

    final LinearLayout root = (LinearLayout) convertView.findViewById(R.id.phonebook_adapter_root); 
    final ImageView photo = (ImageView) convertView.findViewById(R.id.phonebook_adapter_image); 
    final TextView firstname = (TextView) convertView.findViewById(R.id.phonebook_adapter_firstname); 
    final TextView lastname = (TextView) convertView.findViewById(R.id.phonebook_adapter_lastname); 
    final TextView location = (TextView) convertView.findViewById(R.id.phonebook_adapter_location); 
    final TextView availability = (TextView) convertView.findViewById(R.id.phonebook_adapter_availability); 

    Bitmap mBitmap = null; 
    try 
    { 
     mBitmap = Media.getBitmap(context.getContentResolver(), Uri.parse(relations.get(position).getPhoto())); 
     photo.setImageBitmap(mBitmap); 
    } 
    catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 

    firstname.setText(relations.get(position).getFirstName()); 
    lastname.setText(relations.get(position).getLastName()); 

    DBStatus dbStatus = new DBStatus(KramerApplication.getInstance()); 
    Status status = dbStatus.getWithRelation(relations.get(position)); 
    dbStatus.close(); 

    if (status != null) 
    {   
     location.setText(status.getLocation()); 
     availability.setText(status.getAvailability()); 

     if (status.getDisplayedAvailability(2).equals("Busy")) 
      availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_busy, 0, 0, 0); 
     else if (status.getDisplayedAvailability(2).equals("Occupied")) 
      availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_busy, 0, 0, 0); 
     else if (status.getDisplayedAvailability(2).equals("Free")) 
      availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_on, 0, 0, 0); 
     else 
      availability.setCompoundDrawablesWithIntrinsicBounds(R.drawable.availability_off, 0, 0, 0); 
    } 

    root.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) 
     { 
      Intent intent = new Intent(context, ContactDetailsActivity.class); 
      intent.putExtra("contact_id", relations.get(position).getId()); 
      context.startActivity(intent); 
     } 
    }); 

    location.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) 
     { 
      if (selectedLocations.get(position).booleanValue()) 
      { 
       selectedLocations.set(position, new Boolean(false)); 
       location.setBackgroundColor(Color.TRANSPARENT); 
      } 
      else 
      { 
       selectedLocations.set(position, new Boolean(true)); 
       location.setBackgroundColor(Color.RED); 
      } 
     } 
    }); 
    availability.setOnClickListener(new OnClickListener() { 
     public void onClick(View v) 
     { 
      if (selectedAvailabilities.get(position).booleanValue()) 
      { 
       selectedAvailabilities.set(position, new Boolean(false)); 
       availability.setBackgroundColor(Color.TRANSPARENT); 
      } 
      else 
      { 
       selectedAvailabilities.set(position, new Boolean(true)); 
       availability.setBackgroundColor(Color.RED); 
      } 
     } 
    }); 

    return convertView; 
} 

のArrayList「selectedAvailabilities」と「selectedLocationsは」適切にコンストラクタで初期化され、私はそれらを使用するときに自分の仕事をされています。ここでは

は、私は色やない行するために使用するコードです。別のアクティビティで(読み込み専用)。

私はあなたを助けてくれることを願っています。

よろしくお願いいたします。

V.

################################# SOLUTION

誰かが見ている場合解決策については、ここにあります。 user936414!ありがとう!

交換してください(6行目):

if (convertView == null) convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false); 

で:

convertView = inflater.inflate(R.layout.phonebook_adapter_layout, parent, false); 

前:

return convertView; 

追加:

if (selectedAvailabilities.get(position).booleanValue()) 
{ 
    availability.setBackgroundColor(Color.RED); 
} 
if (selectedLocations.get(position).booleanValue()) 
{ 
    location.setBackgroundColor(Color.RED); 
} 

答えて

4

この動作の理由は、convertviewの使用です。これを解決するには、HashSetを用意し、選択したすべての位置をHashSetに配置します。 getViewには、TextViewのHashsetとsetSelectedのチェックが含まれています。お役に立てれば。

はconvertViewはあなたの条件には影響を与えないようにすることもonClickListener外

if (selectedLocations.get(position).booleanValue()) 
{ 
      location.setBackgroundColor(Color.RED); 
} 
else 
{ 

      location.setBackgroundColor(Color.TRANSPARENT); 
} 

を追加します。

+0

まあ、私はなぜ私は、ジョブを行うArrayListを持っている場合、HashSetを使用することを理解していない! convertViewを使用する際の問題点は何ですか? – Manitoba

+0

前のビューの変換されたビューをスクロールすると、ここでレンダリングされます。そのため、スクロール前のconvertviewで選択された位置がここに反映されるのはなぜでしょうか。 – user936414

+0

元のビューを再利用しない方法はありますか?私の定義したレイアウトを使って新しいビューを作成したいのですか? – Manitoba