Как выделить строку в ListView в Android? - PullRequest
34 голосов
/ 08 мая 2011

Мне нужно выделить строку в 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();
            }
         });
    }
}

Ответы [ 8 ]

37 голосов
/ 08 мая 2011

Поскольку по умолчанию ListViews установлен в режим выбора NONE, в сенсорном режиме метод setSelection не будет иметь визуального эффекта.

Чтобы сохранить предыдущий выбор / визуально отобразить явный выбор, сначала вы должны соответствующим образом установить режим выбора списка:

listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

Полезно прочитать Документацию по API этих методов:

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

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

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

  • setChoiceMode
void android.widget.ListView.setChoiceMode(int choiceMode)

Определяет поведение выбора для Список. По умолчанию списки не имеют любое поведение выбора (CHOICE_MODE_NONE). Установив Выбор режима CHOICE_MODE_SINGLE, Список позволяет до одного элемента быть в выбранное государство. Установив choiceMode to 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 будет работать, если вы останетесь в одном и том же упражнении, но завершаете его при каждом щелчке по элементу (изменение выбора), поэтому дополнительные данные следует передавать в начальный 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;
    }
});
27 голосов
/ 19 июня 2013

Просто:

  1. Установите правильный режим выбора в списке. setChoiceMode
  2. Установить фон для поддержки состояния выбора в макете элемента, например:

    android:background="?android:attr/activatedBackgroundIndicator"
    

К вашему сведению:

14 голосов
/ 15 августа 2014

Гораздо проще реализовать это в файлах макета и позволить Android обрабатывать все остальное ...

1) Убедитесь, что на вашем макете ListView (singleChoice, multipleChoice и т. Д.) Установлено android:choiceMode="". По умолчанию установлено значение 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-файл селектора состояний и сохраните его в папке «Drawables». В этом примере мы назовем его 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.

9 голосов
/ 24 августа 2011

У меня была проблема с поиском простого решения, потому что во многих руководствах и ответах содержалась информация об одном выборе с помощью переключателей (которые в значительной степени зависели от RadioGroup).

Моя проблема заключалась в том, что я мог установить элемент в свое состояние «Выделено», но затем не мог сбросить список при выборе следующего элемента.Вот что я придумал:

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));
    }
}
4 голосов
/ 06 декабря 2012

Я решаю эту проблему следующим образом: 1. установите lastClickId, когда щелкните элемент в listView, обновите 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;
}

Адаптер:

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's background to blue
    if (position == MainUserFeedFragment.getCurrentSelectedItemId()) {
        view.setBackgroundResource(R.color.blue);
        }
    }
1 голос
/ 29 октября 2013

Вы можете использовать переход. Следуйте моему коду, потому что я добился выделения определенного элемента списка по выбору Допустим, вы хотите выделить первый элемент на 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 секунд, а затем замедлится до белого.

1 голос
/ 08 мая 2011

Почему вы не сохраняете выборки в массиве, а затем передаете этот массив в конструктор адаптера массива ListView, что-то вроде myArrayAdapter(context,layoutID,dataArray,selectionArray)

, затем в вашем getView методе для массива-переходника, просто сделайтепроверка.Например, в псевдокоде

if row was previously selected
    change background color
0 голосов
/ 02 марта 2016

САМОЕ ПРОСТОЕ из всех

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...