【问题标题】:ListView item won't stay "selected"ListView 项目不会保持“选中”状态
【发布时间】:2011-08-06 15:01:18
【问题描述】:

我想在用户单击列表视图项时更改它的背景。有点像Honeycomb settings page(虽然我不只处理设置,所以我不使用 PreferenceActivity)我有这个功能通过资源状态选择器状态选择器工作,除了单击列表视图菜单更改线性的情况列表视图右侧的布局(一种分屏视图)。我猜 listview 失去焦点,所以 state_pressed 不再正确。

   <item android:state_pressed="true">
     <shape  >
        <solid android:color="@color/blue1" />
     </shape>
   </item>

在选择另一个列表视图项目之前保持该列表视图项目颜色的任何提示?谢谢!

编辑:

我能够使用

在 setOnItemClickListener 中更改背景
view.setBackgroundResource(R.color.red); 

我一次只需要选择一个,所以当单击其他列表项时,我尝试了lv.invalidate()lv.getChildAt(0).invalidate(),但都没有成功,第二个导致空指针异常。有什么想法可以恢复颜色吗?

【问题讨论】:

    标签: android listview resources preferenceactivity


    【解决方案1】:

    当您从单元格中松开手指时,它不再记录为按下状态。您要做的实际上是在用户选择 is 时更改单个行的背景。这意味着实现 onItemClick 或 onItemTouch 并标记适配器以使用新背景重绘行。如果您已经在使用自定义列表适配器,您可以在 getView() 方法中实现对布尔值的检查。您还需要跟踪哪些行被“选中”,哪些未被选中。

    伪代码:

       public View getView(int pos, View convertView, ViewGroup parent) {
          if(isChecked[pos]) //set background to checked color
       }
    

    【讨论】:

    • 我没有实现 getView 方法,因为我有静态和简单的列表视图数据。我应该实施它吗?请帮助我。
    • 你能帮帮我吗?我真的需要你的帮助。
    • @sgarman - 你能告诉我如何使用这个 ischecked[]
    【解决方案2】:

    希望对您有所帮助,

    1.- 为焦点项目创建一个形状文件:\drawable\list_selector_focused.xml

        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    
        <gradient android:angle="90" android:startColor="#f5c98c" android:endColor="#f7ddb8"/> 
    
    </shape>
    

    2.- 为按下的项目创建一个形状文件:\drawable\list_selector_pressed.xml

        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    
        <gradient android:angle="90" android:startColor="#fb9d23" android:endColor="#ffc579" />
    
    </shape>
    

    3.- 创建列表选择器文件:\drawable\list_selector.xml

        <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" />
        <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" />
        <item android:drawable="@drawable/list_selector_focused" />
    
    </selector>
    

    4.- 将此属性添加到布局文件中的 ListView:

     android:choiceMode="singleChoice"
     android:listSelector="@drawable/list_selector"
    

    您可以使用颜色代替渐变形状,

    【讨论】:

      【解决方案3】:

      这是sgarmanidea的实现:

          package com.mypackage;
      
      import java.util.Vector;
      
      import com.myapp.R;
      import com.myapp.data.Address;
      
      import android.content.Context;
      import android.graphics.Color;
      import android.util.Log;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.BaseAdapter;
      import android.widget.TextView;
      
      public class AddressesListAdapter extends BaseAdapter{
          protected Context context;
          protected LayoutInflater mInflater;
          protected int itemResourceId;
          protected Vector<Address> contentItems = new Vector<Address>();
          protected Vector<Boolean> selectedStates;
          private static final String TAG = "myapp";
      
          public AddressesListAdapter(Context context, Vector<Address> contentItems) {
              this.context = context;
              this.contentItems = contentItems;
              mInflater = LayoutInflater.from(context);
              itemResourceId = R.layout.address_list_item;
              selectedStates = new Vector<Boolean>();
              //initial fill
              clearSelectedState();
          }
      
          @Override
          public int getCount() {
              return contentItems.size();
          }
      
          @Override
          public Object getItem(int position) {
              return contentItems.get(position);
          }
      
          @Override
          public long getItemId(int position) {
              return position;
          }
      
          @Override
          public View getView(final int position, View convertView, ViewGroup parent) {
              final ViewHolder holder;
              if (convertView == null) {
                  convertView = mInflater.inflate(itemResourceId, null);
      
                  holder = new ViewHolder();
                  holder.addressName = (TextView) convertView.findViewById(R.id.addressName);
                  convertView.setTag(holder);
              } else {
                  holder = (ViewHolder) convertView.getTag();
              }
      
              Address address = (Address) contentItems.get(position);
              holder.addressName.setText(address.getAddressName());
              holder.addressName.setOnClickListener(new SetFocusListener(position));
      
              //restore saved position from saving vector
              if (selectedStates.get(position)) holder.addressName.setBackgroundColor(Color.BLUE);
              else holder.addressName.setBackgroundColor(Color.TRANSPARENT);
      
              return convertView;
          }
      
          private void clearSelectedState () {
              selectedStates.clear();  
              for (int i = 0 ; i <= contentItems.size(); i++) {
                  selectedStates.add(new Boolean(false));
              } 
          }
      
          private class SetFocusListener implements View.OnClickListener {
              private int position;
      
              public SetFocusListener(int position) {
                  this.position = position;
              }
      
              @Override
              public void onClick(View v) {
                  //clear selected state vector
                  clearSelectedState();
                  //set selected position
                  selectedStates.set(position, new Boolean(true));
                  //refresh adapter to redraw focus
                  notifyDataSetChanged();
              }
          }
      
          static class ViewHolder {
                TextView addressName;
          }
      }
      

      唯一的担心是为每次 getView() 迭代设置新的侦听器可能会很昂贵

      【讨论】:

        【解决方案4】:

        检查的android状态最好用来解决这个问题。

        有人提到使用 android:background="?android:attr/activatedBackgroundIndicator"。

        这只是指向android源代码的frameworks/base/core/res/res/drawable中的activated_background_*资源之一。例如activated_background_holo_dark.xml:

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

        所以本质上你想使用 state_activated 来表示用户按下按钮的时间以及它处于选中(即处于持久选择状态)状态时。请注意,Activated 仅在 Honeycomb 之后引入,如果您针对的是旧设备,则需要依赖 state_checked(更多详细信息here)。

        现在如果你想将一个项目设置为选中,你需要调用listView.setItemChecked(position, true)。您可能希望将 ListView 上的 android:choiceMode 属性设置为适当的值(例如,如果您希望一次只选择一件事,请使用 singleChoice)。您不需要无效,对 setItemChecked 的调用将触发重新布局,这将更新视图。

        如果您允许对 ListView 中的项目重新排序,请注意,因为当前选中的项目需要更新。如果您使用稳定的 ID,这将自动处理。

        要查看实际示例,请查看培训系列中的 NavigationDrawer 示例代码:http://developer.android.com/training/implementing-navigation/nav-drawer.html

        【讨论】:

          【解决方案5】:

          默认情况下,当您使用触摸界面时,“已选择”与“已单击”不同 - 这让我在开始 Android 开发时感到非常头疼。

          要同时支持通过触摸导航的用户和使用滚轮/轨迹球的用户,您可能需要使用setSelection,并在AdapterView.OnItemSelectedListener 实现中进行操作(使用setOnItemSelectedListener 设置)。

          另一个问题是,如果最后一个事件是触摸事件,setSelection 不会突出显示项目。

          我建议您为列表项创建一个自定义视图,并在其中处理突出显示。

          希望这会有所帮助,

          菲尔·莱洛

          【讨论】:

            【解决方案6】:

            好的,所以我尝试了上面的解决方案,上面写着“这是 sgarman 想法的实现:”这只有在 SetFocusListener 是 OnTouchListner 时才有效。否则 onClick 方法会消耗点击。我必须将此解决方案与列表项上的 OnItemClick 侦听器配对,以使列表实际显示突出显示的项。

            【讨论】:

              【解决方案7】:

              我使用了android:state_activated="true" 而不是state_selected。它就像一个魅力!

              【讨论】:

                【解决方案8】:

                如果您在整个活动中保留 listView,您可以在 getView() 方法中执行 mListView.isItemChecked(position)。他们根据结果设置背景颜色。

                【讨论】:

                  【解决方案9】:

                  你试过android:state_selected="true"吗?

                  【讨论】:

                    【解决方案10】:

                    试试

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

                    ;)

                    【讨论】:

                    • 你应该在哪里试试这个?
                    猜你喜欢
                    • 1970-01-01
                    • 2011-03-07
                    • 1970-01-01
                    • 2018-10-22
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多