Как выделить строку в ListView в Android?
Мне нужно выделить строку в ListView
, которая была выбрана (чтобы показать пользователю, что он выбрал), так что это не тот, который будет выбран, это тот, который он выбрал раньше.
У меня уже есть место:
ListView.setSelection(position);
И теперь я хочу выбрать эту конкретную строку и выделить ее.
Код onCreate()
в действии, который содержит ListView
:
public class CountryView extends Activity
{
protected static final String LOG_TAG = null;
/** Called when the activity is first created. */
String[] lv_arr = {};
ListAdapter adapter;
TextView t;
private ListView lvUsers;
private ArrayList<Coun> mListUsers;
String responce=null;
public int d;
int selectedListItem = -1;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.country);
Intent data =getIntent();
mListUsers = getCoun();
lvUsers = (ListView) findViewById(R.id.counlistView);
lvUsers.setAdapter(new ListAdapter(this, R.id.counlistView, mListUsers));
selectedListItem=data.getExtras().getInt("PositionInList");
lvUsers.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lvUsers.setOnItemClickListener(new OnItemClickListener()
{
int positionItem;
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
Intent pongIntent = new Intent(getApplicationContext(),Trav.class);
int counId=mListUsers.get(position).id;
pongIntent.putExtra("response",mListUsers.get(position).p);
pongIntent.putExtra("responseCounID",counId);
//Put the position of the choose list inside extra
positionItem=position;
pongIntent.putExtra("PositionInListSet",positionItem);
setResult(Activity.RESULT_OK,pongIntent);
Log.i("CounID *******************************"," "+counId);
finish();
}
});
}
}
Ответы
Ответ 1
Так как по умолчанию ListViews
установлен режим выбора NONE
, в сенсорном режиме метод setSelection
не будет иметь визуального эффекта.
Для сохранения предыдущего выбора/визуального отображения явного выбора, сначала вы должны соответствующим образом настроить режим выбора списка:
listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
Полезно прочитать API-документы этих методов:
void android.widget.AdapterView.setSelection(int position)
Устанавливает текущий выбранный элемент. к подклассы доступности доступности, которые переопределить этот метод необходимо вызвать сначала переопределить супер метод.
Параметры:
position
Индекс (начиная с 0) выбранного элемента данных.
void android.widget.ListView.setChoiceMode(int choiceMode)
Определяет поведение выбора для Список. По умолчанию списки не имеют любое поведение выбора (CHOICE_MODE_NONE
). Установив selectMode до CHOICE_MODE_SINGLE
, Список позволяет до одного элемента находиться в выбранного состояния. Установив choiceMode до CHOICE_MODE_MULTIPLE
, список позволяет использовать любое количество элементов для выбирается.
Параметры:
choiceMode
Один из CHOICE_MODE_NONE
CHOICE_MODE_SINGLE
, или CHOICE_MODE_MULTIPLE
В случае, если этого недостаточно (скажем, вы хотите всегда показывать последний выбор по-другому рядом с текущим выбором), вы должны сохранить свой последний выбранный элемент (данные, которые заполняют ListAdapter
), как lastSelectedItem
, и в вашем адаптере getView
метод назначает другой фоновый ресурс рендереру, если он равен этому lastSelectedItem
.
Если ваш последний выбор не будет обновляться при изменении выбора, вы должны явно вызвать метод notifyDataSetChanged
в вашем экземпляре адаптера.
Обновить
Поскольку ваша активность, содержащая ListView
, является дочерним элементом активности, которая ждет этого одного результата (на основе части setResult(Activity.RESULT_OK,pongIntent);
), исходная идея верна, последняя позиция должна быть передана через намерение при запуске операции:
selectedListItem = getIntent().getIntExtra("PositionInList", -1);
lvUsers.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lvUsers.setSelection(selectedListItem);
Решение ListView.CHOICE_MODE_SINGLE
будет работать, если вы останетесь в том же самом действии, но вы заканчиваете его на каждом itemClick (изменение выбора), поэтому дополнительные данные должны быть переданы в начало Intent
.
Вы также можете установить ранее выбранный элемент фона из вашего адаптера - упомянутый выше -, переопределив его метод getView
:
lvUsers.setAdapter(new ArrayAdapter(this, R.id.counlistView, groups)
{
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
final View renderer = super.getView(position, convertView, parent);
if (position == selectedListItem)
{
//TODO: set the proper selection color here:
renderer.setBackgroundResource(android.R.color.darker_gray);
}
return renderer;
}
});
Ответ 2
Просто:
- Установите правильный режим выбора в вашем списке.
setChoiceMode
-
Установите фон для поддержки состояния выбора в макете элементов, например:
android:background="?android:attr/activatedBackgroundIndicator"
FYI:
Ответ 3
Это намного проще реализовать в ваших файлах макета и позволить Android справиться с остальными...
1) Убедитесь, что у вас android:choiceMode=""
установлен на макет ListView (singleChoice
, multipleChoice
и т.д.). По умолчанию установлено значение none
.
<ListView
android:id="@+id/invite_friends_fragment_contacts_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:choiceMode="multipleChoice"/> <!-- THIS LINE -->
2) Создайте XML файл селектора состояний и сохраните его в папке с вашими возможностями. В этом примере мы назовем его state_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/blue" android:state_selected="true"/>
<item android:drawable="@android:color/blue" android:state_activated="true"/>
<item android:drawable="@android:color/transparent"/>
</selector>
3) В макете списка элементов добавьте файл state_selector.xml в качестве фона:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/state_selector"> <!-- THIS LINE -->
<!-- ALL OF YOUR ELEMENTS WILL GO HERE (TextViews, ImageViews, etc) -->
</RelativeLayout>
Если вы используете multipleChoice
, вы можете переопределить onItemClick()
и соответственно установить/снять выбранные элементы. Android изменит цвет фона, как указано в файле state_selector.xml.
Ответ 4
У меня возникла проблема в том, чтобы найти легкое решение этого, потому что в большом количестве руководств и ответов содержалась информация об одном выборе с помощью переключателей (которые в значительной степени основывались на RadioGroup's).
Моя проблема заключалась в том, что я мог установить элемент в мое состояние "Выделено", но тогда не мог reset список, когда был выбран следующий элемент. Вот что я придумал:
listView.setOnItemClickListener(new ItemHighlighterListener ());
С этим классом:
private class ItemHighlighterListener implements OnItemClickListener{
private View lastSelectedView = null;
public void clearSelection()
{
if(lastSelectedView != null) lastSelectedView.setBackgroundColor(android.R.color.transparent);
}
@Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
clearSelection();
lastSelectedView = view;
view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.shape_selected_menu_item));
}
}
Ответ 5
Я решаю эту проблему следующим образом:
1. установите lastClickId, щелкнув элемент в спискеView, обновите значение lastClickId до позиции, а затем обновите фон представления.
После этого, когда мы нажимаем один элемент, этот элемент будет выделен, но когда мы прокручиваем listView (делаем элемент, который мы выбрали из экрана) и прокручиваем назад, подсветка исчезнет, потому что метод getView() повторится в ваш адаптер, поэтому мы должны сделать следующее.
2. в вашем адаптере измените фон в методе getView(), вот код:
private static int lastClickId = -1;
private OnItemClickListener listener = new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
if ((lastClickId != -1) && (lastClickId != position)) {
parent.getChildAt(lastClickId).setBackgroundResource(
R.color.grey);
view.setBackgroundResource(R.color.blue);
}
if (lastClickId == -1) {
view.setBackgroundResource(R.color.blue);
}
lastClickId = position;
}
};
public static int getCurrentSelectedItemId() {
return lastClickId;
}
Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = mInflater.inflate(R.layout.tweet_list_layout, null);
// set selected item background to blue
if (position == MainUserFeedFragment.getCurrentSelectedItemId()) {
view.setBackgroundResource(R.color.blue);
}
}
Ответ 6
Почему вы не храните выбор в массиве, а затем передаете этот массив в конструкторе адаптера массива ListView, что-то вроде myArrayAdapter(context,layoutID,dataArray,selectionArray)
то в вашем методе getView
для массива, просто выполните проверку. Например, в псевдокоде
if row was previously selected
change background color
Ответ 7
Вы можете использовать переход. Следуйте моему коду, потому что я добился выделения определенного элемента списка по выбору
Предположим, вы хотите выделить первый элемент в течение 5 секунд.
if(position == 0){
viewHolderThubnail.relImage.setBackgroundResource(R.drawable.translate);
TransitionDrawable transition = (TransitionDrawable) viewHolderThubnail.relImage.getBackground();
transition.startTransition(1000);
}else{
viewHolderThubnail.relImage.setBackgroundResource(R.color.white);
}
translate.xml
<?xml version="1.0" encoding="UTF-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The drawables used here can be solid colors, gradients, shapes, images, etc. -->
<item android:drawable="@drawable/new_state" />
<item android:drawable="@drawable/original_state" />
</transition>
new_state.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#92BCE7"/>
</shape>
original_state.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF"/>
</shape>
Если вы поняли этот код, который очень прост, я должен сказать, что элемент списка в нулевой позиции будет выделяться синим цветом в течение 5 секунд, а затем он будет медленно исчезать до белого цвета.
Ответ 8
ПРОСТАЯ из всех
View updatedview=null;
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//these two lines of code means that only one item can be selected at a time
if(updatedview != null)
updatedview.setBackgroundColor(Color.TRANSPARENT);
updatedview=view;
Toast.makeText(getApplicationContext(), " " + str[position],Toast.LENGTH_LONG).show();
view.setBackgroundColor(Color.CYAN);
}