Изменение цвета фона выбранного элемента в ListView
Я хочу знать, как изменить цвет фона выбранного элемента в моем спискеView. Я хочу только изменить конкретный элемент, нажатый пользователем, то есть если пользователь нажмет на другой элемент, он будет выделен. Ну, так как я хочу, чтобы он был максимально простым и использовал список по умолчанию для Android, я использовал этот код:
record_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
try{
for (int ctr=0;ctr<=record_items.length;ctr++){
if(i==ctr){
record_list.getChildAt(ctr).setBackgroundColor(Color.CYAN);
}else{
record_list.getChildAt(ctr).setBackgroundColor(Color.WHITE);
}
}
}
catch (Exception e){
e.printStackTrace();
}
Log.v("Selected item",record_list.getItemAtPosition(i));
}
});
Хорошо, этот работает, но проблема в том, что он медленный. Теперь я хочу знать, есть ли другой способ, который я могу сделать, который даст тот же результат, что и я.
Я пробовал использовать record_list.getSelectedView().setBackgroundColor(Color.CYAN);
, но он дает мне исключение с нулевым указателем.
Я также попробовал selector.xml, но также не сделал этого.
Кроме того, в ListView есть один объект, который называется listSelector. Это можно сделать в соответствии с документацией "Drawable, используемой для указания текущего выбранного элемента в списке". Я также считаю, что это должно сделать трюк, и да, это делает трюк на моем эмуляторе, но не на моей вкладке галактики. Я также пробовал другие методы, но ничего не работает, как хотелось бы.
Ответы
Ответ 1
Вы можете отслеживать позицию текущего выбранного элемента:
OnItemClickListener listViewOnItemClick = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
mSelectedItem = position;
mAdapter.notifyDataSetChanged();
}
};
И переопределите метод getView вашего адаптера:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view = View.inflate(context, R.layout.item_list, null);
if (position == mSelectedItem) {
// set your color
}
return view;
}
Для меня это трюк.
Ответ 2
Вы можете использовать селектор. Измените значения цветов и измените ниже в соответствии с вашими потребностями.
bkg.xml в папке с возможностью перемещения
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/pressed" />
<item android:state_focused="false"
android:drawable="@drawable/normal" />
</selector>
нажата .xml в папке с возможностью переноса
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF1A47"/> // color
<stroke android:width="3dp"
android:color="#0FECFF"/> // border
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners android:bottomRightRadius="7dp" // for rounded corners
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
normal.xml в папке с возможностью переноса
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke android:width="3dp"
android:color="#0FECFF" />
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
Устанавливает фоновый вывод для пользовательского макета listview для накачки для каждой строки
Я рекомендую использовать пользовательский список с пользовательским адаптером.
android:background="@drawable/bkg"
Если вы не использовали пользовательский адаптер, вы можете установить listselector в listview, как показано ниже
android:listSelector="@drawable/bkg"
Ответ 3
Определить переменную
private ListView mListView;
Инициализировать переменную
mListView = (ListView)findViewById(R.id.list_view);
OnItemClickListener списка просмотра
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adpterView, View view, int position,
long id) {
for (int i = 0; i < mListView.getChildCount(); i++) {
if(position == i ){
mListView.getChildAt(i).setBackgroundColor(Color.BLUE);
}else{
mListView.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
}
}
});
Создайте и запустите проект - Готово
Ответ 4
Если вы хотите, чтобы элемент оставался выделенным после того, как вы его нажали, вам нужно вручную установить его как выбранный в прослушивателе onItemClick
Элемент списка избранных элементов Android ListView выделен:
myList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true); // <== Will cause the highlight to remain
//... do more stuff
}});
Предполагается, что в вашем селекторе есть элемент state_selected:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true" android:drawable="@color/red" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="@color/red" />
<item android:state_enabled="true" android:state_selected="true" android:drawable="@color/red" />
<item android:drawable="@color/white" />
</selector>
Ответ 5
Метод 1:
Обновить ListView в вашей активности/фрагменте макета xml:
<ListView
...
android:choiceMode="singleChoice"
android:listSelector="@android:color/darker_gray"
/>
Чтобы это, все готово!
Если вы хотите программный способ справиться с этим, используйте метод 2...
Метод 2:
Если вы используете ListFragment, вы можете переопределить onListItemClick(), используя представление для установки цвета. Сохраните текущий вид, выбранный в reset цвет последнего выбора.
Обратите внимание, что это работает только в списках, которые подходят на одном экране, поскольку просмотр переработан.
public class MyListFragment extends ListFragment {
View previousSelectedItem;
...
@Override
public void onListItemClick(ListView parent, View v, int position, long id) {
super.onListItemClick(parent, v, position, id);
if (previousSelectedItem!=null) {
previousSelectedItem.setBackgroundColor(Color.WHITE);
}
previousSelectedItem=v;
v.setBackgroundColor(Color.BLUE);
}
}
Ответ 6
Сначала вы можете создать XML файл селектора, как показано ниже, в вашей папке drawable/list_item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
<solid android:color="#333333" />
<padding android:left="5dp" android:right="5dp" />
</shape></item>
<item><shape android:shape="rectangle">
<solid android:color="#222222" />
</shape></item>
</selector>
И затем в вашем списке укажите фон как
android:background="@drawable/list_item_selector"
Ответ 7
Для тех, кто интересуется, что именно нужно сделать, чтобы сохранить выбранные строки даже при прокрутке вверх. Это state_activation Все остальное обеспечивается внутренней функциональностью, вам не нужно беспокоиться о переключении, и вы можете выбрать несколько элементов. Мне не нужно было использовать методы notifyDataSetChanged() или setSelected (true).
Добавьте эту строку в ваш файл селектора, для меня drawable\row_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@android:color/holo_blue_light"/>
<item android:state_enabled="true" android:state_pressed="true" android:drawable="@android:color/holo_blue_light" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="@android:color/holo_blue_bright" />
<item android:state_enabled="true" android:state_selected="true" android:drawable="@android:color/holo_blue_light" />
<item android:state_activated="true" android:drawable="@android:color/holo_blue_light" />
<item android:drawable="@android:color/transparent"/>
</selector>
Затем в макете \custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:background="@drawable/row_background"
android:orientation="vertical">
<TextView
android:id="@+id/line1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Для получения дополнительной информации, я использую это с ListView Adapter, используя myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); а также myList.setMultiChoiceModeListener (новый MultiChoiceModeListener()...
из этого примера: http://www.androidbegin.com/tutorial/android-delete-multiple-selected-items-listview-tutorial/
Кроме того, вы (должны) использовать эту структуру для связи между списком и адаптером: List myList = new ArrayList();
вместо: ArrayList myList = new ArrayList();
Объяснение: Список типов против типа ArrayList в Java
Ответ 8
Самый простой способ, который я нашел:
в вашей деятельности XML добавьте следующие строки:
<ListView
...
android:choiceMode="singleChoice"
android:listSelector="#666666"
/>
или программно установите эти свойства:
listView.setSelector(Drawable selector)
listView.setSelector(int resourceId)
Мой конкретный пример:
<ListView
android:choiceMode="singleChoice"
android:listSelector="#666666"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView"/>
благодаря AJG:
fooobar.com/questions/81768/...
Ответ 9
используйте приведенный ниже xml в качестве фона listitem, он решит все проблемы.
Выбранные будут подсвечены при прокрутке вниз.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/holo_orange_dark" android:state_pressed="true"/>
<item android:drawable="@android:color/holo_green_light" android:state_selected="true"/>
<item android:drawable="@android:color/holo_green_light" android:state_activated="true"/>
Спасибо,
Nagendra
Ответ 10
Я также делаю аналогичную вещь: выделите выбранный элемент списка элементов (измените его на красный) и установите цвет текста внутри элемента на белый.
Я могу придумать " простой, но не эффективный" способ:
сохранить выбранную позицию позиции в пользовательском адаптере и изменить ее в реализации ListView OnItemClickListener
:
// The OnItemClickListener implementation
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListViewAdapter.setSelectedItem(position);
}
// The custom Adapter
private int mSelectedPosition = -1;
public void setSelectedItem (int itemPosition) {
mSelectedPosition = itemPosition;
notifyDataSetChanged();
}
Затем обновите выделенный фон и цвет текста в методе getView()
.
// The custom Adapter
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...
if (position == mSelectedPosition) {
// customize the selected item background and sub views
convertView.setBackgroundColor(YOUR_HIGHLIGHT_COLOR);
textView.setTextColor(TEXT_COLOR);
} else {
...
}
}
После поиска какое-то время я обнаружил, что многие люди упомянули о настройке android:listSelector="YOUR_SELECTOR"
. По прошествии некоторого времени я нашел самый простой способ выделить выделенный элемент списка ListView, который можно выполнить только с двумя строками, установленными в ресурс макета ListView:
android:choiceMode="singleChoice"
android:listSelector="YOUR_COLOR"
Есть и другой способ заставить его работать, например настроить тему activatedBackgroundIndicator
. Но я думаю, что это будет гораздо более общее решение, поскольку оно повлияет на всю тему.
Ответ 11
Я знаю, что это старый вопрос, но я даю простое решение для этой потребности (без циклов!):
//On your adapter create a variable:
private View lastSelectedItem;
//Define the folowing method:
private void toggleBackgroundItem(View view) {
if (lastSelectedItem != null) {
lastSelectedItem.setBackgroundColor(Color.TRANSPARENT);
}
view.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
lastSelectedItem = view;
}
//finally invoque the method onItemClick
lvSac.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick (AdapterView < ? > adapterView, View view,int i, long l){
toggleBackgroundItem(view);
}
}
Ответ 12
Предположим, вы хотите, чтобы каждый элемент был нажат каждый раз. Тогда этот код работает хорошо. Возьмем имя списка как stlist
stList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
// here i overide the onitemclick method in onitemclick listener
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//color change
//selected item colored
for(int i=0; i<stList.getAdapter().getCount();i++)
{
stList.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
parent.getChildAt(position).setBackgroundColor(Color.GRAY);
});
Ответ 13
Это простой метод, который может обрабатывать выбор, даже если список длинный:
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.list_item, null);
//Handle your items.
//StringHolder.mSelectedItem is a public static variable.
if(getItemId(position)==StringHolder.mSelectedItem){
rowView.setBackgroundColor(Color.LTGRAY);
}else{
rowView.setBackgroundColor(Color.TRANSPARENT);
}
return rowView;
}
И затем в вашем onclicklistener:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
catagoryAdapter.notifyDataSetChanged();
.....
Ответ 14
View updateview;// above oncreate method
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (updateview != null)
updateview.setBackgroundColor(Color.TRANSPARENT);
updateview = view;
view.setBackgroundColor(Color.CYAN);
}
});
Ответ 15
В наборе ListView:
android:choiceMode="singleChoice"
Создайте селектор для фона (drawable/selector_gray.xml):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/gray" android:state_checked="true" />
<item android:drawable="@color/white" />
</selector>
Добавить элемент списка:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:background="@drawable/selector_gray"
android:textColor="@color/colorPrimary"
tools:text="Your text" />
В ViewHolder вы можете раздуть этот элемент.
Ответ 16
Это очень просто. В конструкторе "OnItemClick" используйте параметр "view", который является вторым, представляющим представление элементов listView или GridView, и он становится новым представлением элементов, созданным самим адаптеромViewView. Поэтому, чтобы установить новый цвет ТОЛЬКО для самого ИЗБРАННОГО ПУНКТА, выполните следующие действия:
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l){
//view is instead of the view like textView , ImageView, or whatever
view.setBackgroundColor(Color.green);
}
Если вы сделаете какие-либо другие коды, чтобы установить новый цвет, вы столкнетесь с неловким поведением, например, зеленый цвет будет применен к незаглаженному элементу.
Ответ 17
nameofList.getChildAt (положение).setBackgroundColor (КРС);
работал на меня