Элемент ListView: изменение цвета фона на последний выбранный элемент (или нажатие)

1

Я разрабатываю приложение Android 2.3.3 со списком ListActivity.

Я хочу сделать что-то, чтобы показать пользователю, что элемент был выбран им. Я сделал следующее, но это не так (и я искал в stackoverflow, и они противоречивые ответы).

Это layout_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/txtName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/selector"
        android:text="" />

</LinearLayout>

Это файл selector.xml по res/drawable

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"
        android:color="#00FF00" />
    <item android:state_pressed="true"
        android:color="#555555" />
    <item android:color="#000000" />
</selector>

Но это не работает, потому что он говорит, что я должен поместить @drawable в selector.xml.

Как установить цвет фона в синий, чтобы последний элемент списка был нажат?

ОБНОВИТЬ

Адаптер массива, используемый с этим списком:

public class GatesAdapter extends ArrayAdapter<Gate>
{
    /**
     * Application context.
     */
    private Context context;
    /**
     * 
     */
    private int itemLayoutId;
    /**
     * 
     */
    private ArrayList<Gate> gates;
    private int selectedGateIndex;

    public int getSelectedGateIndex() {
        return selectedGateIndex;
    }

    public void setSelectedGateIndex(int selectedGateIndex) {
        this.selectedGateIndex = selectedGateIndex;
    }

    public Gate getSelectedGate()
    {
        return gates.get(selectedGateIndex);
    }

    public void removeSelectedGate()
    {
        this.gates.remove(selectedGateIndex);
    }

    public ArrayList<Gate> getGates()
    {
        return this.gates;
    }

    public GatesAdapter(Context context, int listItemResourceId,
            ArrayList<Gate> objects)
    {
        super(context, listItemResourceId, objects);

        this.context = context;
        this.itemLayoutId = listItemResourceId;
        this.gates = objects;
        this.selectedGateIndex = -1;

        this.setNotifyOnChange(true);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent)
    {
        Log.v("GatesAdapter", "getView.postion: " + position);
        View row = convertView;
        if (row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(itemLayoutId, parent, false);
        }

        Gate gate = gates.get(position);
        if (gate != null)
        {
            TextView itemText = (TextView)row.findViewById(android.R.id.text1);
            if (itemText != null)
            {
                itemText.setText(gate.getName());
                //selectedGateIndex = position;
                if (selectedGateIndex == position)
                {
                    row.setBackgroundColor(Color.BLUE);
                }
            }
        }

        return row;
    }
}
  • 0
    Вы хотите раскрасить выбранный элемент или последний элемент, по которому щелкнули?
  • 0
    Я хочу цвет для последнего выбранного элемента. Я не знаю, есть ли у элемента списка выбранное состояние.
Теги:
selector
android-listview

3 ответа

1

Я сделал это с адаптером пользовательского массива, только что проверил там метод getView():

if (position == lastClicked) {
    v.setBackgroundColor(0x...)
} else {
    v.setBackgroundColor(0x...)
}

блок else важен из-за специфического поведения больших списков

UPDATE: здесь мой пользовательский адаптер массива, который отлично работает:

public class AbcArrayAdapter extends ArrayAdapter<UniversalListItem> {

private Context c;
private int id;
private List<UniversalListItem>items;

public AbcArrayAdapter(Context context, int viewResourceId, List<UniversalListItem> objects){
    super(context,viewResourceId,objects);
    c=context;
    id=viewResourceId;
    items=objects;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(id, null);
    }

    final UniversalListItem o = items.get(position);
    if (o != null) {
        if ( o.isInList() ) {
            v.setBackgroundColor(0x00ffffff);
        } else {
            v.setBackgroundColor(0x4d0099cc);
        }
        /*....*/
    }
    return v;
}

}

  • 0
    Да, я думаю, что это лучшее из возможных решений вашей проблемы. Сравните положение и установите цвет фона.
  • 0
    остальное важно, потому что каждый ряд перерисовывается!
Показать ещё 4 комментария
0

Я предпочитаю это более простое решение:

 lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long arg3) {
            statusText.setText("Redes:" + lv.getCount()+"\n Posición / First:" +position + "/" + lv.getFirstVisiblePosition());

            NetsArrayAdapter aA = (NetsArrayAdapter) parent.getAdapter();

            for(int a = 0; a < parent.getChildCount(); a++) {
                parent.getChildAt(a).setBackgroundColor(Color.TRANSPARENT);
            }

            view.setBackgroundColor(Color.BLUE);
            aA.setLastSelected(position);
        }
    });

private class NetsArrayAdapter extends ArrayAdapter<String> {
    private ArrayList<String> mData;
    private int id;
    private Context c;

    private int lastSelected = -1;

    // declaring our ArrayList of items
    private ArrayList<String> objects;

    /* here we must override the constructor for ArrayAdapter
    * the only variable we care about now is ArrayList<Item> objects,
    * because it is the list of objects we want to display.
    */
    public NetsArrayAdapter(Context context, int textViewResourceId, ArrayList<String> objects) {
        super(context, textViewResourceId, objects);
        c = context;
        id = textViewResourceId;
        mData = objects;
    }

    @Override
    public View getView(final int position, View view, ViewGroup parent) {
        View currView = super.getView(position, view, parent);

        System.out.println("Paint / selected:"+position+" / "+lastSelected);

        if(lastSelected != position)
            currView.setBackgroundColor(Color.BLACK);
        else
            currView.setBackgroundColor(Color.BLUE);

        return currView;
    }

    public int getLastSelected() {
        return lastSelected;
    }

    public void setLastSelected(int lastSelected) {
        this.lastSelected = lastSelected;
    }


}
0

Да, элементы в селекторах принимают только чертежи. Однако вы можете создавать чертежи с цветом: добавьте свои цвета в свои цвета. Xml:

<drawable name="color1">#00FF00</drawable>
<drawable name="color2">#00FF00</drawable>
<drawable name="color3">#000000</drawable>

Затем используйте их как чертежи:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true"
        android:drawable="@drawable/color1" />
    <item android:state_pressed="true"
        android:drawable="@drawable/color2" />
    <item android:drawable="@drawable/color3" />
</selector>

Надеюсь, это поможет вам =)

  • 0
    Извините, но это не работает.
  • 0
    Если вы используете такой подход, вам следует использовать android:state_activated="true" вместо item android:state_selected="true" ( stackoverflow.com/a/6207213/1506048 )

Ещё вопросы

Сообщество Overcoder
Наверх
Меню