2011-04-15 37 views
8

我想在用戶點擊它時更改listview項的背景。有點像Honeycomb settings page(雖然我不處理只是設置,所以我沒有使用PreferenceActivity)我有這個功能通過資源狀態選擇器狀態選擇器工作,除了點擊列表視圖菜單上的情況,將線性佈局更改爲列表視圖的權利(排序分屏視圖)。我猜測listview失去焦點,所以state_pressed不再是真的。ListView項不會保留「選中」

<item android:state_pressed="true"> 
    <shape > 
     <solid android:color="@color/blue1" /> 
    </shape> 
    </item> 

任何提示,以保持該列表視圖項顏色,直到另一個列表視圖項被選中?謝謝!

編輯:

我能得到一個setOnItemClickListener改變的背景

view.setBackgroundResource(R.color.red); 

我只需要一個在被點擊其他列表項,所以當一次選擇,我試過lv.invalidate()lv.getChildAt(0).invalidate()但都沒有工作,第二個導致空指針異常。任何想法使顏色迴歸?

回答

9

當您從手機中釋放手指時,它不再按註冊。當用戶選擇時,你想要做的事實際上是改變單行的背景。這意味着實施onItemClick或onItemTouch並標記適配器以用新背景重新繪製該行。如果您已經在使用自定義列表適配器,則可以在getView()方法中針對布爾值執行檢查。您還需要跟蹤哪些行被選中,哪些不是。

僞代碼:

public View getView(int pos, View convertView, ViewGroup parent) { 
     if(isChecked[pos]) //set background to checked color 
    } 
+0

我沒有實現getView方法,因爲我有靜態和簡單的listview數據。我應該執行它嗎?請幫助我。 – 2012-01-21 06:59:21

+0

你能幫我嗎?我真的需要你的幫助。 – 2012-01-24 05:37:48

+0

@sgarman - 你能告訴我如何使用這個缺血的[] – 2015-02-19 18:09:20

-1

你試過android:state_selected="true"

2

默認情況下,「選擇」是不一樣的「點擊」當你使用觸摸界面 - 這導致了我一些真正頭疼的時候我就開始Android開發的東西。

爲了支持觸摸和使用scrollwheels /軌跡球導航的用戶兩個用戶,你可能想使用setSelection,並做你的操作在AdapterView.OnItemSelectedListener實現(與setOnItemSelectedListener設置)。

另一個問題是setSelection將不會突出顯示一個項目,如果最後一個事件是觸摸事件。

我建議您爲列表項目創建自定義視圖,並在那裏處理突出顯示。

希望這有助於

菲爾Lello

3

這是落實sgarman想法:

package com.mypackage; 

import java.util.Vector; 

import com.myapp.R; 
import com.myapp.data.Address; 

import android.content.Context; 
import android.graphics.Color; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 

public class AddressesListAdapter extends BaseAdapter{ 
    protected Context context; 
    protected LayoutInflater mInflater; 
    protected int itemResourceId; 
    protected Vector<Address> contentItems = new Vector<Address>(); 
    protected Vector<Boolean> selectedStates; 
    private static final String TAG = "myapp"; 

    public AddressesListAdapter(Context context, Vector<Address> contentItems) { 
     this.context = context; 
     this.contentItems = contentItems; 
     mInflater = LayoutInflater.from(context); 
     itemResourceId = R.layout.address_list_item; 
     selectedStates = new Vector<Boolean>(); 
     //initial fill 
     clearSelectedState(); 
    } 

    @Override 
    public int getCount() { 
     return contentItems.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return contentItems.get(position); 
    } 

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

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     final ViewHolder holder; 
     if (convertView == null) { 
      convertView = mInflater.inflate(itemResourceId, null); 

      holder = new ViewHolder(); 
      holder.addressName = (TextView) convertView.findViewById(R.id.addressName); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     Address address = (Address) contentItems.get(position); 
     holder.addressName.setText(address.getAddressName()); 
     holder.addressName.setOnClickListener(new SetFocusListener(position)); 

     //restore saved position from saving vector 
     if (selectedStates.get(position)) holder.addressName.setBackgroundColor(Color.BLUE); 
     else holder.addressName.setBackgroundColor(Color.TRANSPARENT); 

     return convertView; 
    } 

