Изменение цвета фона элемента в Android ListActivity onListItemClick

Я знаю, что это звучит очень просто, и есть вопросы об этом. Но ничто из этого не могло решить мою проблему. Итак, мы идем:

Я хочу изменить цвет фона элемента списка ListActivity когда пользователь нажимает на него, и изменить его обратно в исходный цвет, когда пользователь нажимает снова (т. е. выберите/Отменить выбор элемента вид)

Я попытался использовать getChildAt, он отлично работает, если у меня есть все элементы, видимые на одном экране без прокрутки.

код:

getListView().getChildAt(position).setBackgroundColor(Color.CYAN);

проблема начинается, когда у меня есть больше элементов в списке, и пользователь должен прокручивать их. После изменения фона для элемента цвет фона отображается на новых видимых элементах при прокрутке. Кроме того,getChildAt(position) возвращает null (и, следовательно, a NullPointerException) при повторном нажатии на элемент.

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

спасибо заранее!

6 ответов


конечно. Я бы сделал это в getView() метод пользовательского ListAdapter.

MyAdapter extends SimpleAdapter {
    private ArrayList<Integer> coloredItems = new ArrayList<Integer>();

    public MyAdapter(...) {
        super(...);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = super.getView(position, convertView, parent);

        if (coloredItems.contains(position)) {
            v.setBackgroundColor(Color.CYAN);
        } else {
            v.setBackgroundColor(Color.BLACK); //or whatever was original
        }

        return v;
    }
}

обновление coloredItems при клике.

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    if (coloredItems.contains(position)) {
        //remove position from coloredItems
        v.setBackgroundColor(Color.BLACK); //or whatever was original
    } else {
        //add position to coloredItems
        v.setBackgroundColor(Color.CYAN);
    }
}

Если вы имеете дело с ListFragment этот код будет полезен,

  @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (view != null) {
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            getListView().setDescendantFocusability(ListView.FOCUS_AFTER_DESCENDANTS);
            catagoryValueListView=getListView();
            catagoryValueListView.setOnItemClickListener(new OnItemClickListener() {

             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 if (ColoredView != null)
                     ColoredView.setBackgroundColor(Color.WHITE); //original color

                 view.setBackgroundColor(Color.BLUE); //selected color
                 ColoredView = view;
                                  }
        });
    }

}

что я делаю, я создаю XML-файл, т. е. list_background и поместите его в папку мешочки.

xml выглядит следующим образом:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:drawable="@color/list_selected" android:state_pressed="true" />
   <item android:drawable="@android:color/white" />
</selector>

и в xml-коде для элемента ListView я помещаю этот xml в качестве фона элементов, т. е.

товар.XML-код:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          style="@style/Fill"
          android:background="@drawable/list_background">

     <!-- Your layout here -->
</RelativeLayout>

style=@style / Fill-это только короткий путь, который я сделал для android: layout_height= "match_parent"и android:layout_width=" match_parent

затем в onListItemCLick:

public void onListItemClick(ListView l, View v, int position, long id) {
    v.setPressed( !v.isPressed ) //Toggle between colors of the view
}

просто вы можете сделать это в onListItemClick метод

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

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

    ColorDrawable colorDrawable1 = new ColorDrawable(
            Color.parseColor("#A0A3A0"));
    v.setBackgroundDrawable(colorDrawable1);   

    if (position == 0) {
        Intent i = new Intent(MainActivity.this, NewActivity.class);

        startActivity(i);
    }

}

вот как я это сделал:

создать глобальную переменную View ColoredView; тогда, когда вы setOnItemClickListener для ListView сделайте так:

MenuList.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (ColoredView != null)
                    ColoredView.setBackgroundColor(Color.WHITE); //original color

                view.setBackgroundColor(Color.BLUE); //selected color
                ColoredView = view;
            }
        });

это самый простой способ на мой взгляд.


спасибо heycosmo. твое решение решило мою проблему.

понятия не имею, почему мы должны установить фон в 2 местах.

1. GetView адаптера адаптера()

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     ....
     ....
     ....
        if(arrayBools[position]) {
            view.setBackgroundColor(Common.colorBkgroundSelected);
        }
        else{
            view.setBackgroundColor(Common.colorBkgroundNormal);            
        } 
     ....
     ....
     ....
}

2. ListActivity-это onListItemClick ().

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
      super.onListItemClick(l, v, position, id);       
      arrayBools[position] = ( arrayBools[position] ? false : true );

     if(arrayBools[position]) {
         v.setBackgroundColor(colorBkgroundSelected);
     }
     else{
        v.setBackgroundColor(colorBkgroundNormal);          
     }    
}