【问题标题】:Android - Keep ListView's item highlighted once one has been clickedAndroid - 单击后保持 ListView 的项目突出显示
【发布时间】:2012-03-06 01:31:48
【问题描述】:

所以我有一个包含 2 个 ListView 小部件的活动,当您在第一个小部件中选择一个值时,第二个将填充与第一个 ListView 中的选择相关的值。这个机制没有问题,但现在我希望用户选择保持突出显示。我已经阅读了大量与该主题相关的问题,似乎有无数种方法可以实现这一点,但在尝试了大约 4-5 次之后,我仍然无法让它发挥作用。

我已经使用android:listSelector="#CCCCCC" XML 属性在第二个ListView 上工作了,但是一旦将OnItemClickListener 引入到组合中(就像我在第一个@ 987654328@).

到目前为止,这是我所拥有的:

自定义OnItemClickListener 我发现浏览了有关此主题的各种答案(稍作修改以使其在第二个 ListView 中加载我的信息):

private class ItemHighlighterListener implements OnItemClickListener {

    private View oldSelection = null;

    public void clearSelection() {
        if(oldSelection != null) {
            oldSelection.setBackgroundColor(android.R.color.transparent);
        }
    }

    public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
        clearSelection();
        oldSelection = view;
        view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));
        loadClubs(mXMLPortalOptions.getRegion(pos).getId());
        mClubList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item_white, mClubs));
    }
}

这是我的list_selector.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_selected="true"><shape>
            <solid android:color="#CCCCCC" />
        </shape></item>

    <item android:state_selected="false"><shape>
            <solid android:color="#FFFFFF" />
        </shape></item>

</selector>

调用并执行方法(OnItemClick),但我的ListItem的背景颜色保持不变:/

我不敢相信这个简单的任务竟然如此复杂。

如果我省略了可能有用的代码,或者我的问题缺乏细节,请随时指出,我会尽力解释自己。

【问题讨论】:

标签: android listview android-listview highlighting


【解决方案1】:

为所选项目放置一个位置变量。更改onItemClicked() 方法中的位置。查看getView()内List Adapter中选中的位置,并设置选中项的背景。

public class TestAdapter extends BaseAdapter
{
    private Context context;
    private ArrayList<TestList> testList;
    private int selectedIndex;
    private int selectedColor = Color.parseColor("#1b1b1b");

    public TestAdapter(Context ctx, ArrayList<TestList> testList)
    {
        this.context = ctx;
        this.testList = testList;
        selectedIndex = -1;
    }

    public void setSelectedIndex(int ind)
    {
        selectedIndex = ind;
        notifyDataSetChanged();
    }

    @Override
    public int getCount()
    {
        return testList.size();
    }

    @Override
    public Object getItem(int position)
    {
        return testList.get(position);
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    private class ViewHolder
    {
        TextView tv;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        View vi = convertView;
        ViewHolder holder;
        if(convertView == null)
        {
            vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null);
            holder = new ViewHolder();

            holder.tv = (TextView) vi;

            vi.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) vi.getTag();
        }

        if(selectedIndex!= -1 && position == selectedIndex)
        {
            holder.tv.setBackgroundColor(Color.BLACK);
        }
        else
        {
            holder.tv.setBackgroundColor(selectedColor);
        }
        holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText());

        return vi;
    }

}

现在在单击列表项时设置 selectedIndex 变量。

public class TestActivity extends Activity implements OnItemClickListener
{
    // Implemented onItemClickListener

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        adapter.setSelectedIndex(position);
    }
}

【讨论】:

  • 你能详细解释一下吗.. 我得到了一些东西,但不是 100%。所以请详细说明步骤..请
  • 很好的解释 - 几个新概念都一口气解释了,谢谢!
  • 伟大而简单,这就是我喜欢我的代码的地方!直到我将一些东西设为静态并移动了一些东西(见下面我的回答),我才让它工作。 +1
  • 您好,我正在尝试将这种方法与可扩展的列表视图一起使用,但无法使其正常工作,每当我打开一个组时,我发现其中选择了一个项目
  • @R4j 它不应该让你的 UI 变慢。也许还有其他原因。每次notifyDataSetChanged() 调用时,只会更新可见的行数。
【解决方案2】:

要扩展 Shaiful 的出色解决方案,您可能无法让他在您的情况下发挥作用。

如果您正在使用将代码全部放在public void onListItemClick(ListView l, View v, int index, long id) 中,如果您正在使用片段并且必须声明一个接口而不是实现 OnListItemClickListener,或者导致您的 IDE 生成错误的任何原因,您可能必须访问变量和静态方法。

