2011-01-03 9 views
7

Mam problem ze zmianą tła widoku w widoku listy.Zmień tło listy - dziwne zachowanie

Co potrzebne:
zmienić obraz tła wiersza onClick()

Co właściwie się dzieje:
Tło zostanie zmieniony (wybrane) po naciśnięciu na przykład pierwszy wpis. Ale po przewinięciu w dół zaznaczono także 8 pozycję. Przewiń do góry, pierwszy nie jest już wybrany. Drugi wpis jest teraz wybrany. dalej przewijanie i nadal skacze ...

co mam dong w Kodeksie:
mam kanały i onClick() przełączam atrybut kanału logiczną wybraną a potem zmienić tło. Robię tylko tylko onClick(), dlatego nie rozumiem, dlaczego dzieje się tak również w innych wpisach. Jedno zawiadomienia I to: Wydaje się, że tylko „rysunek” -part ponieważ rzecz, która się wybrany „przez niego samego siebie” ma nadal wybraną wartość na fałszywy

myślę, że wydaje się mieć coś zrobić z ponownym wykorzystaniem poglądów w niestandardowych ListAdapters getView (...)

Kodeks onClick() w ListActivity:

@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; 
    } 

Kodeksu z 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; 
} 

naprawdę doceni każdy pomysł jak rozwiązać ten problem! :)

Jeśli potrzebujesz więcej informacji, proszę mi powiedzieć.

Z góry dziękuję!

Odpowiedz

10

Pokażę Ci kod, który używam dla każdego ListView i prawidłowo kontrolnego zdarzenie click do zmiany tła i robi nic więcej

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; 
    } 

} 

plik officeslistitemlayout.xml będzie jak po dodać odkształcalne i zaprojektować go według umieścić następujący kod w 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> 

nadzieję, że pomoże :)

+0

Czy mam rację, że być może jest to tylko dlatego, że brakowało mi tej części: if (pozycja == selectedListItem) { holder.backgrouundView.setBackgroundResource (R.drawable.and_gray_bg_listing_selected); } else { właściciel.backgrouundView.setBackgroundResource (R.drawable.and_gray_bg_listing); } ? Jestem w pracy, więc nie mogę tego wypróbować ... ale zrobię to tak szybko, jak będę w domu. Dziękuję bardzo długo :) – Beasly

+1

Tak, wystarczy wykonać to sprawdzenie w metodzie getView. Reszta będzie automatycznie wykonywana – Javanator

+0

Za pomocą tej metody możemy bardzo płynnie rysować listy i kontrolować kolejne zdarzenia. wprowadziłem nawet animowaną funkcję usuwania iPhone TableView .. czerwony przycisk usuwania i inne rzeczy – Javanator