如何清除ListView选择? [英] How do I clear ListView selection?

查看:283
本文介绍了如何清除ListView选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


TL; DR:您从(a)我的列表视图中选择一个选项。然后,你改变主意并在(b)我的编辑文本中输入内容。如何清除列表视图选择并仅显示您的编辑文本? (反之亦然)

TL;DR: You choose an option from (a) my listview. Then, you change your mind and type something in (b) my edit text. How do I clear your listview selection and only show your edittext? (and vice versa)

我有一个带有选项列表视图的应用程序以及一个用于创建自己选项的edittext。我需要用户选择或创建一个选项,但不能同时选择或创建两个选项。这是我的布局图:

I have an application with a listview of options as well as an edittext to create an own option. I need the user to either choose or create an option, but not both. Here's a drawing of my layout:

< img src =https://i.stack.imgur.com/ljxR2.pngalt =在此处输入图像说明>

每当用户从列表视图中选择一个选项,我将其设置为已选择,将其设置为绿色,如下所示:

Whenever the user selects an option from the listview, I set it as "selected" by making it green, like so:

<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="true"
        android:drawable="@color/colorPrimary"/>
    <item
        android:state_selected="false"
        android:drawable="@color/windowBackground" />
</selector>

(这是我列表视图的背景)

(this is set as the background of my listview)

问题:如果用户决定输入他们自己的选项,我想取消选择listview选项,因为他们只能有一个选项。

Problem: I want to unselect the listview option if the user decides to type in their own option since they can only have one option.


  1. 用户从列表视图中选择一个选项

  2. 用户决定使用以下选项创建自己的选项edittext

  3. 当他们开始输入自己的

  1. User selects an option from the listview
  2. User decides they want to create their own option using the edittext
  3. The listview option is unselected when they start typing their own


时,列表视图选项未被选中

我已经尝试过 ,但没有任何选择。

e.setOnEditorActionListener(new TextView.OnEditorActionListener()
        {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                for(int i=0; i<=5; i++){
                                listView.setItemChecked(i, false);
                }
                listView.clearChoices();
                listView.requestLayout()
                adapter.notifyDataSetChanged()
             }
        }

一个非常令人费解的困境,任何帮助都表示赞赏!

A very puzzling predicament, any help is appreciated!

编辑:这是edittext的布局:

<EditText
                android:id="@+id/editText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@+id/textView4"
                android:layout_alignBottom="@+id/textView4"
                android:layout_toEndOf="@+id/textView4"
                android:layout_toRightOf="@+id/textView4"
                android:color="@color/colorPrimary"
                android:imeOptions="actionDone"
                android:inputType="text"
                android:textColor="@color/textColorPrimary"
                android:textColorHint="@color/colorPrimary" />

编辑:这是listview的布局:

    <ListView
        android:id="@+id/listview"
        android:layout_width="wrap_content"
        android:layout_height="250dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/toolbar"
        android:background="@drawable/bg_key"
        android:choiceMode="singleChoice"
        android:listSelector="@color/colorPrimary">

    </ListView>


推荐答案