public static int selectedPosition = 0;
ArrayAdapter<Your_obj> adapter = null;

@Override
public void onListItemClick(ListView l, View v, int index, long id) {
    super.onListItemClick(l, v, index, id);

        selectedPosition = index;
        Your_adapter.setSelectedIndex(selectedPosition);
        adapter.notifyDataSetChanged();
}

在 Your_adapter 中:

private static int selectedIndex;

//public Your_adapter...

public static void setSelectedIndex(int ind) {
    selectedIndex = ind;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    WellHolder holder = null;

    if (null == convertView) {

                //set up your "holder"
    }

    if (position == selectedIndex) {
        convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan));
    }
    else {
        convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver));
    }

    return convertView;
}

其他一些区别是您不必将任何变量初始化为“0”或“-1”,并且在您的活动中调用 notifyDataSetChanged()。

再次感谢@Shaiful 的解决方案。它确实帮助我节省了尝试让 iOS 中的默认设置适用于 Android 的时间,同时避免选择器/项目/聚焦/按下/等。

【讨论】:

  • 这是因为你没有使用状态列表,这是一个低效且不太合适的解决方案,最好依靠这种东西的平台
【解决方案3】:

我遇到了类似的问题。这就是我的解决方案:

首先将自定义列表选择器添加到您的列表视图中:

<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="fill_parent"
    android:listSelector="@drawable/listselector" />

在listselector.xml里面:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_accelerated="false"
        android:drawable="@drawable/bg" />
</selector>

最后是带有高亮颜色的可绘制 bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#33b5e6"/>
</shape>

