Как выделить строку в 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-документы этих методов:

  • setSelection
void android.widget.AdapterView.setSelection(int position)

Устанавливает текущий выбранный элемент. к подклассы доступности доступности, которые переопределить этот метод необходимо вызвать сначала переопределить супер метод.

Параметры:
position Индекс (начиная с 0) выбранного элемента данных.

  • setChoiceMode
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;
    }
});

Ответ 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);
}