    private void clearSelectedState() { 
     selectedStates.clear(); 
     for (int i = 0 ; i <= contentItems.size(); i++) { 
      selectedStates.add(new Boolean(false)); 
     } 
    } 

    private class SetFocusListener implements View.OnClickListener { 
     private int position; 

     public SetFocusListener(int position) { 
      this.position = position; 
     } 

     @Override 
     public void onClick(View v) { 
      //clear selected state vector 
      clearSelectedState(); 
      //set selected position 
      selectedStates.set(position, new Boolean(true)); 
      //refresh adapter to redraw focus 
      notifyDataSetChanged(); 
     } 
    } 

    static class ViewHolder { 
      TextView addressName; 
    } 
} 

釷唯一擔心的,它可能是昂貴的,以建立新的偵聽器爲每個getView()迭代

5

希望得到這個幫助,

1。 - 爲關注項目的形狀文件:\繪製\ list_selector_focused.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 

    <gradient android:angle="90" android:startColor="#f5c98c" android:endColor="#f7ddb8"/> 

</shape> 

2:創建壓制件的形狀文件:\繪製\ list_selector_pressed.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 

    <gradient android:angle="90" android:startColor="#fb9d23" android:endColor="#ffc579" /> 

</shape> 

3 .-創建列表選擇文件:\繪製\ list_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" /> 
    <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" /> 
    <item android:drawable="@drawable/list_selector_focused" /> 

</selector> 

4.-這個屬性添加到您的ListView在佈局文件:

android:choiceMode="singleChoice" 
android:listSelector="@drawable/list_selector" 

你可以用顏色來代替梯度形狀,

-1

嘗試

android:background="?android:attr/activatedBackgroundIndicator" 

;)

+0

你應該試試這個嗎? – 2014-10-06 13:59:00

3

Android的狀態檢查最適合用來解決這個問題。

有人提到使用android:background =「?android:attr/activatedBackgroundIndicator」。

這只是指向android源代碼的frameworks/base/core/res/res/drawable中的一個activated_background_ *資源。例如activated_background_holo_dark.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" /> 
    <item android:drawable="@color/transparent" /> 
</selector> 

所以基本上你想使用state_activated表示,當用戶按下按鈕,以及當它是在一個檢查(即持久選擇狀態)的狀態。請注意,激活僅在Honeycomb之後引入,如果您針對的是舊設備,則需要依賴state_checked(更多詳細信息here)。

現在,如果您想將項目設置爲已選中狀態,則需要致電listView.setItemChecked(position, true)。您可能需要將ListView上的android:choiceMode屬性設置爲適當的值(例如,如果您只希望一次選擇一件事情,請使用singleChoice)。你不需要失效,對setItemChecked的調用將觸發一個更新視圖的重新佈局。

如果允許在ListView中重新排序項目,並且要小心,因爲當前選中的項目需要更新。如果您使用穩定的ID,則會自動處理。

要查看這個實例的示例,請查看培訓系列中找到的NavigationDrawer示例代碼:http://developer.android.com/training/implementing-navigation/nav-drawer.html

0

好的,所以我嘗試了上面的解決方案,從它說「這是sgarman想法的實現:」這僅適用於SetFocusListener是OnTouchListner。另外,onClick方法消耗點擊。我必須將此解決方案與列表項目上的OnItemClick偵聽器配對,才能使列表實際顯示突出顯示的項目。

0

我用android:state_activated="true"代替state_selected。它像一個魅力!

0

如果您在整個活動中保留listView,則可以在getView()方法中執行mListView.isItemChecked(position)。他們根據結果設置背景顏色。