2011-01-03 26 views
7

リストビューでビューの背景を変更する際に問題があります。リストビューの変更 - 奇妙な動作

Iは必要なもの:
変更実際に何が起こる行のonClick()

の背景画像:背景が変更されます
を例えば押した後(選択)最初のエントリ。しかし、スクロールダウンした後、8番目のエントリも選択されます。 最初にスクロールしてもう一度選択しません。 2番目の項目が選択されました。 はスクロールを続け、それがどのような私は、コードに洞よ...

ジャンプ続けて:私は、チャネルの属性に を選択ブール値を切り替え、その後、私は変更
私はチャンネルを持っている、とのonClick()背景。 私はこれをやっています onClick()なぜ私はそれが他のエントリーでも起こっているのを知ることができません。 I通知 ことの一つは、次のとおりです。「それ自身で」選択した取得アイテムがまだ上選択値を持っているので、唯一の「描画」-partのようです

私はそれを持っているようだと思います

@Override 
    protected ViewHolder createHolder(View v) { 

     // createHolder will be called only as long, as the ListView is not 
     // filled 

     TextView title = (TextView) v 
       .findViewById(R.id.tv_title_channel_list_adapter); 
     TextView content = (TextView) v 
       .findViewById(R.id.tv_content_channel_list_adapter); 

     ImageView icon = (ImageView) v 
       .findViewById(R.id.icon_channel_list_adapter); 

     if (title == null || content == null || icon == null) { 
      Log.e("ERROR on findViewById", 
        "Couldn't find Title, Content or Icon"); 
     } 
     ViewHolder mvh = new MyViewHolder(title, content, icon); 

     // We make the views become clickable 
     // so, it is not necessary to use the android:clickable attribute in 
     // XML 

     v.setOnClickListener(new ChannelListAdapter.OnClickListener(mvh) { 

      public void onClick(View v, ViewHolder viewHolder) { 
       // we toggle the enabled state and also switch the the 
       // background 
       MyViewHolder mvh = (MyViewHolder) viewHolder; 
       Channel ch = (Channel) mvh.data; 
       ch.setSelected(!ch.getSelected()); // toggle 

       if (ch.getSelected()) { 
        v.setBackgroundResource(R.drawable.row_blue_selected); 
       } else { 
        v.setBackgroundResource(R.drawable.row_blue); 
       } 
       // TESTING 
       Log.d("onClick() Channel", "onClick() Channel: " 
         + ch.getTitle() + " selected: " + ch.getSelected()); 
      } 
     }); 
return mvh; 
    } 

コード:何かがカスタムListAdapters getViewメソッド内のビュー(...)

ListActivity中のonClick()のコードの再利用を行うにはgetViewメソッド(...)の:

@Override 
public View getView(int position, View view, ViewGroup parent) { 
    ViewHolder holder; 

    // When view is not null, we can reuse it directly, there is no need 
    // to reinflate it. 
    // We only inflate a new View when the view supplied by ListView is 
    // null. 
    if (view == null) { 
     view = mInflater.inflate(mViewId, null); 

     // call own implementation 
     holder = createHolder(view); 

     // TEST 
     // we set the holder as tag 
     view.setTag(holder); 

    } else { 
     // get holder back...much faster than inflate 
     holder = (ViewHolder) view.getTag(); 
    } 

    // we must update the object's reference 
    holder.data = getItem(position); 

      // <EDIT SOLUTION> 

    if(getItem(position).get_id() == channelList.get(position).get_id()){ 
     if(getItem(position).getSelected()) 
     { 
      view.setBackgroundResource(R.drawable.row_blue_selected); 
     } 
     else{ 
      view.setBackgroundResource(R.drawable.row_blue); 
     } 
    } 

      // </EDIT SOLUTION> 

    // call the own implementation 
    bindHolder(holder); 

    return view; 
} 

私は本当にこれを解決する方法任意のアイデアをいただければ幸いです! :)

詳細情報が必要な場合は教えてください。

ありがとうございます!

答えて

10

officeslistitemlayout.xmlファイルを追加し、次のようになります

public class Offices extends Activity { 

    private ListView listView; 