【讨论】:

    【解决方案4】:

    我认为最好和最简单的解决方案就是这个。您不需要在 ListView 本身上设置任何 android:listSelector 或对适配器进行任何更改。您不需要甚至需要调用OnItemClickListener 中的任何setSelection(position),因为它会自动处理。

    1. 设置为您的 ListView:

      android:choiceMode="singleChoice"
      
    2. 设置列表项本身的背景:

      android:background="?android:attr/activatedBackgroundIndicator"
      
    3. 就是这样。

    这样您将获得默认的系统行为。这就是在默认的android.R.layout.simple_list_item_activated_1 布局中完成的方式。

    【讨论】:

      【解决方案5】:

      lv.setSelector(R.drawable.highlighter);

      highlighter.png 图像放入可绘制文件夹
      在列表视图中突出显示所选项目的最简单方法。

      【讨论】:

        【解决方案6】:

        两周前我正在寻找它,结果是可绘制选择器无法实现。 欲了解更多信息,请阅读 Android 开发者博客中的这篇文章:Touch Mode

        在简历中:只有当您的手指在屏幕上时,才会选择项目。

        另一种可能性是保存在 var 中选择的项目,并使用您的自定义适配器绘制不同的颜色,就像 Shaiful 说的那样。

        【讨论】:

          【解决方案7】:
          //create a list_itemselectorin drawable folder
          //you will get the list item selected background color change once you select //the item
          
              <selector xmlns:android="http://schemas.android.com/apk/res/android">
          
                  <!-- Focused State -->
                  <item android:state_focused="true"><shape>
                          <solid android:color="#66FFFFFF" />
                      </shape></item>
                  <!-- Pressed State -->
          
                  <item android:state_pressed="true"><shape>
                          <solid android:color="@color/Black" />
                      </shape></item>
          
                  <!-- Default State -->
                  <item><shape>
                          <solid android:color="@color/Black" />
                      </shape></item>
          
              </selector>
          
          
              //create a list in layout folder
                <ListView
                      android:id="@+id/mySlidingList"
                      android:layout_width="match_parent"
                      android:layout_height="match_parent"
                      android:choiceMode="singleChoice"
                      android:divider="@color/GrayHot"
                      android:dividerHeight="1dip"
                      android:listSelector="@drawable/list_itemselector"
                      android:scrollbars="none" />
          

          // 并查看输出。

          【讨论】:

            【解决方案8】:

            如果你可以使用drawable来显示listItem Highlighted,那么你应该使用以下代码:-

            listView.setSelector(R.drawable.bg_image);
            

            有效。

            【讨论】:

              【解决方案9】:

              有一个简单的完全 XML 解决方案,它对我有用。 首先,使用选择器代码定义 XML-drawable,其中“正常”状态将对应于列表项的“选定未按下”视觉状态,而 state_pressed=true 对应于“按下”视觉状态。 文件“custom_item_selector.xml”示例,类似于 Holo 蓝色选择:

              <?xml version="1.0" encoding="utf-8"?>
              <selector xmlns:android="http://schemas.android.com/apk/res/android">
                  <item android:state_pressed="true">
                      <shape android:shape="rectangle">
                          <solid
                              android:color="#643292ff">
                          </solid>
                          <stroke
                              android:width="1dp"
                              android:color="#c83292ff">
                          </stroke>
                      </shape>
                  </item>
                  <item>
                      <shape android:shape="rectangle">
                          <solid
                              android:color="#323292ff">
                          </solid>
                          <stroke
                              android:width="1dp"
                              android:color="#783292ff">
                          </stroke>
                      </shape>
                  </item>
              </selector>
              

              (也可以在那里设置焦点状态)。 其次,将此 xml-drawable 应用为 ListView 的 listSelector 并设置它所需的选择模式:

              <ListView
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:id="@+id/listView"
                          android:choiceMode="singleChoice"
                          android:listSelector="@drawable/custom_item_selector"/>
              

              就是这样。它允许为“简单选定”和“按下选定”项目定义不同的视觉状态,例如使项目在按下时更亮。

              【讨论】:

                【解决方案10】:

                要保持列表项(多选)突出显示,单击(激活)时,请按照以下步骤操作。

                1.将背景设置为可绘制的列表项布局。

                    <?xml version="1.0" encoding="utf-8"?>
                    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                        android:layout_width="match_parent"
                        android:layout_height="40dp"
                        android:background="@drawable/list_item_selector">
                
                        <ImageView
                            android:id="@+id/icon"
                            android:layout_width="22px"
                            android:layout_height="22px"
                            android:layout_marginLeft="4px"
                            android:layout_marginRight="10px"
                            android:layout_marginTop="4px"
                            android:src="@mipmap/ic_launcher" >
                        </ImageView>
                
                        <TextView
                            android:id="@+id/label"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@+id/label"
                            android:textSize="20px" >
                        </TextView>
                    </LinearLayout>
                

                2。可绘制选择器

                <?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_red_light" />
                
                <item android:state_activated="true" android:drawable="@android:color/holo_orange_dark" />
                
                </selector>
                

                3. Listview设置多选模式

                getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

                按下时

                下图显示,当用户选择多个列表项时。

                激活时

                【讨论】:

                  【解决方案11】:

                  为了总结这篇文章并可能在将来帮助其他人,我建议答案:)

                  首先,我们需要创建res/drawable/list_item_background.xml文件,内容如下:

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

                  当然,请指定您的可绘制资源。您还可以添加其他具有不同状态的&lt;item&gt; 元素,例如state_pressedstate_focused 等。

                  然后,我们应该将background 参数设置为我们的自定义列表项ViewGroup 元素(f.i. res/layout/list_item_layout.xml),如下所示:

                  android:background="@drawable/list_item_background"
                  

                  下一步是修改我们的自定义Adapter 类。以下是以下代码片段:

                  public class CustomAdapter extends BaseAdapter {
                      private List<Item> items;
                      private LayoutInflater itemInflater;        
                      private int selectedIndex; // add this
                  
                      public CustomAdapter(Context c, List<Item> items) {
                          this.items = items;
                          this.itemInflater = LayoutInflater.from(c);
                          selectedIndex = -1; // add this
                      }
                  
                      /* add this */
                      public void setSelectedIndex(int index) {
                          selectedIndex = index;
                          notifyDataSetChanged();
                      }
                  
                      /* other adapter's stuff */
                  
                      @Override
                      public View getView(int position, View convertView, ViewGroup parent) {
                          if(convertView == null) {
                              convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false);
                          }
                  
                          // add this
                          convertView.setActivated(selectedIndex != -1 && position == selectedIndex);
                  
                          /* do some stuff */
                  
                          return convertView;
                      }
                  }
                  

                  最后,我们应该在AdapterView.OnItemClickListeneronItemClick(...)方法中调用setSelectedIndex(position)适配器的方法。

                  public class YourActivity extends Activity
                          implements AdapterView.OnItemClickListener {
                  
                      private CustomAdapter mCustomAdapter;
                  
                      /* activity implementation */
                  
                      @Override
                      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                          mCustomAdapter.setSelectedIndex(position);
                      }
                  }
                  

                  现在,我们可以对适当的列表项突出显示感到满意了 :)

                  附:如果我们想在我们的列表中启用多项选择模式,我们只需将以下字符串放入保存listView 实例的活动类:

                  listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
                  

                  因此,我们将获得正确的多个项突出显示。

                  -- 希望这对任何人都有帮助:)

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2016-11-15
                    • 1970-01-01
                    • 2013-04-17
                    • 1970-01-01
                    • 2016-01-09
                    • 1970-01-01
                    • 2013-11-18
                    • 2015-02-17
                    相关资源
                    最近更新 更多