Long Story Short




  • ListView选择器( android:listSelector )用于指示点击事件,但未选择项

  • 如果绘制了一个ListView选择器(首次点击后),如果没有ListView中的重大更改,它将不会消失。

  • 因此使用如果没有状态作为ListView选择器应用于透明背景,则只有drawable具有透明背景。 不要使用纯色资源,不要混淆

  • 使用ListView选择模式( android:choiceMode )表示所选项目。

  • ListView通过在其根目录中设置 android:state_activated 来告知选择了哪一行视图。为您的适配器提供相应的布局/视图,以正确表示所选项目。

  • Long Story Short

    • ListView selector (android:listSelector) is designed to indicate a click event, but not selected items.
    • If a ListView selector is drawn (after first click) it won't dissapear without drastic changes in the ListView
    • Hence use only drawables with transparent background if no state is applied to it as a ListView selector. Don't use a plain color resource for it, don't confuse yourself.
    • Use ListView choice mode (android:choiceMode) to indicate selected items.
    • ListView tells which row is selected by setting android:state_activated on their root view. Provide your adapter with corresponding layout/views to represent selected items correctly.
    • 嗯, ListView 中的内置选择乍一看是非常棘手的。但是,您应该记住两个主要区别,以避免混淆这样 - 列表视图选择器选择模式

      Well, the built-in selection in ListView is utterly tricky at a first glance. However there are two main distinctions you should keep in mind to avoid confusing like this - list view selector and choice mode.

      ListView选择器是一个可绘制的资源,假设表示单击列表项的事件。您可以通过XML属性指定它 android:listSelector 或使用方法 setSelector() 。我无法在docs中找到它,但我的理解是这个资源不应该是一个简单的颜色,因为在它被绘制之后,它不会在视图中没有剧烈变化的情况下消失(比如设置适配器,反过来可能导致出现一些故障),因此只有在特定状态时才能看到这样的drawable(例如 android:state_pressed )。下面是一个简单的drawable示例,可以用作列表视图选择器

      ListView selector is a drawable resource that is assumed to indicate an event of clicking a list item. You can specify it either by XML-property android:listSelector or using method setSelector(). I couldn't find it in docs, but my understanding is that this resource should not be a plain color, because after it's being drawn, it won't vanish without drastic changes in the view (like setting an adapter, that in turn may cause some glitches to appear), hence such drawable should be visible only while particular state (e.g. android:state_pressed) is applied. Here is a simple example of the drawable that can be used as a List View selector

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

      无论出于何种原因,您都无法使用颜色状态列表作为列表视图选择器,但仍然可以使用纯颜色(大多数不合适)和状态列表 drawables。这让事情有些混乱。
      第一次单击列表视图后,您将无法轻松地从列表视图中删除列表视图选择器。

      For whatever reason you cannot use a Color State List as List View selector, but still can use plain colors (that are mostly inappropriate) and State List drawables. It makes things somewhat confusing. After the first click on a List View happens, you will not be able to remove List View selector from the List View easily.

      这里的主要思路是列表视图选择器不是为了表示所选项目

      假设ListView选择模式为表示所选项目。您可能知道,主要有两种我们可以在ListView中使用的选择模式 - 单选和多选。它们允许分别跟踪选择的单个或多个行。您可以通过 android:choiceMode进行设置 XML-property或 setChoiceMode() 方法。
      ListView本身会在其中保留选定的行,并通过设置 android:state_activated 行根视图的属性。为了使您的行反映此状态,其根视图必须具有相应的可绘制集,例如作为背景。以下是此类drawable的示例:

      ListView choice mode is assumed to indicate selected items. As you might know, primarily there are two choice modes we can use in ListView - Single Choice and Multiple Choice. They allow to track a single or multiple rows selected respectively. You can set them via android:choiceMode XML-property or setChoiceMode() method. The ListView itself keeps selected rows in it and let them know which one is selected at any given moment by setting android:state_activated property of the row root view. In order to make your rows reflect this state, their root view must have a corresponding drawable set, e.g. as a background. Here is an example of such drawable:

      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item
              android:state_activated="true"
              android:drawable="@android:color/holo_green_light" />
          <item
              android:drawable="@android:color/transparent" />
      </selector>
      

      您可以使用 setItemChecked() 方法。如果您希望ListView清除所有选定的项目,可以使用 clearChoices() 方法。您还可以使用方法系列检查所选项目: getCheckedItemCount() getCheckedItemIds() getCheckedItemPosition() (对于单选模式), getCheckedItemPositions() (多选模式)

      You can make rows selected/deselected programmatically using the setItemChecked() method. If you want a ListView to clear all selected items, you can use the clearChoices() method. You also can check selected items using the family of the methods: getCheckedItemCount(), getCheckedItemIds(), getCheckedItemPosition() (for single choice mode), getCheckedItemPositions() (for multiple choice mode)

      如果你想保持简单,不要使用列表视图选择器以指示所选项目

      而不是实际删除选择器,更改布局和实现强大的方法,我们可以在需要时隐藏选择器drawable,并在以后单击ListView项时显示它:

      Instead of actually removing selector, changing layouts and implementing a robust approach, we can hide the selector drawable when it's needed and show it later when clicking a ListView item:

          public void hideListViewSelector() {
              mListView.getSelector().setAlpha(0);
          }
      
          @Override
          public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              if (mListView.getSelector().getAlpha() == 0) {
                  mListView.getSelector().setAlpha(255);
              }
          }
      



      选项2.周到的方式



      让我们仔细检查你的代码并使其符合我所描述的规则。

      Option 2. Thoughtful way

      Let's go through your code and make it comply the rules i described step by step.

      在ListView布局中,选择器设置为纯色,因此单击它们时,项目会被它着色。您用作ListView背景的drawable没有任何影响,因为单击其行时ListView状态不会更改,因此ListView始终只有 @ color / windowBackground 背景。

      In your ListView layout the selector is set to a plain color, and therefore your items are colored by it when they are clicked. The drawable you use as the ListView background have no impact, because ListView state doesn't change when its rows are clicked, hence your ListView always has just @color/windowBackground background.

      要解决您的问题,首先需要从ListView布局中删除选择器:

      To solve your problem you need at first remove the selector from the ListView layout:


      <ListView
          android:id="@+id/listview"
          android:layout_width="wrap_content"
          android:layout_height="250dp"
          android:layout_alignParentLeft="true"
          android:layout_alignParentStart="true"
          android:layout_below="@+id/toolbar"
          android:listSelector="@color/colorPrimary"
          android:background="@color/windowBackground"
          android:choiceMode="singleChoice"/> 




      让你的行反映激活状态



      在评论中,你给你的适配器如下:

      Make your rows reflect activated state

      In the comments you give your adapter as follows:

      final ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, text1, listOfThings);
      

      您还问我是否可以继续使用标准适配器来实现所需的行为。我们可以肯定,但无论如何需要进行一些更改。我可以看到这种情况的3个选项:

      You also asked me if it's possible to keep using standard adapter to achieve desired behavior. We can for sure, but anyway a few changes are required. I can see 3 options for this case:

      1。使用标准的android检查布局

      您可以指定相应的标准布局 - 使用 CheckedTextView 没有更改背景可绘制作为根组件或使用 的组件activatedBackgroundIndicator 作为其背景绘制。对于您的情况,最合适的选项应该是 simple_list_item_activated_1 。只需将其设置为 ArrayAdapter 构造函数如下:

      You can just specify a corresponding standard layout - either any of the layouts that use CheckedTextView without changed background drawable as the root component or of those that use activatedBackgroundIndicator as their background drawable. For your case the most appropriate option should be the simple_list_item_activated_1. Just set it as in your ArrayAdapter constructor like this:

      final ArrayAdapter<String> adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_activated_1, android.R.id.text1, listOfThings);

      此选项最接近我所理解的标准适配器。

      This option is the closest to what i understand by 'standard' adapter.

      2。自定义您的适配器

      您可以使用标准布局和大多数标准适配器,只有一个小例外,即获取项目视图。只需引入一个匿名类并覆盖方法 getView() ,提供具有相应背景drawable的行视图:

      You can use standard layout and mostly standard adapter with a small exception of getting a view for your items. Just introduce an anonymous class and override the method getView(), providing row views with corresponding background drawable:

      final ArrayAdapter<String> adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1, listOfThings) {
      
          @NonNull
          @Override
          public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
              final View view = super.getView(position, convertView, parent);
              if (convertView == null) {
                  view.setBackgroundResource(R.drawable.list_item_bg);
              }
              return view;
          }
      };

      3。自定义您的布局

      解决此问题的最常见方法当然是为项目视图引入您自己的布局。这是我的简单示例:

      The most common way of addressing this issue is of course introducing your own layout for the items view. Here is my simple example:

      <FrameLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:background="@drawable/list_item_bg"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:padding="16dp">
      
          <TextView
              android:id="@android:id/text1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"/>
      
      </FrameLayout>
      

      我将其保存在文件 /res/layout/list_view_item.xml 不要忘记在适配器中设置此布局:

      I saved it in a file /res/layout/list_view_item.xml Do not forget setting this layout in your adapter:

      final ArrayAdapter<String> adapter = new ArrayAdapter(this, R.layout.list_view_item, android.R.id.text1, listOfThings);



      在需要时明确选择



      之后,您的行将在单击时反映所选状态,并且您可以轻松清除<$的选定状态c $ c> ListView 通过调用 clearChoices()和结果 requestLayout() 要求ListView重绘自身。

      Clear choices when needed

      After that your rows will reflect selected state when they are clicked, and you can easily clear the selected state of your ListView by calling clearChoices() and consequence requestLayout() to ask the ListView to redraw itself.

      这里有一点评论如果你想在用户开始输入时取消选择该项目,而不是在他实际点击返回(完成)按钮时取消选择,你需要使用< a href =https://developer.android.com/reference/android/text/TextWatcher.html\"rel =nofollow noreferrer> TextWatcher 回调相反:

      One little comment here that if you want unselect the item when user start typing, but not when he actually clicks the return (done) button, you need to use a TextWatcher callback instead:

          mEditText.addTextChangedListener(new TextWatcher(){
      
              @Override
              public void beforeTextChanged(CharSequence s, int start, int count, int after) {
              }
      
              @Override
              public void onTextChanged(CharSequence s, int start, int before, int count) {
                  if (mListView.getCheckedItemCount() > 0) {
                      mListView.clearChoices();
                      mListView.requestLayout();
                  }
              }
      
              @Override
              public void afterTextChanged(Editable s) {}
          });
      

      希望它有所帮助。

      这篇关于如何清除ListView选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