    /* selectedListItem will contain the number of items to be selected. 
    * Your list item OnOlickListener will simply change this variable 
    * to the position of the clicked item. The Adapter will do the rest 
    * because you need to refresh the ListView. 
    */ 
    private int selectedListItem = -1; 
    private Handler mHandler = new Handler(); 
    private Vector<String> data; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.officeslayout); 
     data = new Vector<String>(); 

     // Add data as per your requirement 
     data.add("one"); 
     data.add("two"); 
     data.add("three"); 
     data.add("four"); 
     data.add("Five"); 
     data.add("Six"); 
     data.add("Seven"); 
     data.add("Eight"); 
     data.add("Nine"); 
     data.add("Ten"); 

     listView = (ListView)findViewById(R.id.ListView01); 
     listView.setDivider(null); 

     listView.setOnItemClickListener(new OnItemClickListener() { 
      public void onItemClick(AdapterView<?> parent, View view, 
        int position, long id) { 

       selectedListItem = position; 
       ((EfficientAdapter)listView.getAdapter()).notifyDataSetChanged(); 

       mHandler.postDelayed(new Runnable() { 

        @Override 
        public void run() { 
         // call any new activity here or do any thing you want here   

        } 
       }, 200L); 
      } 
     }); 

     listView.setAdapter(new EfficientAdapter(getApplicationContext())); 
    } 

    private class EfficientAdapter extends BaseAdapter { 
     private LayoutInflater mInflater; 

     public EfficientAdapter(Context context) { 
      mInflater = LayoutInflater.from(context); 
     } 

     public int getCount() { 
      return data.size(); 
     } 

     public Object getItem(int position) { 
      return position; 
     } 

     public long getItemId(int position) { 
      return position; 
     } 

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

      ViewHolder holder; 

      if (convertView == null || convertView.getTag() == null) { 
       convertView = mInflater.inflate(R.layout.officeslistitemlayout, null); 
       holder = new ViewHolder(); 
       holder.backgroundView = (ImageView) convertView 
        .findViewById(R.id.OfficesBackground); 
       holder.officesTitle = (TextView) convertView 
        .findViewById(R.id.OfficesName); 

       convertView.setTag(holder); 
      } else { 
       holder = (ViewHolder) convertView.getTag(); 
      } 

      if(position == selectedListItem) { 
       holder.backgroundView.setBackgroundResource(R.drawable.and_gray_bg_listing_selected); 
      } else { 
       holder.backgroundView.setBackgroundResource(R.drawable.and_gray_bg_listing); 
      } 

      holder.officesTitle.setText(data.get(position)); 

      return convertView; 
     } 
    } 

    static class ViewHolder { 
     TextView officesTitle; 
     ImageView backgroundView; 
    } 

} 

私はあなたに私はすべてのListViewに使用するコードをお見せしましょう、適切に背景を変更するためのクリックイベントを制御し、何もして、さらに

描画可能で、あなたに合わせてデザインしてください。RelativeLayoutに次のコードを入れてください。

<ImageView android:id="@+id/OfficesBackground" android:layout_width="fill_parent"  
      android:layout_height="45dip" 
      android:layout_alignParentTop="true" 
      android:background="@drawable/and_gray_bg_listing" 
      android:scaleType="fitXY" 
      ></ImageView> 


     <TextView android:id="@+id/OfficesName" android:layout_width="wrap_content" 
        android:text="Offices Name" 
        android:textColor="#000000" android:textStyle="bold" 
        android:layout_height="wrap_content" 
        android:layout_centerVertical="true" android:layout_marginLeft="5dip" 
      ></TextView> 

希望します。

+0

は、私は多分それは私がその部分を逃したという理由だけであることを修正アム: 場合(位置== selectedListItem) { holder.backgrouundView.setBackgroundResource(R.drawable。and_gray_bg_listing_selected); } } ? 私はatmにいるので、試してみることはできません...しかし、私は家にいるとすぐにします。 ありがとうありがとう:) – Beasly

+1

はい、getViewメソッドでこのチェックを実行するだけです。残りのものは自動的に行われます – Javanator

+0

このメソッドを使用すると、リストビューを非常にスムーズに描画でき、さらにイベントを制御することができます。私もiPhone TableViewのアニメーション削除機能を実装しました..赤の削除ボタンと他のもの – Javanator